diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..4f06b0c
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,6 @@
+{
+ "presets": [
+ "@babel/preset-env",
+ "@babel/preset-react"
+ ]
+}
diff --git a/.gitignore b/.gitignore
index 59b30be..c0a6b32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,10 @@ npm-debug.log
ssl-keys
dart-sass
dump.rdb
+formspree/static/bundle.js
+formspree/static/bundle.min.js
+formspree/static/main.css
+*tmp-browserify*
# C extensions
*.so
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2369f27
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,19 @@
+all: formspree/static/bundle.js formspree/static/main.css
+
+watch:
+ find formspree/js/ formspree/scss/ -name '*.js' -o -name '*.scss' | entr make
+
+$(shell find formspree/js/):
+ ./node_modules/.bin/prettier "formspree/js/**/*.js"
+
+formspree/static/bundle.js: $(shell find formspree/js)
+ ./node_modules/.bin/browserify formspree/js/main.js -dv --outfile formspree/static/bundle.js
+
+formspree/static/bundle.min.js: $(shell find formspree/js)
+ ./node_modules/.bin/browserify formspree/js/main.js -g [ envify --NODE_ENV production ] -g uglifyify | ./node_modules/.bin/uglifyjs --compress --mangle > formspree/static/bundle.min.js
+
+formspree/static/main.css: $(shell find formspree/scss) dart-sass/src/dart
+ cd dart-sass && ./sass ../formspree/scss/main.scss ../formspree/static/main.css
+
+dart-sass/src/dart:
+ echo -e "\n\ninstall dart-sass from https://github.com/sass/dart-sass/releases\n\n"
diff --git a/formspree/forms/api.py b/formspree/forms/api.py
new file mode 100644
index 0000000..0d42c6d
--- /dev/null
+++ b/formspree/forms/api.py
@@ -0,0 +1,203 @@
+from flask import request, jsonify, g
+from flask_login import current_user, login_required
+
+from formspree import settings
+from formspree.stuff import DB
+from formspree.utils import jsonerror, IS_VALID_EMAIL
+from .helpers import referrer_to_path, sitewide_file_check, remove_www, \
+ referrer_to_baseurl
+from .models import Form, Submission
+
+
+@login_required
+def list():
+ # grab all the forms this user controls
+ if current_user.upgraded:
+ forms = current_user.forms.order_by(Form.id.desc()).all()
+ else:
+ forms = []
+
+ return jsonify({
+ 'ok': True,
+ 'user': {
+ 'upgraded': current_user.upgraded,
+ 'email': current_user.email
+ },
+ 'forms': [f.serialize() for f in forms]
+ })
+
+
+@login_required
+def create():
+ # check that this request came from user dashboard to prevent XSS and CSRF
+ referrer = referrer_to_baseurl(request.referrer)
+ service = referrer_to_baseurl(settings.SERVICE_URL)
+ if referrer != service:
+ return jsonerror(400, {'error': 'Improper request.'})
+
+ if not current_user.upgraded:
+ g.log.info('Failed to create form from dashboard. User is not upgraded.')
+ return jsonerror(402, {'error': "Please upgrade your account."})
+
+ email = request.get_json().get('email')
+ url = request.get_json().get('url')
+ sitewide = request.get_json().get('sitewide')
+
+ g.log = g.log.bind(email=email, url=url, sitewide=sitewide)
+
+ if not IS_VALID_EMAIL(email):
+ g.log.info('Failed to create form from dashboard. Invalid address.')
+ return jsonerror(400, {'error': "The provided email address is not valid."})
+
+ g.log.info('Creating a new form from the dashboard.')
+
+ email = email.lower().strip() # case-insensitive
+ form = Form(email, owner=current_user)
+ if url:
+ url = 'http://' + url if not url.startswith('http') else url
+ form.host = referrer_to_path(url)
+
+ # sitewide forms, verified with a file at the root of the target domain
+ if sitewide:
+ if sitewide_file_check(url, email):
+ form.host = remove_www(referrer_to_path(urljoin(url, '/'))[:-1])
+ form.sitewide = True
+ else:
+ return jsonerror(403, {
+ 'error': u"Couldn't verify the file at {}.".format(url)
+ })
+
+ DB.session.add(form)
+ DB.session.commit()
+
+ if form.host:
+ # when the email and url are provided, we can automatically confirm the form
+ # but only if the email is registered for this account
+ for email in current_user.emails:
+ if email.address == form.email:
+ g.log.info('No need for email confirmation.')
+ form.confirmed = True
+ DB.session.add(form)
+ DB.session.commit()
+ break
+ else:
+ # in case the email isn't registered for this user
+ # we automatically send the email confirmation
+ form.send_confirmation()
+
+ return jsonify({
+ 'ok': True,
+ 'hashid': form.hashid,
+ 'submission_url': settings.API_ROOT + '/' + form.hashid,
+ 'confirmed': form.confirmed
+ })
+
+
+@login_required
+def get(hashid):
+ if not current_user.upgraded:
+ return jsonerror(402, {'error': "Please upgrade your account."})
+
+ form = Form.get_with_hashid(hashid)
+ if not form:
+ return jsonerror(404, {'error': "Form not found."})
+
+ for cont in form.controllers:
+ if cont.id == current_user.id: break
+ else:
+ return jsonerror(401, {'error': "You do not control this form."})
+
+ submissions, fields = form.submissions_with_fields()
+
+ ret = form.serialize()
+ ret['submissions'] = submissions
+ ret['fields'] = fields
+
+ return jsonify(ret)
+
+
+@login_required
+def update(hashid):
+ # check that this request came from user dashboard to prevent XSS and CSRF
+ referrer = referrer_to_baseurl(request.referrer)
+ service = referrer_to_baseurl(settings.SERVICE_URL)
+ if referrer != service:
+ return jsonerror(400, {'error': 'Improper request.'})
+
+ form = Form.get_with_hashid(hashid)
+ if not form:
+ return jsonerror(400, {'error': 'Not a valid form.'})
+
+ if form.owner_id != current_user.id and form not in current_user.forms:
+ return jsonerror(401, {'error': 'Wrong user.'})
+
+ patch = request.get_json()
+
+ for attr in ['disable_storage', 'disabled', 'disable_email', 'captcha_disabled']:
+ if attr in patch:
+ setattr(form, attr, patch[attr])
+
+ DB.session.add(form)
+ DB.session.commit()
+ return jsonify({'ok': True})
+
+
+@login_required
+def delete(hashid):
+ # check that this request came from user dashboard to prevent XSS and CSRF
+ referrer = referrer_to_baseurl(request.referrer)
+ service = referrer_to_baseurl(settings.SERVICE_URL)
+
+ if referrer != service:
+ return jsonerror(400, {'error': 'Improper request.'})
+
+ form = Form.get_with_hashid(hashid)
+ if not form:
+ return jsonerror(400, {'error': 'Not a valid form.'})
+
+ if form.owner_id != current_user.id and form not in current_user.forms:
+ return jsonerror(401, {'error': 'Wrong user.'})
+
+ for submission in form.submissions:
+ DB.session.delete(submission)
+ DB.session.delete(form)
+ DB.session.commit()
+
+ return jsonify({'ok': True})
+
+
+@login_required
+def submission_delete(hashid, submissionid):
+ # check that this request came from user dashboard to prevent XSS and CSRF
+ referrer = referrer_to_baseurl(request.referrer)
+ service = referrer_to_baseurl(settings.SERVICE_URL)
+ if referrer != service:
+ return jsonerror(400, {'error': 'Improper request.'})
+
+ form = Form.get_with_hashid(hashid)
+ if not form:
+ return jsonerror(400, {'error': 'Not a valid form.'})
+
+ if form.owner_id != current_user.id and form not in current_user.forms:
+ return jsonerror(401, {'error': 'Wrong user.'})
+
+ submission = Submission.query.get(submissionid)
+ if not submission:
+ return jsonerror(401, 'Not a valid submission.')
+
+ DB.session.delete(submission)
+ form.counter -= 1
+ DB.session.add(form)
+ DB.session.commit()
+ return jsonify({'ok': True})
+
+
+@login_required
+def sitewide_check():
+ email = request.get_json().get('email')
+ url = request.get_json().get('url')
+
+ if sitewide_file_check(url, email):
+ return jsonify({'ok': True})
+ else:
+ return jsonify({'ok': False})
diff --git a/formspree/forms/helpers.py b/formspree/forms/helpers.py
index 02c8f96..575f382 100644
--- a/formspree/forms/helpers.py
+++ b/formspree/forms/helpers.py
@@ -91,20 +91,22 @@ def sitewide_file_check(url, email):
g.log = g.log.bind(url=url, email=email)
- res = requests.get(url, timeout=3, headers={
- 'User-Agent': 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36'
- })
- if not res.ok:
- g.log.debug('Sitewide file not found.', contents=res.text[:100])
- return False
+ try:
+ res = requests.get(url, timeout=3, headers={
+ 'User-Agent': 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/55.0.2883.87 Chrome/55.0.2883.87 Safari/537.36'
+ })
+ if not res.ok:
+ g.log.debug('Sitewide file not found.', contents=res.text[:100])
+ return False
- for line in res.text.splitlines():
- line = line.strip(u'\xef\xbb\xbf ')
- if line == email:
- g.log.debug('Email found in sitewide file.')
- return True
+ for line in res.text.splitlines():
+ line = line.strip(u'\xef\xbb\xbf ')
+ if line == email:
+ g.log.debug('Email found in sitewide file.')
+ return True
+ except requests.exceptions.ConnectionError:
+ pass
- g.log.warn('Email not found in sitewide file.', contents=res.text[:100])
return False
@@ -119,14 +121,6 @@ def verify_captcha(form_data, request):
return r.ok and r.json().get('success')
-def valid_domain_request(request):
- # check that this request came from user dashboard to prevent XSS and CSRF
- referrer = referrer_to_baseurl(request.referrer)
- service = referrer_to_baseurl(settings.SERVICE_URL)
-
- return referrer == service
-
-
def assign_ajax(form, sent_using_ajax):
if form.uses_ajax is None:
form.uses_ajax = sent_using_ajax
@@ -168,16 +162,3 @@ def fetch_first_submission(nonce):
return json.loads(jsondata.decode('utf-8'))
except:
return None
-
-def check_valid_form_settings_request(form):
- if not valid_domain_request(request):
- return jsonify(error='The request you made is not valid. Please visit your dashboard and try again.'), 400
-
- if form.owner_id != current_user.id and form not in current_user.forms:
- return jsonify(
- error='You aren\'t the owner of that form. Please log in as the form owner and try again.'), 400
-
- if not form:
- return jsonify(error='That form does not exist. Please check the link and try again.'), 400
-
- return True
diff --git a/formspree/forms/models.py b/formspree/forms/models.py
index c204585..0e527ab 100644
--- a/formspree/forms/models.py
+++ b/formspree/forms/models.py
@@ -116,6 +116,47 @@ class Form(DB.Model):
except IndexError:
return None
+ def serialize(self):
+ return {
+ 'sitewide': self.sitewide,
+ 'hashid': self.hashid,
+ 'hash': self.hash,
+ 'counter': self.counter,
+ 'email': self.email,
+ 'host': self.host,
+ 'confirm_sent': self.confirm_sent,
+ 'confirmed': self.confirmed,
+ 'disabled': self.disabled,
+ 'captcha_disabled': self.captcha_disabled,
+ 'disable_email': self.disable_email,
+ 'disable_storage': self.disable_storage,
+ 'is_public': bool(self.hash),
+ 'url': '{S}/{E}'.format(
+ S=settings.SERVICE_URL,
+ E=self.hashid
+ )
+ }
+
+ def submissions_with_fields(self):
+ '''
+ Fetch all submissions, extract all fields names from every submission
+ into a single fields list, excluding the KEYS_NOT_STORED values, because
+ they are worthless.
+ Add the special 'date' field to every submission entry, based on
+ .submitted_at, and use this as the first field on the fields array.
+ '''
+
+ fields = set()
+ submissions = []
+ for s in self.submissions:
+ fields.update(s.data.keys())
+ s.data['date'] = s.submitted_at.isoformat()
+ s.data['id'] = s.id
+ submissions.append(s.data)
+
+ fields = ['date'] + sorted(fields - KEYS_NOT_STORED)
+ return submissions, fields
+
def send(self, data, keys, referrer):
'''
Sends form to user's email.
diff --git a/formspree/forms/views.py b/formspree/forms/views.py
index 7d8fcb5..7c35df0 100644
--- a/formspree/forms/views.py
+++ b/formspree/forms/views.py
@@ -20,9 +20,7 @@ from formspree.utils import request_wants_json, jsonerror, IS_VALID_EMAIL, \
from .helpers import http_form_to_dict, ordered_storage, referrer_to_path, \
remove_www, referrer_to_baseurl, sitewide_file_check, \
verify_captcha, temp_store_hostname, get_temp_hostname, \
- HASH, assign_ajax, valid_domain_request, \
- KEYS_NOT_STORED, KEYS_EXCLUDED_FROM_EMAIL, \
- check_valid_form_settings_request
+ HASH, assign_ajax, KEYS_EXCLUDED_FROM_EMAIL
from .models import Form, Submission
@@ -486,349 +484,50 @@ def confirm_email(nonce):
@login_required
-def forms():
- '''
- A reminder: this is the /forms endpoint, but for GET requests
- it is also the /dashboard endpoint.
-
- The /dashboard endpoint, the address gave by url_for('dashboard'),
- is the target of a lot of redirects around the app, but it can
- be changed later to point to somewhere else.
- '''
-
- # grab all the forms this user controls
- if current_user.upgraded:
- forms = current_user.forms.order_by(Form.id.desc()).all()
- else:
- forms = []
-
- if request_wants_json():
- return jsonify({
- 'ok': True,
- 'forms': [{
- 'email': f.email,
- 'host': f.host,
- 'confirm_sent': f.confirm_sent,
- 'confirmed': f.confirmed,
- 'is_public': bool(f.hash),
- 'url': '{S}/{E}'.format(
- S=settings.SERVICE_URL,
- E=f.hashid
- )
- } for f in forms]
- })
- else:
- return render_template('forms/list.html',
- enabled_forms=[form for form in forms if not form.disabled],
- disabled_forms=[form for form in forms if form.disabled]
- )
+def serve_dashboard(hashid=None, s=None):
+ return render_template('forms/dashboard.html')
@login_required
-def create_form():
- # create a new form
-
- if not current_user.upgraded:
- g.log.info('Failed to create form from dashboard. User is not upgraded.')
- return jsonerror(402, {'error': "Please upgrade your account."})
-
- if request.get_json():
- email = request.get_json().get('email')
- url = request.get_json().get('url')
- sitewide = request.get_json().get('sitewide')
- else:
- email = request.form.get('email')
- url = request.form.get('url')
- sitewide = request.form.get('sitewide')
-
- g.log = g.log.bind(email=email, url=url, sitewide=sitewide)
-
- if not IS_VALID_EMAIL(email):
- g.log.info('Failed to create form from dashboard. Invalid address.')
- if request_wants_json():
- return jsonerror(400, {'error': "The provided email address is not valid."})
- else:
- flash(u'The provided email address is not valid.', 'error')
- return redirect(url_for('dashboard'))
-
- g.log.info('Creating a new form from the dashboard.')
-
- email = email.lower() # case-insensitive
- form = Form(email, owner=current_user)
- if url:
- url = 'http://' + url if not url.startswith('http') else url
- form.host = referrer_to_path(url)
-
- # sitewide forms, verified with a file at the root of the target domain
- if sitewide:
- if sitewide_file_check(url, email):
- form.host = remove_www(referrer_to_path(urljoin(url, '/'))[:-1])
- form.sitewide = True
- else:
- return jsonerror(403, {
- 'error': u"Couldn't verify the file at {}.".format(url)
- })
-
- DB.session.add(form)
- DB.session.commit()
-
- if form.host:
- # when the email and url are provided, we can automatically confirm the form
- # but only if the email is registered for this account
- for email in current_user.emails:
- if email.address == form.email:
- g.log.info('No need for email confirmation.')
- form.confirmed = True
- DB.session.add(form)
- DB.session.commit()
- break
- else:
- # in case the email isn't registered for this user
- # we automatically send the email confirmation
- form.send_confirmation()
-
- if request_wants_json():
- return jsonify({
- 'ok': True,
- 'hashid': form.hashid,
- 'submission_url': settings.API_ROOT + '/' + form.hashid,
- 'confirmed': form.confirmed
- })
- else:
- flash(u'Your new form endpoint was created!', 'success')
- return redirect(url_for('dashboard', new=form.hashid) + '#form-' + form.hashid)
-
-
-@login_required
-def sitewide_check():
- email = request.args.get('email')
- url = request.args.get('url')
-
- if sitewide_file_check(url, email):
- return '', 200
- else:
- return '', 404
-
-
-@login_required
-def form_submissions(hashid, format=None):
+def export_submissions(hashid, format=None):
if not current_user.upgraded:
return jsonerror(402, {'error': "Please upgrade your account."})
form = Form.get_with_hashid(hashid)
-
for cont in form.controllers:
if cont.id == current_user.id: break
else:
- if request_wants_json():
- return jsonerror(403, {'error': "You do not control this form."})
- else:
- return redirect(url_for('dashboard'))
+ return abort(401)
- if not format:
- # normal request.
- if request_wants_json():
- return jsonify({
+ submissions, fields = form.submissions_with_fields()
+
+ if format == 'json':
+ return Response(
+ json.dumps({
'host': form.host,
'email': form.email,
- 'submissions': [dict(s.data, date=s.submitted_at.isoformat()) for s in form.submissions]
- })
- else:
- fields = set()
- for s in form.submissions:
- fields.update(s.data.keys())
- fields -= KEYS_NOT_STORED
+ 'fields': fields,
+ 'submissions': submissions
+ }, sort_keys=True, indent=2),
+ mimetype='application/json',
+ headers={
+ 'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.json' \
+ % (hashid, datetime.datetime.now().isoformat().split('.')[0])
+ }
+ )
+ elif format == 'csv':
+ out = io.BytesIO()
+
+ w = csv.DictWriter(out, fieldnames=fields, encoding='utf-8')
+ w.writeheader()
+ for sub in submissions:
+ w.writerow(sub)
- submissions = []
- for sub in form.submissions:
- for f in fields:
- value = sub.data.get(f, '')
- typ = type(value)
- sub.data[f] = value if typ is str \
- else pyaml.dump(value, safe=True)
- submissions.append(sub)
-
- return render_template('forms/submissions.html',
- form=form,
- fields=sorted(fields),
- submissions=submissions
- )
- elif format:
- # an export request, format can be json or csv
- if format == 'json':
- return Response(
- json.dumps({
- 'host': form.host,
- 'email': form.email,
- 'submissions': [dict(s.data, date=s.submitted_at.isoformat()) for s in form.submissions]
- }, sort_keys=True, indent=2),
- mimetype='application/json',
- headers={
- 'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.json' \
- % (hashid, datetime.datetime.now().isoformat().split('.')[0])
- }
- )
- elif format == 'csv':
- out = io.BytesIO()
- fieldnames = set(field for sub in form.submissions for field in sub.data.keys())
- fieldnames = ['date'] + sorted(fieldnames)
-
- w = csv.DictWriter(out, fieldnames=fieldnames, encoding='utf-8')
- w.writeheader()
- for sub in form.submissions:
- w.writerow(dict(sub.data, date=sub.submitted_at.isoformat()))
-
- return Response(
- out.getvalue(),
- mimetype='text/csv',
- headers={
- 'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.csv' \
- % (hashid, datetime.datetime.now().isoformat().split('.')[0])
- }
- )
-
-
-@login_required
-def form_recaptcha_toggle(hashid):
- form = Form.get_with_hashid(hashid)
- valid_check = check_valid_form_settings_request(form)
- if valid_check != True:
- return valid_check
-
- checked_status = request.json['checked']
- form.captcha_disabled = not checked_status
- DB.session.add(form)
- DB.session.commit()
-
- if form.captcha_disabled:
- return jsonify(disabled=True, message='CAPTCHA successfully disabled')
- else:
- return jsonify(disabled=False, message='CAPTCHA successfully enabled')
-
-@login_required
-def form_email_notification_toggle(hashid):
- form = Form.get_with_hashid(hashid)
- valid_check = check_valid_form_settings_request(form)
- if valid_check != True:
- return valid_check
-
- checked_status = request.json['checked']
- form.disable_email = not checked_status
- DB.session.add(form)
- DB.session.commit()
-
- if form.disable_email:
- return jsonify(disabled=True, message='Email notifications successfully disabled')
- else:
- return jsonify(disabled=False, message='Email notifications successfully enabled')
-
-@login_required
-def form_archive_toggle(hashid):
- form = Form.get_with_hashid(hashid)
- valid_check = check_valid_form_settings_request(form)
- if valid_check != True:
- return valid_check
-
- checked_status = request.json['checked']
- form.disable_storage = not checked_status
- DB.session.add(form)
- DB.session.commit()
-
- if form.disable_storage:
- return jsonify(disabled=True, message='Submission archive successfully disabled')
- else:
- return jsonify(disabled=False, message='Submission archive successfully enabled')
-
-@login_required
-def form_toggle(hashid):
- form = Form.get_with_hashid(hashid)
-
- # check that this request came from user dashboard to prevent XSS and CSRF
- if not valid_domain_request(request):
- return render_template('error.html',
- title='Improper Request',
- text='The request you made is not valid. Please visit your dashboard and try again.'), 400
-
- if form.owner_id != current_user.id:
- if form not in current_user.forms: #accounts for bug when form isn't assigned owner_id bc it was not created from dashboard
- return render_template('error.html',
- title='Wrong user',
- text='You aren\'t the owner of that form. Please log in as the form owner and try again.'), 400
- if not form:
- return render_template('error.html',
- title='Not a valid form',
- text='That form does not exist. Please check the link and try again.'), 400
- else:
- form.disabled = not form.disabled
- DB.session.add(form)
- DB.session.commit()
- if form.disabled:
- flash(u'Form successfully disabled', 'success')
- else:
- flash(u'Form successfully enabled', 'success')
- return redirect(url_for('dashboard'))
-
-
-@login_required
-def form_deletion(hashid):
- form = Form.get_with_hashid(hashid)
-
- # check that this request came from user dashboard to prevent XSS and CSRF
- referrer = referrer_to_baseurl(request.referrer)
- service = referrer_to_baseurl(settings.SERVICE_URL)
- if referrer != service:
- return render_template('error.html',
- title='Improper Request',
- text='The request you made is not valid. Please visit your dashboard and try again.'), 400
-
- if form.owner_id != current_user.id:
- if form not in current_user.forms: #accounts for bug when form isn't assigned owner_id bc it was not created from dashboard
- return render_template('error.html',
- title='Wrong user',
- text='You aren\'t the owner of that form. Please log in as the form owner and try again.'), 400
- if not form:
- return render_template('error.html',
- title='Not a valid form',
- text='That form does not exist. Please check the link and try again.'), 400
- else:
- for submission in form.submissions:
- DB.session.delete(submission)
- DB.session.delete(form)
- DB.session.commit()
- flash(u'Form successfully deleted', 'success')
- return redirect(url_for('dashboard'))
-
-
-@login_required
-def submission_deletion(hashid, submissionid):
- submission = Submission.query.get(submissionid)
- form = Form.get_with_hashid(hashid)
-
- # check that this request came from user dashboard to prevent XSS and CSRF
- referrer = referrer_to_baseurl(request.referrer)
- service = referrer_to_baseurl(settings.SERVICE_URL)
- if referrer != service:
- return render_template('error.html',
- title='Improper Request',
- text='The request you made is not valid. Please visit your dashboard and try again.'), 400
-
- if form.owner_id != current_user.id:
- if form not in current_user.forms: #accounts for bug when form isn't assigned owner_id bc it was not created from dashboard
- return render_template('error.html',
- title='Wrong user',
- text='You aren\'t the owner of that form. Please log in as the form owner and try again.' + str(form.id)), 400
- if not submission:
- return render_template('error.html',
- title='Not a valid submission',
- text='That submission does not exist. Please check the link and try again.'), 400
- elif submission.form_id != form.id:
- return render_template('error.html',
- title='Not a valid submissions',
- text='That submission does not match the form provided. Please check the link and try again.'), 400
- else:
- DB.session.delete(submission)
- form.counter -= 1
- DB.session.add(form)
- DB.session.commit()
- flash(u'Submission successfully deleted', 'success')
- return redirect(url_for('form-submissions', hashid=hashid))
+ return Response(
+ out.getvalue(),
+ mimetype='text/csv',
+ headers={
+ 'Content-Disposition': 'attachment; filename=form-%s-submissions-%s.csv' \
+ % (hashid, datetime.datetime.now().isoformat().split('.')[0])
+ }
+ )
diff --git a/formspree/js/forms/CreateForm.js b/formspree/js/forms/CreateForm.js
new file mode 100644
index 0000000..c278aaa
--- /dev/null
+++ b/formspree/js/forms/CreateForm.js
@@ -0,0 +1,262 @@
+/** @format */
+
+const url = require('url')
+const isValidUrl = require('valid-url').isWebUri
+const isValidEmail = require('is-valid-email')
+const React = require('react')
+const toastr = window.toastr
+
+const modals = require('../modals')
+
+module.exports = class CreateForm extends React.Component {
+ constructor(props) {
+ super(props)
+
+ this.setEmail = this.setEmail.bind(this)
+ this.setURL = this.setURL.bind(this)
+ this.setSitewide = this.setSitewide.bind(this)
+ this.validate = this.validate.bind(this)
+ this.create = this.create.bind(this)
+ this.checkSitewide = this.checkSitewide.bind(this)
+
+ this.state = {
+ url: '',
+ email: '',
+ sitewide: false,
+
+ invalid: null,
+ verified: false,
+ disableVerification: false
+ }
+ }
+
+ componentDidMount() {
+ modals()
+ }
+
+ render() {
+ if (!this.props.user.upgraded) {
+ return (
+
+ Please upgrade your account in order to create
+ forms from the dashboard and manage the forms currently associated
+ with your emails.
+
+ )
+ }
+
+ let {
+ email,
+ url: urlv,
+ sitewide,
+ invalid,
+ verified,
+ disableVerification
+ } = this.state
+
+ return (
+
+ )
+ }
+
+ setEmail(e) {
+ this.setState({email: e.target.value}, this.validate)
+ }
+
+ setURL(e) {
+ this.setState({url: e.target.value}, this.validate)
+ }
+
+ setSitewide(e) {
+ this.setState({sitewide: e.target.checked}, this.validate)
+ }
+
+ validate() {
+ this.setState(st => {
+ st.invalid = null
+
+ let {email, url: urlv, sitewide} = st
+ urlv = /^https?:\/\//.test(urlv) ? urlv : 'http://' + urlv
+
+ if (!isValidEmail(email)) {
+ st.invalid = 'email'
+ return
+ }
+
+ if (sitewide) {
+ if (urlv && !isValidUrl(urlv)) {
+ st.invalid = 'urlv'
+ }
+ } else {
+ if (urlv && urlv !== 'http://' && !isValidUrl(urlv)) {
+ st.invalid = 'urlv'
+ }
+ }
+
+ return st
+ })
+ }
+
+ async checkSitewide(e) {
+ e.preventDefault()
+
+ try {
+ let r = await (await fetch(`/api/forms/sitewide-check`, {
+ method: 'POST',
+ body: JSON.stringify({email: this.state.email, url: this.state.url}),
+ credentials: 'same-origin',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json'
+ }
+ })).json()
+
+ if (!r.ok) {
+ toastr.warning("The verification file wasn't found.")
+ this.setState({verified: false, disableVerification: true})
+
+ setTimeout(() => {
+ this.setState({disableVerification: false})
+ }, 5000)
+ return
+ }
+
+ toastr.success('The file exists! you can create your site-wide form now.')
+ this.setState({verified: true})
+ } catch (e) {
+ console.error(e)
+ toastr.error(e.message)
+ }
+ }
+
+ async create(e) {
+ e.preventDefault()
+
+ try {
+ let r = await (await fetch('/api/forms', {
+ method: 'POST',
+ body: JSON.stringify({
+ email: this.state.email,
+ url: this.state.url,
+ sitewide: this.state.sitewide
+ }),
+ credentials: 'same-origin',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json'
+ }
+ })).json()
+
+ toastr.success('Form created!')
+ this.props.history.push(`/forms/${r.hashid}`)
+ } catch (e) {
+ console.error(e)
+ toastr.error(e.message)
+ }
+ }
+}
diff --git a/formspree/js/forms/FormList.js b/formspree/js/forms/FormList.js
new file mode 100644
index 0000000..fba7c7e
--- /dev/null
+++ b/formspree/js/forms/FormList.js
@@ -0,0 +1,200 @@
+/** @format */
+
+const React = require('react')
+const cs = require('class-set')
+const {Link} = require('react-router-dom')
+const createPortal = require('react-dom').createPortal
+
+const CreateForm = require('./CreateForm')
+const HeaderPortal = require('./HeaderPortal')
+
+module.exports = class FormList extends React.Component {
+ constructor(props) {
+ super(props)
+
+ this.state = {
+ loading: true,
+ user: {},
+ enabled_forms: [],
+ disabled_forms: [],
+ error: null
+ }
+ }
+
+ async componentDidMount() {
+ try {
+ let r = await (await fetch('/api/forms', {
+ credentials: 'same-origin',
+ headers: {Accept: 'application/json'}
+ })).json()
+
+ this.setState({
+ user: r.user,
+ enabled_forms: r.forms.filter(f => !f.disabled),
+ disabled_forms: r.forms.filter(f => f.disabled),
+ loading: false
+ })
+ } catch (e) {
+ console.error(e)
+ this.setState({error: e.message})
+ }
+ }
+
+ render() {
+ if (this.state.loading) {
+ return (
+
+ )
+ }
+
+ if (this.state.error) {
+ return (
+
+
+ An error has ocurred while we were trying to fetch your forms,
+ please try again or contact us at support@formspree.io.
+
+
+ )
+ }
+
+ return (
+ <>
+
+ Your Forms
+
+
+
Active Forms
+ {this.state.enabled_forms.length ? (
+
+
+ {this.state.enabled_forms.map(form => (
+
+ ))}
+
+
+ ) : (
+
+ No active forms found. Forms can be enabled by clicking the unlock
+ icon below.
+
+ )}
+
+ {this.state.disabled_forms.length ? (
+ <>
+
Disabled Forms
+
+
+ {this.state.disabled_forms.map(form => (
+
+ ))}
+
+
+ >
+ ) : null}
+
+ {this.state.enabled_forms.length === 0 &&
+ this.state.disabled_forms.length === 0 &&
+ this.user.upgraded ? (
+
+ You don't have any forms associated with this account, maybe you
+ should verify your email .
+
+ ) : null}
+
+
+
+ >
+ )
+ }
+}
+
+class FormItem extends React.Component {
+ render() {
+ let form = this.props
+
+ return (
+
+
+
+ {form.host ? (
+ form.confirmed ? (
+
+
+
+ ) : form.confirm_sent ? (
+
+
+
+ ) : null
+ ) : (
+
+
+
+ )}
+
+
+
+
+ {form.host ? (
+
+ {form.host}
+ {form.sitewide ? (
+
+ / *
+
+ ) : null}
+
+ ) : (
+ 'Waiting for a submission'
+ )}
+
+
+
+
+
+ {form.email}
+
+
+
+
+
+ {form.counter == 0 ? (
+ never submitted
+ ) : (
+ `${form.counter} submissions`
+ )}
+
+
+
+ )
+ }
+}
diff --git a/formspree/js/forms/FormPage.js b/formspree/js/forms/FormPage.js
new file mode 100644
index 0000000..cc0d684
--- /dev/null
+++ b/formspree/js/forms/FormPage.js
@@ -0,0 +1,476 @@
+/** @format */
+
+const toastr = window.toastr
+const React = require('react')
+const {Route, NavLink, Redirect} = require('react-router-dom')
+const CodeMirror = require('react-codemirror2')
+require('codemirror/mode/xml/xml')
+
+const HeaderPortal = require('./HeaderPortal')
+
+module.exports = class FormPage extends React.Component {
+ constructor(props) {
+ super(props)
+
+ this.state = {
+ form: null
+ }
+
+ this.fetchForm = this.fetchForm.bind(this)
+ }
+
+ async componentDidMount() {
+ this.fetchForm()
+ }
+
+ render() {
+ let hashid = this.props.match.params.hashid
+
+ return (
+ <>
+
+ {hashid}
+
+
+ Submission History
+
+
+ Form Settings
+
+
+
+ }
+ />
+ {this.state.form && (
+ <>
+ (
+
+ )}
+ />
+ (
+
+ )}
+ />
+ >
+ )}
+ >
+ )
+ }
+
+ async fetchForm() {
+ let hashid = this.props.match.params.hashid
+
+ try {
+ let r = await (await fetch(`/api/forms/${hashid}`, {
+ credentials: 'same-origin',
+ headers: {Accept: 'application/json'}
+ })).json()
+
+ this.setState({form: r})
+ } catch (e) {
+ console.error(e)
+ toastr.error(`Failed to fetch form, see the console for more details.`)
+ }
+ }
+}
+
+class FormSubmissions extends React.Component {
+ constructor(props) {
+ super(props)
+
+ this.deleteSubmission = this.deleteSubmission.bind(this)
+ }
+
+ render() {
+ let {form} = this.props
+
+ return (
+
+
+ Submissions for
+ {!form.hash ? (
+ /{form.hashid}
+ ) : (
+ /{form.email}
+ )}
+ on {form.host}
+ {form.sitewide ? 'and all its subpaths.' : null}
+ {form.hash ? (
+ <>
+
+
+ you can now replace the email in the URL with{' '}
+ {`/${form.hashid}`}
+
+ >
+ ) : (
+ <>
+
+
+ targeting {form.email}
+
+ >
+ )}
+
+ {form.submissions.length ? (
+
+
+
+ Submitted at
+ {form.fields.slice(1 /* the first field is 'date' */).map(f => (
+ {f}
+ ))}
+
+
+
+
+ {form.submissions.map(s => (
+
+
+ {new Date(Date.parse(s.date))
+ .toString()
+ .split(' ')
+ .slice(0, 5)
+ .join(' ')}
+
+ {form.fields
+ .slice(1 /* the first field is 'date' */)
+ .map(f => (
+
+ {s[f]}
+
+ ))}
+
+
+
+
+
+
+ ))}
+
+
+ ) : (
+
No submissions archived yet.
+ )}
+
+ )
+ }
+
+ async deleteSubmission(e) {
+ e.preventDefault()
+
+ let subid = e.currentTarget.dataset.sub
+
+ try {
+ let r = await (await fetch(
+ `/api/forms/${this.props.form.hashid}/submissions/${subid}`,
+ {
+ method: 'DELETE',
+ credentials: 'same-origin',
+ headers: {Accept: 'application/json'}
+ }
+ )).json()
+
+ if (r.error) {
+ toastr.warning(`Failed to delete submission: ${r.error}`)
+ return
+ }
+
+ toastr.success('Submission deleted.')
+ this.props.onUpdate()
+ } catch (e) {
+ console.error(e)
+ toastr.error(
+ 'Failed to delete submission, see the console for more details.'
+ )
+ }
+ }
+}
+
+class FormSettings extends React.Component {
+ constructor(props) {
+ super(props)
+
+ this.update = this.update.bind(this)
+ this.deleteForm = this.deleteForm.bind(this)
+ this.cancelDelete = this.cancelDelete.bind(this)
+
+ this.state = {
+ deleting: false
+ }
+ }
+
+ render() {
+ let {form} = this.props
+
+ return (
+ <>
+
+
Sample HTML
+
+
+
+
+ Use this code in your HTML, modifying it according to your
+ needs:
+
+
+
+ Your email:
+
+
+
+ Your message:
+
+
+
+
+
+ Send
+`}
+ options={{
+ theme: 'oceanic-next',
+ mode: 'xml',
+ viewportMargin: Infinity
+ }}
+ />
+
+
+
+
+
+
Form Settings
+
+
+
+
Form Enabled
+
+ You can disable this form to cause it to stop receiving new
+ submissions temporarily or permanently.
+
+
+
+
+
+
+
+
+
+
+
+
+
reCAPTCHA
+
+
+ reCAPTCHA provides vital spam protection, but you can turn it
+ off if you need.
+
+
+
+
+
+
+
Email Notifications
+
+ You can disable the emails Formspree sends if you just want to
+ download the submissions from the dashboard.
+
+
+
+
+
+
+
+
+
+
+
+
Submission Archive
+
+ You can disable the submission archive if you don't want
+ Formspree to store your submissions.
+
+
+
+
+
+
+
+
+
+
+
+
+ {this.state.deleting
+ ? 'Are you sure you want to delete?'
+ : 'Delete Form'}
+
+
+ {this.state.deleting ? (
+
+ This will delete the form on {form.host} targeting{' '}
+ {form.email} and all its submissions? This action{' '}
+ cannot be undone.
+
+ ) : (
+
+ Deleting the form will erase all traces of this form on
+ our databases, including all the submissions.
+
+ )}
+
+
+
+ {this.state.deleting ? (
+ <>
+
+ Sure, erase everything
+
+
+ No, don't delete!
+
+ >
+ ) : (
+
+
+
+ )}
+
+
+
+
+ >
+ )
+ }
+
+ async update(e) {
+ try {
+ let res = await (await fetch(`/api/forms/${this.props.form.hashid}`, {
+ method: 'PATCH',
+ body: JSON.stringify({
+ [e.currentTarget.name]: !e.currentTarget.checked
+ }),
+ credentials: 'same-origin',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json'
+ }
+ })).json()
+
+ if (res.error) {
+ toastr.warning(`Failed to save settings: ${res.error}`)
+ return
+ }
+
+ toastr.success('Settings saved.')
+ this.props.onUpdate()
+ } catch (e) {
+ console.error(e)
+ toastr.error('Failed to update form. See the console for more details.')
+ }
+ }
+
+ cancelDelete(e) {
+ e.preventDefault()
+ this.setState({deleting: false})
+ }
+
+ async deleteForm(e) {
+ e.preventDefault()
+
+ if (this.props.form.counter > 0 && !this.state.deleting) {
+ // double-check the user intentions to delete,
+ // but only if the form has been used already.
+ this.setState({deleting: true})
+ return
+ }
+
+ this.setState({deleting: false})
+ try {
+ let res = await (await fetch(`/api/forms/${this.props.form.hashid}`, {
+ method: 'DELETE',
+ credentials: 'same-origin',
+ headers: {
+ Accept: 'application/json'
+ }
+ })).json()
+
+ if (res.error) {
+ toastr.warning(`Failed to delete form: ${res.error}`)
+ return
+ }
+
+ toastr.success('Form successfully deleted.')
+ this.props.history.push('/forms')
+ } catch (e) {
+ console.error(e)
+ toastr.error('Failed to delete form. See the console for more details.')
+ }
+ }
+}
diff --git a/formspree/js/forms/HeaderPortal.js b/formspree/js/forms/HeaderPortal.js
new file mode 100644
index 0000000..7642c45
--- /dev/null
+++ b/formspree/js/forms/HeaderPortal.js
@@ -0,0 +1,7 @@
+/** @format */
+
+const createPortal = require('react-dom').createPortal
+
+module.exports = function TitlePortal(props) {
+ return createPortal(props.children, document.querySelector('#header .center'))
+}
diff --git a/formspree/js/forms/dashboard.js b/formspree/js/forms/dashboard.js
new file mode 100644
index 0000000..185e367
--- /dev/null
+++ b/formspree/js/forms/dashboard.js
@@ -0,0 +1,24 @@
+/** @format */
+
+const React = require('react')
+const render = require('react-dom').render
+const {BrowserRouter: Router, Route} = require('react-router-dom')
+
+const FormList = require('./FormList')
+const FormPage = require('./FormPage')
+
+class Dashboard extends React.Component {
+ render() {
+ return (
+
+ <>
+
+
+
+ >
+
+ )
+ }
+}
+
+render( , document.querySelector('.container.block'))
diff --git a/formspree/js/main.js b/formspree/js/main.js
new file mode 100644
index 0000000..c8463b9
--- /dev/null
+++ b/formspree/js/main.js
@@ -0,0 +1,99 @@
+/**
+ * @format
+ */
+
+const $ = window.$
+const StripeCheckout = window.StripeCheckout
+const toastr = window.toastr
+
+toastr.options = {positionClass: 'toast-top-center'}
+
+/* top navbar */
+var nav = $('body > nav')
+nav.addClass('js')
+nav.find('.menu').slicknav()
+nav
+ .find('h4')
+ .clone()
+ .prependTo('.slicknav_menu')
+
+/* adding a shadow at the bottom of the menu bar only when not at the top */
+var w = $(window)
+w.scroll(function() {
+ var scrollPos = w.scrollTop()
+ if (scrollPos && !nav.hasClass('scrolled')) {
+ nav.addClass('scrolled')
+ } else if (!scrollPos) {
+ nav.removeClass('scrolled')
+ }
+})
+
+/* background-color should inherit, but CSS's "inherit" breaks z-index */
+var bgcolor = $(document.body).css('background-color')
+if (bgcolor.split(',').length === 4 || bgcolor === 'transparent') {
+ bgcolor = 'white'
+}
+nav.css('background-color', bgcolor)
+
+/* modals -- working with or without JS */
+require('./modals')()
+
+/* turning flask flash messages into js popup notifications */
+window.popupMessages.forEach(function(m, i) {
+ var category = m[0] || 'info'
+ var text = m[1]
+ setTimeout(function() {
+ toastr[category](text)
+ }, (1 + i) * 1500)
+})
+
+/* stripe checkout */
+var stripebutton = $('#stripe-upgrade')
+if (stripebutton.length) {
+ var handler = StripeCheckout.configure(stripebutton.data())
+ stripebutton.on('click', function(e) {
+ handler.open({
+ token: function(token) {
+ stripebutton
+ .closest('form')
+ .append(
+ ` `
+ )
+ .append(
+ ` `
+ )
+ .submit()
+ }
+ })
+ e.preventDefault()
+ })
+}
+
+/* quick script for showing the resend confirmation form */
+$('a.resend').on('click', function() {
+ $(this).hide()
+ $('form.resend').show()
+ return false
+})
+
+/* scripts at other files */
+require('./forms/dashboard.js')
+
+/* toggle the card management menu */
+$(function() {
+ $('#card-list tr:even').addClass('even')
+ $('#card-list tr:not(.even)').hide()
+ $('#card-list tr:first-child').show()
+
+ $('#card-list tr.even').click(function() {
+ $(this)
+ .next('tr')
+ .toggle()
+ $(this)
+ .find('.arrow')
+ .toggleClass('up')
+ $(this)
+ .find('.fa-chevron-right')
+ .toggleClass('fa-rotate-90')
+ })
+})
diff --git a/formspree/js/modals.js b/formspree/js/modals.js
new file mode 100644
index 0000000..d6c85c3
--- /dev/null
+++ b/formspree/js/modals.js
@@ -0,0 +1,53 @@
+/** @format */
+
+const $ = window.$
+
+module.exports = function modals() {
+ $('.modal').each(function() {
+ let modal = $(this)
+ modal.addClass('js')
+ let id = modal.attr('id')
+
+ $(`[href="#${id}"]`).click(function(e) {
+ // open the modal
+ e.preventDefault()
+ modal.toggleClass('target')
+ })
+
+ modal.click(function(e) {
+ // close the modal
+ if (e.target === modal[0]) {
+ cleanHash()
+ modal.toggleClass('target')
+ e.preventDefault()
+ }
+ })
+ modal.find('.x a').click(function(e) {
+ // close the modal
+ cleanHash()
+ e.preventDefault()
+ modal.toggleClass('target')
+ })
+ })
+
+ function cleanHash() {
+ if (!window.location.hash) return
+ if (window.history && window.history.replaceState) {
+ window.history.replaceState('', document.title, window.location.pathname)
+ } else {
+ let pos = $(window).scrollTop()
+ window.location.hash = ''
+ $(window).scrollTop(pos)
+ }
+ }
+
+ // activate modals from url hash #
+ setTimeout(() => {
+ // setTimeout is needed because :target elements only appear after
+ // the page is loaded or something like that.
+ let activatedModal = $('*:target')
+ if (activatedModal.length && !activatedModal.is('.target')) {
+ activatedModal.toggleClass('target')
+ }
+ }, 0)
+}
diff --git a/formspree/static/js/sitewide.js b/formspree/js/sitewide.js
similarity index 62%
rename from formspree/static/js/sitewide.js
rename to formspree/js/sitewide.js
index d34adf8..03224e6 100644
--- a/formspree/static/js/sitewide.js
+++ b/formspree/js/sitewide.js
@@ -1,3 +1,5 @@
+/** @format */
+
const url = require('url')
const isValidUrl = require('valid-url').isWebUri
const isValidEmail = require('is-valid-email')
@@ -11,7 +13,7 @@ const $ = window.$
const toastr = window.toastr
/* create-form validation for site-wide forms */
-module.exports = function sitewide () {
+module.exports = function sitewide() {
var parentNode = $('#create-form .container')
if (!parentNode.length) return
@@ -37,20 +39,29 @@ module.exports = function sitewide () {
parentNode.on('input', 'input[name="url"], input[name="email"]', run)
parentNode.on('click', '.verify button', check)
- function run () {
+ function run() {
let checkbox = parentNode.find('input[name="sitewide"]')
- let email = parentNode.find('input[name="email"]').val().trim()
- let urlv = parentNode.find('input[name="url"]').val().trim()
+ let email = parentNode
+ .find('input[name="email"]')
+ .val()
+ .trim()
+ let urlv = parentNode
+ .find('input[name="url"]')
+ .val()
+ .trim()
urlv = /^https?:\/\//.test(urlv) ? urlv : 'http://' + urlv
let sitewide = checkbox.is(':checked')
// wrong input
- if (!isValidEmail(email)) { // invalid email
+ if (!isValidEmail(email)) {
+ // invalid email
data.invalid = 'email'
- } else if (sitewide && !isValidUrl(urlv)) { // invalid url with sitewide
+ } else if (sitewide && !isValidUrl(urlv)) {
+ // invalid url with sitewide
data.invalid = 'url'
- } else if (!sitewide && urlv && urlv !== 'http://' && !isValidUrl(urlv)) { // invalid url without sitewide
+ } else if (!sitewide && urlv && urlv !== 'http://' && !isValidUrl(urlv)) {
+ // invalid url without sitewide
data.invalid = 'url'
} else {
data.invalid = null
@@ -63,15 +74,17 @@ module.exports = function sitewide () {
apply(render(data))
}
- function check () {
+ function check() {
$.ajax({
url: '/forms/sitewide-check?' + parentNode.find('form').serialize(),
- success: function () {
- toastr.success('The file exists! you can create your site-wide form now.')
+ success: function() {
+ toastr.success(
+ 'The file exists! you can create your site-wide form now.'
+ )
data.verified = true
apply(render(data))
},
- error: function () {
+ error: function() {
toastr.warning("The verification file wasn't found.")
data.verified = false
data.disableVerification = true
@@ -87,17 +100,29 @@ module.exports = function sitewide () {
return false
}
- function apply (vtree) {
+ function apply(vtree) {
let patches = diff(tree, vtree)
rootNode = patch(rootNode, patches)
tree = vtree
}
- function render ({invalid, sitewide, verified, urlv, email, disableVerification}) {
+ function render({
+ invalid,
+ sitewide,
+ verified,
+ urlv,
+ email,
+ disableVerification
+ }) {
return h('form', {method: 'post', action: formActionURL}, [
h('.col-1-1', [
h('h4', 'Send email to:'),
- h('input', {type: 'email', name: 'email', placeholder: emailPlaceholder, value: email})
+ h('input', {
+ type: 'email',
+ name: 'email',
+ placeholder: emailPlaceholder,
+ value: email
+ })
]),
h('.col-1-1', [
h('h4', 'From URL:'),
@@ -112,35 +137,47 @@ module.exports = function sitewide () {
]),
h('.col-3-4.info', [
invalid
- ? h('div.red', invalid === 'email'
- ? 'Please input a valid email address.'
- : [
- 'Please input a valid URL. For example: ',
- h('span.code', url.resolve('http://www.mywebsite.com', sitewide ? '' : '/contact.html'))
- ])
- : sitewide && verified || !sitewide
+ ? h(
+ 'div.red',
+ invalid === 'email'
+ ? 'Please input a valid email address.'
+ : [
+ 'Please input a valid URL. For example: ',
+ h(
+ 'span.code',
+ url.resolve(
+ 'http://www.mywebsite.com',
+ sitewide ? '' : '/contact.html'
+ )
+ )
+ ]
+ )
+ : (sitewide && verified) || !sitewide
? h('div', {innerHTML: ''})
: h('span', [
- 'Please ensure ',
- h('span.code', url.resolve(urlv, '/formspree-verify.txt')),
- ' exists and contains a line with ',
- h('span.code', email)
- ])
+ 'Please ensure ',
+ h('span.code', url.resolve(urlv, '/formspree-verify.txt')),
+ ' exists and contains a line with ',
+ h('span.code', email)
+ ])
]),
h('.col-1-3', [
h('.verify', [
- h('button', sitewide && !invalid && !disableVerification
- ? {}
- : sitewide
- ? {disabled: true}
- : {style: {visibility: 'hidden'}, disabled: true},
- 'Verify')
+ h(
+ 'button',
+ sitewide && !invalid && !disableVerification
+ ? {}
+ : sitewide
+ ? {disabled: true}
+ : {style: {visibility: 'hidden'}, disabled: true},
+ 'Verify'
+ )
])
]),
h('.col-1-3', {innerHTML: ''}),
h('.col-1-3', [
h('.create', [
- sitewide && verified || !sitewide && !invalid
+ (sitewide && verified) || (!sitewide && !invalid)
? h('button', {type: 'submit'}, 'Create form')
: h('button', {disabled: true}, 'Create form')
])
diff --git a/formspree/routes.py b/formspree/routes.py
index 559b5db..3cfd102 100644
--- a/formspree/routes.py
+++ b/formspree/routes.py
@@ -1,4 +1,5 @@
import formspree.forms.views as fv
+import formspree.forms.api as fa
import formspree.users.views as uv
import formspree.static_pages.views as sv
@@ -37,18 +38,18 @@ def configure_routes(app):
app.add_url_rule('/logout', 'logout', view_func=uv.logout, methods=['GET'])
# Users' forms
- app.add_url_rule('/dashboard', 'dashboard', view_func=fv.forms, methods=['GET'])
- app.add_url_rule('/forms', 'forms', view_func=fv.forms, methods=['GET'])
- app.add_url_rule('/forms', 'create-form', view_func=fv.create_form, methods=['POST'])
- app.add_url_rule('/forms/sitewide-check', view_func=fv.sitewide_check, methods=['GET'])
- app.add_url_rule('/forms//', 'form-submissions', view_func=fv.form_submissions, methods=['GET'])
- app.add_url_rule('/forms/.', 'form-submissions', view_func=fv.form_submissions, methods=['GET'])
- app.add_url_rule('/forms//toggle-recaptcha', 'toggle-recaptcha', view_func=fv.form_recaptcha_toggle, methods=['POST'])
- app.add_url_rule('/forms//toggle-emails', 'toggle-emails', view_func=fv.form_email_notification_toggle, methods=['POST'])
- app.add_url_rule('/forms//toggle-storage', 'toggle-storage', view_func=fv.form_archive_toggle, methods=['POST'])
- app.add_url_rule('/forms//toggle', 'form-toggle', view_func=fv.form_toggle, methods=['POST'])
- app.add_url_rule('/forms//delete', 'form-deletion', view_func=fv.form_deletion, methods=['POST'])
- app.add_url_rule('/forms//delete/', 'submission-deletion', view_func=fv.submission_deletion, methods=['POST'])
+ app.add_url_rule('/dashboard', 'dashboard', view_func=fv.serve_dashboard, methods=['GET'])
+ app.add_url_rule('/forms', 'dashboard', view_func=fv.serve_dashboard, methods=['GET'])
+ app.add_url_rule('/forms/', view_func=fv.serve_dashboard, methods=['GET'])
+ app.add_url_rule('/forms//', view_func=fv.serve_dashboard, methods=['GET'])
+ app.add_url_rule('/forms/.', view_func=fv.export_submissions, methods=['GET'])
+ app.add_url_rule('/api/forms', view_func=fa.list, methods=['GET'])
+ app.add_url_rule('/api/forms', view_func=fa.create, methods=['POST'])
+ app.add_url_rule('/api/forms/', view_func=fa.get, methods=['GET'])
+ app.add_url_rule('/api/forms/', view_func=fa.update, methods=['PATCH'])
+ app.add_url_rule('/api/forms/', view_func=fa.delete, methods=['DELETE'])
+ app.add_url_rule('/api/forms/sitewide-check', view_func=fa.sitewide_check, methods=['POST'])
+ app.add_url_rule('/api/forms//submissions/', view_func=fa.submission_delete, methods=['DELETE'])
# Webhooks
app.add_url_rule('/webhooks/stripe', view_func=uv.stripe_webhook, methods=['POST'])
diff --git a/formspree/static/scss/alertbox.scss b/formspree/scss/alertbox.scss
similarity index 100%
rename from formspree/static/scss/alertbox.scss
rename to formspree/scss/alertbox.scss
diff --git a/formspree/static/scss/dashboard.scss b/formspree/scss/dashboard.scss
similarity index 95%
rename from formspree/static/scss/dashboard.scss
rename to formspree/scss/dashboard.scss
index 39bdbb1..841c0fa 100644
--- a/formspree/static/scss/dashboard.scss
+++ b/formspree/scss/dashboard.scss
@@ -111,6 +111,14 @@
}
.dashboard {
+ #header {
+ h3 {
+ a {
+ margin: 0 10px;
+ }
+ }
+ }
+
.row:after {
content: "";
display: none;
@@ -444,38 +452,16 @@
}
}
-.html-highlight {
- clear: both;
- font-size: 14px;
- font-family: monospace;
- padding: 5px;
- border: 2px dashed #696969;
- border-radius: 5px;
-
- .bracket {
- color: #a65700
- }
- .tagname {
- color: #800000;
- font-weight: bold;
- }
- .attrkey {
- color: #074726
- }
- .equal {
- color: #808030
- }
- .attrvalue {
- color: #0000e6
- }
- .comment {
- color: #696969
- }
-}
-
a.button.export {
width: 11em;
text-align: center;
display: inline-block;
margin: 0 0 20px 20px;
}
+
+.CodeMirror {
+ border: 1px solid #eee;
+ padding: 10px;
+ height: auto;
+ font-size: 90%;
+}
diff --git a/formspree/static/scss/formspree.scss b/formspree/scss/formspree.scss
similarity index 100%
rename from formspree/static/scss/formspree.scss
rename to formspree/scss/formspree.scss
diff --git a/formspree/static/scss/grid.scss b/formspree/scss/grid.scss
similarity index 100%
rename from formspree/static/scss/grid.scss
rename to formspree/scss/grid.scss
diff --git a/formspree/static/scss/hint/hint-always.scss b/formspree/scss/hint/hint-always.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-always.scss
rename to formspree/scss/hint/hint-always.scss
diff --git a/formspree/static/scss/hint/hint-color-types.scss b/formspree/scss/hint/hint-color-types.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-color-types.scss
rename to formspree/scss/hint/hint-color-types.scss
diff --git a/formspree/static/scss/hint/hint-core.scss b/formspree/scss/hint/hint-core.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-core.scss
rename to formspree/scss/hint/hint-core.scss
diff --git a/formspree/static/scss/hint/hint-effects.scss b/formspree/scss/hint/hint-effects.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-effects.scss
rename to formspree/scss/hint/hint-effects.scss
diff --git a/formspree/static/scss/hint/hint-mixins.scss b/formspree/scss/hint/hint-mixins.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-mixins.scss
rename to formspree/scss/hint/hint-mixins.scss
diff --git a/formspree/static/scss/hint/hint-position.scss b/formspree/scss/hint/hint-position.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-position.scss
rename to formspree/scss/hint/hint-position.scss
diff --git a/formspree/static/scss/hint/hint-rounded.scss b/formspree/scss/hint/hint-rounded.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-rounded.scss
rename to formspree/scss/hint/hint-rounded.scss
diff --git a/formspree/static/scss/hint/hint-variables.scss b/formspree/scss/hint/hint-variables.scss
similarity index 100%
rename from formspree/static/scss/hint/hint-variables.scss
rename to formspree/scss/hint/hint-variables.scss
diff --git a/formspree/static/scss/hint/hint.scss b/formspree/scss/hint/hint.scss
similarity index 100%
rename from formspree/static/scss/hint/hint.scss
rename to formspree/scss/hint/hint.scss
diff --git a/formspree/static/scss/ionicons/_ionicons-font.scss b/formspree/scss/ionicons/_ionicons-font.scss
similarity index 100%
rename from formspree/static/scss/ionicons/_ionicons-font.scss
rename to formspree/scss/ionicons/_ionicons-font.scss
diff --git a/formspree/static/scss/ionicons/_ionicons-icons.scss b/formspree/scss/ionicons/_ionicons-icons.scss
similarity index 100%
rename from formspree/static/scss/ionicons/_ionicons-icons.scss
rename to formspree/scss/ionicons/_ionicons-icons.scss
diff --git a/formspree/static/scss/ionicons/_ionicons-variables.scss b/formspree/scss/ionicons/_ionicons-variables.scss
similarity index 99%
rename from formspree/static/scss/ionicons/_ionicons-variables.scss
rename to formspree/scss/ionicons/_ionicons-variables.scss
index 034a14a..bdeafdf 100644
--- a/formspree/static/scss/ionicons/_ionicons-variables.scss
+++ b/formspree/scss/ionicons/_ionicons-variables.scss
@@ -1,7 +1,7 @@
// Ionicons Variables
// --------------------------
-$ionicons-font-path: "../fonts" !default;
+$ionicons-font-path: "fonts" !default;
$ionicons-font-family: "Ionicons" !default;
$ionicons-version: "2.0.1" !default;
$ionicons-prefix: ion- !default;
@@ -738,4 +738,4 @@ $ionicon-var-wifi: "\f25c";
$ionicon-var-wineglass: "\f2b9";
$ionicon-var-woman: "\f25d";
$ionicon-var-wrench: "\f2ba";
-$ionicon-var-xbox: "\f30c";
\ No newline at end of file
+$ionicon-var-xbox: "\f30c";
diff --git a/formspree/static/scss/ionicons/ionicons.scss b/formspree/scss/ionicons/ionicons.scss
similarity index 100%
rename from formspree/static/scss/ionicons/ionicons.scss
rename to formspree/scss/ionicons/ionicons.scss
diff --git a/formspree/static/scss/main.scss b/formspree/scss/main.scss
similarity index 99%
rename from formspree/static/scss/main.scss
rename to formspree/scss/main.scss
index 0459491..94526b4 100644
--- a/formspree/static/scss/main.scss
+++ b/formspree/scss/main.scss
@@ -22,7 +22,7 @@ $error-red: #CC3F36;
@import 'dashboard.scss';
@import 'nav.scss';
@import 'toastr.scss';
-@import 'submissions.scss';
+@import 'settings.scss';
@import 'ionicons/ionicons.scss';
html {
diff --git a/formspree/static/scss/nav.scss b/formspree/scss/nav.scss
similarity index 100%
rename from formspree/static/scss/nav.scss
rename to formspree/scss/nav.scss
diff --git a/formspree/static/scss/normalize.scss b/formspree/scss/normalize.scss
similarity index 100%
rename from formspree/static/scss/normalize.scss
rename to formspree/scss/normalize.scss
diff --git a/formspree/static/scss/reset.scss b/formspree/scss/reset.scss
similarity index 100%
rename from formspree/static/scss/reset.scss
rename to formspree/scss/reset.scss
diff --git a/formspree/scss/settings.scss b/formspree/scss/settings.scss
new file mode 100644
index 0000000..b283b4e
--- /dev/null
+++ b/formspree/scss/settings.scss
@@ -0,0 +1,89 @@
+/** @format */
+
+#settings {
+ p#status {
+ float: right;
+ color: $dark-blue;
+ font-size: 0.7em;
+ margin-right: 2%;
+
+ &.error {
+ color: $red;
+ }
+ }
+
+ h4 {
+ margin: 14px 0 4px 0 !important;
+ }
+
+ p.description {
+ line-height: 1em;
+ display: inline-block;
+ font-size: 0.8em;
+ margin: 0;
+ margin-top: 0.2em;
+ color: #999999;
+ }
+
+ .switch-row {
+ margin: auto;
+ position: relative;
+ text-align: right;
+ .switch {
+ position: absolute;
+ display: inline-block;
+ width: 60px;
+ height: 26px;
+ right: 5%;
+ input {
+ display: none;
+ }
+ }
+ }
+
+ .slider {
+ position: absolute;
+ cursor: pointer;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: #ccc;
+ -webkit-transition: 0.4s;
+ transition: 0.4s;
+
+ &:before {
+ position: absolute;
+ content: '';
+ height: 18px;
+ width: 26px;
+ left: 4px;
+ bottom: 4px;
+ background-color: white;
+ -webkit-transition: 0.4s;
+ transition: 0.4s;
+ }
+ }
+
+ input:checked + .slider {
+ background-color: $dark-green;
+ }
+
+ input:focus + .slider {
+ box-shadow: 0 0 1px $dark-green;
+ }
+
+ input:checked + .slider:before {
+ -webkit-transform: translateX(26px);
+ -ms-transform: translateX(26px);
+ transform: translateX(26px);
+ }
+
+ .row {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ }
+}
diff --git a/formspree/static/scss/slicknav/core.scss b/formspree/scss/slicknav/core.scss
similarity index 100%
rename from formspree/static/scss/slicknav/core.scss
rename to formspree/scss/slicknav/core.scss
diff --git a/formspree/static/scss/slicknav/theme.scss b/formspree/scss/slicknav/theme.scss
similarity index 100%
rename from formspree/static/scss/slicknav/theme.scss
rename to formspree/scss/slicknav/theme.scss
diff --git a/formspree/static/scss/toastr.scss b/formspree/scss/toastr.scss
similarity index 100%
rename from formspree/static/scss/toastr.scss
rename to formspree/scss/toastr.scss
diff --git a/formspree/static/scss/typography.scss b/formspree/scss/typography.scss
similarity index 100%
rename from formspree/static/scss/typography.scss
rename to formspree/scss/typography.scss
diff --git a/formspree/static/css/main.css b/formspree/static/css/main.css
deleted file mode 100644
index 798499f..0000000
--- a/formspree/static/css/main.css
+++ /dev/null
@@ -1,5913 +0,0 @@
-@charset "UTF-8";
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-nav,
-section,
-summary {
- display: block;
-}
-
-audio,
-canvas,
-video {
- display: inline-block;
-}
-
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-
-[hidden], template {
- display: none;
-}
-
-html {
- background: #fff;
- color: #000;
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
-}
-
-html,
-button,
-input,
-select,
-textarea {
- font-family: sans-serif;
-}
-
-body {
- margin: 0;
-}
-
-a {
- background: transparent;
-}
-a:focus {
- outline: thin dotted;
-}
-a:hover, a:active {
- outline: 0;
-}
-
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-
-h2 {
- font-size: 1.5em;
- margin: 0.83em 0;
-}
-
-h3 {
- font-size: 1.17em;
- margin: 1em 0;
-}
-
-h4 {
- font-size: 1em;
- margin: 1.33em 0;
-}
-
-h5 {
- font-size: 0.83em;
- margin: 1.67em 0;
-}
-
-h6 {
- font-size: 0.75em;
- margin: 2.33em 0;
-}
-
-abbr[title] {
- border-bottom: 1px dotted;
-}
-
-b,
-strong {
- font-weight: bold;
-}
-
-dfn {
- font-style: italic;
-}
-
-mark {
- background: #ff0;
- color: #000;
-}
-
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, serif;
- font-size: 1em;
-}
-
-pre {
- white-space: pre;
- white-space: pre-wrap;
- word-wrap: break-word;
-}
-
-q {
- quotes: "“" "”" "‘" "’";
-}
-
-q:before,
-q:after {
- content: "";
- content: none;
-}
-
-small {
- font-size: 80%;
-}
-
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-
-sup {
- top: -0.5em;
-}
-
-sub {
- bottom: -0.25em;
-}
-
-img {
- border: 0;
-}
-
-svg:not(:root) {
- overflow: hidden;
-}
-
-figure {
- margin: 0;
-}
-
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-
-legend {
- border: 0;
- padding: 0;
- white-space: normal;
-}
-
-button,
-input,
-select,
-textarea {
- font-family: inherit;
- font-size: 100%;
- margin: 0;
- vertical-align: baseline;
-}
-
-button,
-input {
- line-height: normal;
-}
-
-button,
-select {
- text-transform: none;
-}
-
-button,
-html input[type=button],
-input[type=reset],
-input[type=submit] {
- -webkit-appearance: button;
- cursor: pointer;
-}
-
-button[disabled],
-input[disabled] {
- cursor: default;
-}
-
-input[type=checkbox],
-input[type=radio] {
- box-sizing: border-box;
- padding: 0;
-}
-
-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;
-}
-
-button::-moz-focus-inner, input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-
-textarea {
- overflow: auto;
- vertical-align: top;
-}
-
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-* {
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
-}
-
-.row {
- width: 100%;
-}
-.row:after {
- content: ".";
- display: block;
- clear: both;
- visibility: hidden;
- line-height: 0;
- height: 0;
-}
-
-.container {
- max-width: 950px;
- margin: 0 auto;
-}
-.container:after {
- content: ".";
- display: block;
- clear: both;
- visibility: hidden;
- line-height: 0;
- height: 0;
-}
-@media (min-width: 760px) {
- .container.narrow {
- max-width: 600px;
- }
-}
-@media (max-width: 760px) {
- .container {
- max-width: 100% !important;
- }
-}
-
-.col-1-1 {
- float: left;
- padding: 0 20px;
- width: 100%;
-}
-@media (max-width: 760px) {
- .col-1-1 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-1-2 {
- float: left;
- padding: 0 20px;
- width: 50%;
-}
-@media (max-width: 760px) {
- .col-1-2 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-1-3 {
- float: left;
- padding: 0 20px;
- width: 33.33%;
-}
-@media (max-width: 760px) {
- .col-1-3 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-2-3 {
- float: left;
- padding: 0 20px;
- width: 66.66%;
-}
-@media (max-width: 760px) {
- .col-2-3 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-1-4 {
- float: left;
- padding: 0 20px;
- width: 25%;
-}
-@media (max-width: 760px) {
- .col-1-4 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-3-4 {
- float: left;
- padding: 0 20px;
- width: 75%;
-}
-@media (max-width: 760px) {
- .col-3-4 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-2-5 {
- float: left;
- padding: 0 20px;
- width: 40%;
-}
-@media (max-width: 760px) {
- .col-2-5 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-3-5 {
- float: left;
- padding: 0 20px;
- width: 60%;
-}
-@media (max-width: 760px) {
- .col-3-5 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-5-12 {
- float: left;
- padding: 0 20px;
- width: 41.67%;
-}
-@media (max-width: 760px) {
- .col-5-12 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-5-6 {
- float: left;
- padding: 0 20px;
- width: 83.33%;
-}
-@media (max-width: 760px) {
- .col-5-6 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-.col-1-6 {
- float: left;
- padding: 0 20px;
- width: 16.67%;
-}
-@media (max-width: 760px) {
- .col-1-6 {
- width: 100% !important;
- margin-bottom: 20px !important;
- }
-}
-
-@media print {
- .col-1-1 {
- width: 100% !important;
- }
-
- .col-1-2 {
- width: 50% !important;
- }
-
- .col-1-4 {
- width: 25% !important;
- }
-
- .col-1-3 {
- width: 33.33% !important;
- }
-
- .col-2-3 {
- width: 66.66% !important;
- }
-
- .col-5-12 {
- width: 41.67% !important;
- }
-}
-body {
- font-size: 18px;
- line-height: 1.5em;
- font-family: "proxima-nova-soft", "Proxima Nova Soft", sans-serif;
-}
-
-h1, h2, h3, h4, h5, h6, p {
- font-family: "proxima-nova-soft", "Proxima Nova Soft", sans-serif;
- -webkit-font-smoothing: antialiased;
-}
-h1:first-child, h2:first-child, h3:first-child, h4:first-child, h5:first-child, h6:first-child, p:first-child {
- margin-top: 0;
-}
-h1:last-child, h2:last-child, h3:last-child, h4:last-child, h5:last-child, h6:last-child, p:last-child {
- margin-bottom: 0;
-}
-h1 > small, h2 > small, h3 > small, h4 > small, h5 > small, h6 > small, p > small {
- font-size: 0.65em;
- color: #aaa;
-}
-
-h1, h2, h3, h4, h5, h6 {
- font-weight: 600;
- line-height: 1.3em;
- color: #1b3544;
-}
-h1.light, h2.light, h3.light, h4.light, h5.light, h6.light {
- font-weight: 400;
- color: #444;
-}
-
-p {
- line-height: 1.5em;
- color: #444;
-}
-
-a {
- color: #359173;
- text-decoration: none;
- transition: color 0.3s ease-in-out;
-}
-a:hover {
- color: #2A735B;
-}
-
-.center {
- text-align: center;
-}
-
-.right {
- text-align: right;
-}
-
-.caps {
- text-transform: uppercase;
-}
-
-/*-------------------------------------*\
- HINT.css - A CSS tooltip library
-\*-------------------------------------*/
-/**
- * HINT.css is a tooltip library made in pure CSS.
- *
- * Source: https://github.com/chinchang/hint.css
- * Demo: http://kushagragour.in/lab/hint/
- *
- * Release under The MIT License
- *
- */
-/**
- * source: hint-core.scss
- *
- * Defines the basic styling for the tooltip.
- * Each tooltip is made of 2 parts:
- * 1) body (:after)
- * 2) arrow (:before)
- *
- * Classes added:
- * 1) hint
- */
-.hint, [data-hint] {
- position: relative;
- display: inline-block;
- /**
- * tooltip arrow
- */
- /**
- * tooltip body
- */
-}
-.hint:before, .hint:after, [data-hint]:before, [data-hint]:after {
- position: absolute;
- -webkit-transform: translate3d(0, 0, 0);
- -moz-transform: translate3d(0, 0, 0);
- transform: translate3d(0, 0, 0);
- visibility: hidden;
- opacity: 0;
- z-index: 1000000;
- pointer-events: none;
- -webkit-transition: 0.3s ease;
- -moz-transition: 0.3s ease;
- transition: 0.3s ease;
-}
-.hint:hover:before, .hint:hover:after, .hint:focus:before, .hint:focus:after, [data-hint]:hover:before, [data-hint]:hover:after, [data-hint]:focus:before, [data-hint]:focus:after {
- visibility: visible;
- opacity: 1;
-}
-.hint:before, [data-hint]:before {
- content: "";
- position: absolute;
- background: transparent;
- border: 6px solid transparent;
- z-index: 1000001;
-}
-.hint:after, [data-hint]:after {
- font-family: "myriad-pro", sans-serif;
- font-weight: 400;
- content: attr(data-hint);
- background: #1b3544;
- color: white;
- padding: 12px 15px;
- font-size: 16px;
- line-height: 16px;
- white-space: nowrap;
-}
-
-/**
- * source: hint-position.scss
- *
- * Defines the positoning logic for the tooltips.
- *
- * Classes added:
- * 1) hint--top
- * 2) hint--bottom
- * 3) hint--left
- * 4) hint--right
- */
-/**
- * set default color for tooltip arrows
- */
-.hint--top:before {
- border-top-color: #1b3544;
-}
-
-.hint--bottom:before {
- border-bottom-color: #1b3544;
-}
-
-.hint--left:before {
- border-left-color: #1b3544;
-}
-
-.hint--right:before {
- border-right-color: #1b3544;
-}
-
-/**
- * top tooltip
- */
-.hint--top:before {
- margin-bottom: -12px;
-}
-.hint--top:after {
- margin-left: -18px;
-}
-.hint--top:before, .hint--top:after {
- bottom: 100%;
- left: 18px;
-}
-.hint--top:hover:after, .hint--top:hover:before, .hint--top:focus:after, .hint--top:focus:before {
- -webkit-transform: translateY(-8px);
- -moz-transform: translateY(-8px);
- transform: translateY(-8px);
-}
-
-/**
- * bottom tooltip
- */
-.hint--bottom:before {
- margin-top: -12px;
-}
-.hint--bottom:after {
- margin-left: -18px;
-}
-.hint--bottom:before, .hint--bottom:after {
- top: 100%;
- left: 18px;
-}
-.hint--bottom:hover:after, .hint--bottom:hover:before, .hint--bottom:focus:after, .hint--bottom:focus:before {
- -webkit-transform: translateY(8px);
- -moz-transform: translateY(8px);
- transform: translateY(8px);
-}
-
-/**
- * right tooltip
- */
-.hint--right:before {
- margin-left: -12px;
- margin-bottom: -6px;
-}
-.hint--right:after {
- margin-bottom: -20px;
-}
-.hint--right:before, .hint--right:after {
- left: 100%;
- bottom: 50%;
-}
-.hint--right:hover:after, .hint--right:hover:before, .hint--right:focus:after, .hint--right:focus:before {
- -webkit-transform: translateX(8px);
- -moz-transform: translateX(8px);
- transform: translateX(8px);
-}
-
-/**
- * left tooltip
- */
-.hint--left:before {
- margin-right: -12px;
- margin-bottom: -6px;
-}
-.hint--left:after {
- margin-bottom: -20px;
-}
-.hint--left:before, .hint--left:after {
- right: 100%;
- bottom: 50%;
-}
-.hint--left:hover:after, .hint--left:hover:before, .hint--left:focus:after, .hint--left:focus:before {
- -webkit-transform: translateX(-8px);
- -moz-transform: translateX(-8px);
- transform: translateX(-8px);
-}
-
-/**
- * source: hint-color-types.scss
- *
- * Contains tooltips of various types based on color differences.
- *
- * Classes added:
- * 1) hint--error
- * 2) hint--warning
- * 3) hint--info
- * 4) hint--success
- *
- */
-/**
- * Error
- */
-.hint--error:after {
- background-color: #b34e4d;
-}
-.hint--error.hint--top:before {
- border-top-color: #b34e4d;
-}
-.hint--error.hint--bottom:before {
- border-bottom-color: #b34e4d;
-}
-.hint--error.hint--left:before {
- border-left-color: #b34e4d;
-}
-.hint--error.hint--right:before {
- border-right-color: #b34e4d;
-}
-
-/**
- * Warning
- */
-.hint--warning:after {
- background-color: #c09854;
-}
-.hint--warning.hint--top:before {
- border-top-color: #c09854;
-}
-.hint--warning.hint--bottom:before {
- border-bottom-color: #c09854;
-}
-.hint--warning.hint--left:before {
- border-left-color: #c09854;
-}
-.hint--warning.hint--right:before {
- border-right-color: #c09854;
-}
-
-/**
- * Info
- */
-.hint--info:after {
- background-color: #3986ac;
-}
-.hint--info.hint--top:before {
- border-top-color: #3986ac;
-}
-.hint--info.hint--bottom:before {
- border-bottom-color: #3986ac;
-}
-.hint--info.hint--left:before {
- border-left-color: #3986ac;
-}
-.hint--info.hint--right:before {
- border-right-color: #3986ac;
-}
-
-/**
- * Success
- */
-.hint--success:after {
- background-color: #458746;
-}
-.hint--success.hint--top:before {
- border-top-color: #458746;
-}
-.hint--success.hint--bottom:before {
- border-bottom-color: #458746;
-}
-.hint--success.hint--left:before {
- border-left-color: #458746;
-}
-.hint--success.hint--right:before {
- border-right-color: #458746;
-}
-
-/**
- * source: hint-always.scss
- *
- * Defines a persisted tooltip which shows always.
- *
- * Classes added:
- * 1) hint--always
- *
- */
-.hint--always:after, .hint--always:before {
- opacity: 1;
- visibility: visible;
-}
-.hint--always.hint--top:after, .hint--always.hint--top:before {
- -webkit-transform: translateY(-8px);
- -moz-transform: translateY(-8px);
- transform: translateY(-8px);
-}
-.hint--always.hint--bottom:after, .hint--always.hint--bottom:before {
- -webkit-transform: translateY(8px);
- -moz-transform: translateY(8px);
- transform: translateY(8px);
-}
-.hint--always.hint--left:after, .hint--always.hint--left:before {
- -webkit-transform: translateX(-8px);
- -moz-transform: translateX(-8px);
- transform: translateX(-8px);
-}
-.hint--always.hint--right:after, .hint--always.hint--right:before {
- -webkit-transform: translateX(8px);
- -moz-transform: translateX(8px);
- transform: translateX(8px);
-}
-
-/**
- * source: hint-rounded.scss
- *
- * Defines rounded corner tooltips.
- *
- * Classes added:
- * 1) hint--rounded
- *
- */
-.hint--rounded:after {
- border-radius: 4px;
-}
-
-/**
- * source: hint-effects.scss
- *
- * Defines various transition effects for the tooltips.
- *
- * Classes added:
- * 1) hint--bounce
- *
- */
-.hint--bounce:before, .hint--bounce:after {
- -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);
- -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);
- transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);
-}
-
-.alert-box {
- padding: 15px;
- font-size: 1em;
- line-height: 1.5em;
- display: block;
- border: 2px solid #359173;
- background-color: transparent;
- color: #359173;
-}
-.alert-box.error {
- border-color: #D9534F;
- background-color: transparent;
- color: #D9534F;
-}
-.alert-box.success {
- border-color: #359173;
- background-color: transparent;
- color: #359173;
-}
-.alert-box.banner {
- text-align: center;
- margin-bottom: 0;
-}
-@media (max-width: 760px) {
- .alert-box.banner {
- position: absolute;
- left: 0;
- width: 100%;
- border: 0;
- border-bottom: 2px solid #359173;
- }
-}
-.alert-box.banner a {
- opacity: 0.75;
- text-decoration: underline;
-}
-
-a.alert-box:hover {
- color: #1b3544;
- border-color: #f1f1fa;
-}
-
-a.alert-box.error:hover {
- color: #D9534F;
- border-color: #D9534F;
-}
-
-a.alert-box.success:hover {
- color: #359173;
- border-color: #359173;
-}
-
-.highlight {
- padding: 2px 6px;
- font-weight: bold;
- font-size: 20px;
- color: white;
- background-color: #35918D;
- border-radius: 3px;
- margin: 3px;
-}
-
-.login .row {
- padding: 2.2em 0;
-}
-.login input, .login button {
- font-size: 1.2em;
- margin: 2px 0 1em 0;
-}
-
-.no-underline {
- border-bottom: none !important;
-}
-
-.no-border {
- border: none !important;
- padding: 0 !important;
- margin: 0 !important;
-}
-
-.invoice {
- font-size: 9pt;
- line-height: 1.2em;
-}
-.invoice .middle > * {
- vertical-align: middle;
-}
-.invoice strong {
- color: #1b3544;
-}
-.invoice img {
- display: inline;
- height: 50px;
- margin-right: 10px;
-}
-.invoice h1 {
- display: inline;
-}
-.invoice .row {
- padding-top: 40px;
-}
-.invoice .row p {
- -webkit-margin-before: 0;
-}
-.invoice h3 {
- margin-bottom: 0;
-}
-.invoice #invoice-table h3 {
- margin-bottom: 10px;
-}
-.invoice #invoice-table table, .invoice #invoice-table tbody td {
- border: 0.25px solid #DFDFDF;
-}
-.invoice #invoice-table thead {
- background-color: #359173;
- color: white;
- text-align: center;
- border-color: #000000;
-}
-.invoice #invoice-table tbody {
- vertical-align: top;
-}
-.invoice #invoice-table th, .invoice #invoice-table td {
- padding: 10px;
-}
-.invoice .invoice-unpaid:after {
- content: "UNPAID";
- position: absolute;
- top: 120px;
- right: 15%;
- z-index: 1;
- font-family: "Special Elite", Arial, sans-serif;
- transform: rotate(-45deg);
- font-size: 40px;
- color: #c00;
- border: solid 4px #c00;
- padding: 15px 5px 5px;
- border-radius: 5px;
- opacity: 0.7;
- text-shadow: 0 0 2px #c00;
- box-shadow: 0 0 2px #c00;
-}
-
-.dashboard {
- /* icon morphing */
-}
-.dashboard .row:after {
- content: "";
- display: none;
-}
-.dashboard .card {
- border-width: 0;
-}
-.dashboard span[class^=ion-] {
- display: inline-block;
- font-size: 20px;
- text-align: center;
- width: 32px;
-}
-.dashboard .delete {
- color: #D9534F;
- border-color: #D9534F;
-}
-.dashboard .delete:hover {
- transition: color 0.3s ease-in-out;
- color: #D87431;
-}
-.dashboard div.submissions-col {
- overflow-x: auto;
-}
-.dashboard table {
- text-align: left;
- width: 100%;
-}
-@media screen and (max-width: 600px) {
- .dashboard table.responsive {
- border: 0;
- }
- .dashboard table.responsive thead {
- display: none;
- }
- .dashboard table.responsive tr {
- margin-bottom: 10px;
- display: block;
- border-bottom: 5px solid #ddd;
- }
- .dashboard table.responsive tr td {
- display: block;
- font-size: 13px;
- border-bottom: 1px dotted #ccc;
- margin: 10px auto;
- max-width: 100%;
- }
- .dashboard table.responsive tr td:last-child {
- border-bottom: 0;
- }
- .dashboard table.responsive tr td:before {
- content: attr(data-label);
- display: block;
- text-transform: uppercase;
- font-weight: bold;
- }
-}
-.dashboard table.submissions {
- padding: 2px;
- background: #fff;
-}
-.dashboard table.submissions th {
- padding: 7px 0;
-}
-.dashboard table.submissions tr:first-child td {
- padding-top: 10px;
-}
-.dashboard table.submissions td {
- padding: 3px 1px;
-}
-.dashboard table.submissions pre {
- font-family: inherit;
- margin: 0;
- max-width: 300px;
-}
-.dashboard table.submissions tr pre.full {
- display: none;
-}
-.dashboard table.submissions tr:target pre {
- display: none;
-}
-.dashboard table.submissions tr:target pre + pre.full {
- display: block;
-}
-.dashboard table.forms td.target-email, .dashboard table.emails td.target-email {
- max-width: 250px;
- word-break: break-word;
-}
-.dashboard table.forms td.n-submissions, .dashboard table.emails td.n-submissions {
- min-width: 150px;
-}
-.dashboard table.forms tr.new span[class^=ion-], .dashboard table.emails tr.new span[class^=ion-] {
- color: #D9534F;
-}
-.dashboard table.forms tr.waiting_confirmation span[class^=ion-], .dashboard table.emails tr.waiting_confirmation span[class^=ion-] {
- color: #D87431;
-}
-.dashboard table.forms tr.verified span[class^=ion-], .dashboard table.emails tr.verified span[class^=ion-] {
- color: #2A735B;
-}
-.dashboard table.forms tr.new a:not(*:hover), .dashboard table.emails tr.new a:not(*:hover) {
- border-bottom: 1px dotted;
- margin-bottom: -1px;
- line-height: 1em;
-}
-.dashboard table.forms tr.new .never, .dashboard table.emails tr.new .never {
- font-size: 15px;
-}
-.dashboard table.forms tr:not(.new) *:not(.n-submissions) a:not(*:hover), .dashboard table.emails tr:not(.new) *:not(.n-submissions) a:not(*:hover) {
- color: inherit;
-}
-.dashboard table.emails tr:nth-child(2) td {
- padding-top: 10px;
-}
-.dashboard table.emails td:last-child {
- text-align: center;
-}
-.dashboard .pad-top {
- padding-top: 0.9em;
-}
-.dashboard #card-list {
- border-collapse: collapse;
-}
-.dashboard #card-list tr {
- border: solid 2px #359173;
- border-radius: 3px;
-}
-.dashboard #card-list td {
- background: #FFF;
- color: #000;
- padding: 7px 15px;
-}
-.dashboard .fa-chevron-right {
- transition: transform 0.25s ease-in-out;
-}
-.dashboard #card-list tr.even td {
- cursor: pointer;
-}
-.dashboard .create-form {
- margin: 3em 0;
-}
-.dashboard .create-form form {
- clear: both;
-}
-.dashboard .create-form form input:not([type=checkbox]):not([type=radio]) {
- margin-top: 0;
- clear: both;
- width: 100%;
- vertical-align: top;
-}
-.dashboard .create-form form button {
- padding: 0.63em 32px;
- text-align: center;
-}
-.dashboard .create-form .info {
- font-size: 13px;
- margin-bottom: 10px;
- text-align: right;
-}
-.dashboard .create-form .modal:not(.js):target > *,
-.dashboard .create-form .modal.target > * {
- top: 20%;
-}
-.dashboard .modal[id^=form-] textarea {
- font-size: 15px;
-}
-.dashboard .modal > * {
- background: #fefefe;
- border: #333333 solid 1px;
- border-radius: 5px;
- margin-left: -385px;
- position: fixed;
- left: 50%;
- top: -100%;
- z-index: 11;
- width: 770px;
- -webkit-transform: translate(0, -500%);
- -ms-transform: translate(0, -500%);
- transform: translate(0, -500%);
- -webkit-transition: -webkit-transform 0.3s ease-out;
- -moz-transition: -moz-transform 0.3s ease-out;
- -o-transition: -o-transform 0.3s ease-out;
- transition: transform 0.3s ease-out;
- padding: 0.3em 1.3em 1.3em 1.3em;
-}
-.dashboard .modal > * .x a {
- float: right;
- padding: 10px;
- font-size: 1.7em;
-}
-.dashboard .modal > * h4 {
- margin: 0;
- padding: 0;
- margin-top: 13px;
- float: left;
-}
-.dashboard .modal.narrow > * {
- width: 500px;
- margin-left: -290px;
-}
-.dashboard .modal .small {
- font-size: 0.75em;
-}
-.dashboard .modal .identified {
- background-size: 12% auto;
- background-repeat: no-repeat;
- background-position: right 10% center;
- transition: none;
- background-image: url("/static/img/cards/card.png");
-}
-.dashboard .modal .identified.visa {
- background-image: url("/static/img/cards/visa.png");
-}
-.dashboard .modal .identified.mastercard {
- background-image: url("/static/img/cards/mastercard.png");
-}
-.dashboard .modal .identified.amex {
- background-image: url("/static/img/cards/amex.png");
-}
-.dashboard .modal .identified.dinersclub {
- background-image: url("/static/img/cards/dinersclub.png");
-}
-.dashboard .modal .identified.discover {
- background-image: url("/static/img/cards/discover.png");
-}
-.dashboard .modal .identified.jcb {
- background-image: url("/static/img/cards/jcb.png");
-}
-.dashboard .modal .identified.visaelectron {
- background-image: url("/static/img/cards/visaelectron.png");
-}
-.dashboard .modal .identified.maestro {
- background-image: url("/static/img/cards/maestro.png");
-}
-.dashboard .modal .card {
- font-size: 1em;
- text-transform: uppercase;
- font-weight: 600;
- border: 2px solid #359173;
- color: #359173;
- background: transparent;
- line-height: 1em;
- padding: 0.6em 0.9em;
- transition: all 0.3s ease-in-out;
-}
-.dashboard .modal .card:hover {
- border-color: #2A735B;
- color: #2A735B;
-}
-.dashboard .modal:not(.js):target > *, .dashboard .modal.target > * {
- -webkit-transform: translate(0, 0);
- -ms-transform: translate(0, 0);
- transform: translate(0, 0);
- top: 10%;
-}
-.dashboard .modal:before {
- content: "";
- display: none;
- background: rgba(0, 0, 0, 0.6);
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 10;
-}
-.dashboard .modal:not(.js):target:before, .dashboard .modal.target:before {
- display: block;
-}
-.dashboard .modal .red {
- color: #D9534F;
-}
-.dashboard .fa-unlock:hover::before {
- content: "";
-}
-.dashboard .fa-lock:hover::before {
- content: "";
-}
-
-.html-highlight {
- clear: both;
- font-size: 14px;
- font-family: monospace;
- padding: 5px;
- border: 2px dashed #696969;
- border-radius: 5px;
-}
-.html-highlight .bracket {
- color: #a65700;
-}
-.html-highlight .tagname {
- color: #800000;
- font-weight: bold;
-}
-.html-highlight .attrkey {
- color: #074726;
-}
-.html-highlight .equal {
- color: #808030;
-}
-.html-highlight .attrvalue {
- color: #0000e6;
-}
-.html-highlight .comment {
- color: #696969;
-}
-
-a.button.export {
- width: 11em;
- text-align: center;
- display: inline-block;
- margin: 0 0 20px 20px;
-}
-
-.slicknav_btn {
- position: relative;
- display: block;
- vertical-align: middle;
- float: right;
- padding: 0.438em 0.625em 0.438em 0.625em;
- line-height: 1.125em;
- cursor: pointer;
-}
-.slicknav_btn .slicknav_icon-bar + .slicknav_icon-bar {
- margin-top: 0.188em;
-}
-
-.slicknav_menu {
- *zoom: 1;
-}
-.slicknav_menu .slicknav_menutxt {
- display: block;
- line-height: 1.188em;
- float: left;
-}
-.slicknav_menu .slicknav_icon {
- float: left;
- margin: 0.188em 0 0 0.438em;
-}
-.slicknav_menu .slicknav_no-text {
- margin: 0;
-}
-.slicknav_menu .slicknav_icon-bar {
- display: block;
- width: 1.125em;
- height: 0.125em;
- -webkit-border-radius: 1px;
- -moz-border-radius: 1px;
- border-radius: 1px;
- -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
- -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
- box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
-}
-.slicknav_menu:before {
- content: " ";
- display: table;
-}
-.slicknav_menu:after {
- content: " ";
- display: table;
- clear: both;
-}
-
-.slicknav_nav {
- clear: both;
-}
-.slicknav_nav ul {
- display: block;
-}
-.slicknav_nav li {
- display: block;
-}
-.slicknav_nav .slicknav_arrow {
- font-size: 0.8em;
- margin: 0 0 0 0.4em;
-}
-.slicknav_nav .slicknav_item {
- cursor: pointer;
-}
-.slicknav_nav .slicknav_item a {
- display: inline;
-}
-.slicknav_nav .slicknav_row {
- display: block;
-}
-.slicknav_nav a {
- display: block;
-}
-.slicknav_nav .slicknav_parent-link a {
- display: inline;
-}
-
-.slicknav_brand {
- float: left;
-}
-
-.slicknav_menu {
- font-size: 16px;
- box-sizing: border-box;
- background: #4c4c4c;
- padding: 5px;
-}
-.slicknav_menu * {
- box-sizing: border-box;
-}
-.slicknav_menu .slicknav_menutxt {
- color: #fff;
- font-weight: bold;
- text-shadow: 0 1px 3px #000;
-}
-.slicknav_menu .slicknav_icon-bar {
- background-color: #fff;
-}
-
-.slicknav_btn {
- margin: 5px 5px 6px;
- text-decoration: none;
- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- background-color: #222;
-}
-
-.slicknav_nav {
- color: #fff;
- margin: 0;
- padding: 0;
- font-size: 0.875em;
- list-style: none;
- overflow: hidden;
-}
-.slicknav_nav ul {
- list-style: none;
- overflow: hidden;
- padding: 0;
- margin: 0 0 0 20px;
-}
-.slicknav_nav .slicknav_row {
- padding: 5px 10px;
- margin: 2px 5px;
-}
-.slicknav_nav .slicknav_row:hover {
- -webkit-border-radius: 6px;
- -moz-border-radius: 6px;
- border-radius: 6px;
- background: #ccc;
- color: #fff;
-}
-.slicknav_nav a {
- padding: 5px 10px;
- margin: 2px 5px;
- text-decoration: none;
- color: #fff;
-}
-.slicknav_nav a:hover {
- -webkit-border-radius: 6px;
- -moz-border-radius: 6px;
- border-radius: 6px;
- background: #ccc;
- color: #222;
-}
-.slicknav_nav .slicknav_txtnode {
- margin-left: 15px;
-}
-.slicknav_nav .slicknav_item a {
- padding: 0;
- margin: 0;
-}
-.slicknav_nav .slicknav_parent-link a {
- padding: 0;
- margin: 0;
-}
-
-.slicknav_brand {
- color: #fff;
- font-size: 18px;
- line-height: 30px;
- padding: 7px 12px;
- height: 44px;
-}
-
-.slicknav_menu {
- display: none;
-}
-
-body > nav {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- background: inherit;
- z-index: 9;
- padding: 7px 10px;
- height: 41px;
-}
-body > nav + * {
- margin-top: 41px;
-}
-body > nav.scrolled {
- box-shadow: 0 0 0.6em rgba(17, 17, 17, 0.3);
-}
-body > nav > .greetings {
- float: left;
-}
-body > nav > .menu {
- float: right;
-}
-body > nav .item {
- margin-left: 0.5em;
-}
-
-@media screen and (max-width: 40em) {
- body > nav.js {
- display: none;
- }
-
- .slicknav_menu {
- display: block;
- }
-}
-.slicknav_menu {
- background: #4CD1A7;
- /* our transcluded menu header ("Welcome...") */
-}
-.slicknav_menu a {
- color: white;
-}
-.slicknav_menu > a {
- float: right;
-}
-.slicknav_menu h4 {
- padding: 0;
- margin: 0;
- line-height: 33px;
- margin-top: 5px;
- float: left;
-}
-.slicknav_menu .slicknav_btn {
- background-color: #2A735B;
-}
-.slicknav_menu .slicknav_menutxt {
- text-shadow: 0 1px 3px #2A735B;
-}
-
-.toast-title {
- font-weight: bold;
-}
-
-.toast-message {
- -ms-word-wrap: break-word;
- word-wrap: break-word;
-}
-
-.toast-message a,
-.toast-message label {
- color: #ffffff;
-}
-
-.toast-message a:hover {
- color: #cccccc;
- text-decoration: none;
-}
-
-.toast-close-button {
- position: relative;
- right: -0.3em;
- top: -0.3em;
- float: right;
- font-size: 20px;
- font-weight: bold;
- color: #ffffff;
- -webkit-text-shadow: 0 1px 0 #ffffff;
- text-shadow: 0 1px 0 #ffffff;
- opacity: 0.8;
- -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
- filter: alpha(opacity=80);
-}
-
-.toast-close-button:hover,
-.toast-close-button:focus {
- color: #000000;
- text-decoration: none;
- cursor: pointer;
- opacity: 0.4;
- -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
- filter: alpha(opacity=40);
-}
-
-/*Additional properties for button version
- iOS requires the button element instead of an anchor tag.
- If you want the anchor version, it requires `href="#"`.*/
-button.toast-close-button {
- padding: 0;
- cursor: pointer;
- background: transparent;
- border: 0;
- -webkit-appearance: none;
-}
-
-.toast-top-center {
- top: 0;
- right: 0;
- width: 100%;
-}
-
-.toast-bottom-center {
- bottom: 0;
- right: 0;
- width: 100%;
-}
-
-.toast-top-full-width {
- top: 0;
- right: 0;
- width: 100%;
-}
-
-.toast-bottom-full-width {
- bottom: 0;
- right: 0;
- width: 100%;
-}
-
-.toast-top-left {
- top: 12px;
- left: 12px;
-}
-
-.toast-top-right {
- top: 12px;
- right: 12px;
-}
-
-.toast-bottom-right {
- right: 12px;
- bottom: 12px;
-}
-
-.toast-bottom-left {
- bottom: 12px;
- left: 12px;
-}
-
-#toast-container {
- position: fixed;
- z-index: 999999;
- /*overrides*/
-}
-
-#toast-container * {
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
-}
-
-#toast-container > div {
- position: relative;
- overflow: hidden;
- margin: 0 0 6px;
- padding: 15px 15px 15px 50px;
- width: 300px;
- -moz-border-radius: 3px 3px 3px 3px;
- -webkit-border-radius: 3px 3px 3px 3px;
- border-radius: 3px 3px 3px 3px;
- background-position: 15px center;
- background-repeat: no-repeat;
- -moz-box-shadow: 0 0 12px #999999;
- -webkit-box-shadow: 0 0 12px #999999;
- box-shadow: 0 0 12px #999999;
- color: #ffffff;
- opacity: 0.8;
- -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
- filter: alpha(opacity=80);
-}
-
-#toast-container > :hover {
- -moz-box-shadow: 0 0 12px #000000;
- -webkit-box-shadow: 0 0 12px #000000;
- box-shadow: 0 0 12px #000000;
- opacity: 1;
- -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
- filter: alpha(opacity=100);
- cursor: pointer;
-}
-
-#toast-container > .toast-info {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=") !important;
-}
-
-#toast-container > .toast-error {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=") !important;
-}
-
-#toast-container > .toast-success {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==") !important;
-}
-
-#toast-container > .toast-warning {
- background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=") !important;
-}
-
-#toast-container.toast-top-center > div,
-#toast-container.toast-bottom-center > div {
- width: 300px;
- margin: auto;
-}
-
-#toast-container.toast-top-full-width > div,
-#toast-container.toast-bottom-full-width > div {
- width: 96%;
- margin: auto;
-}
-
-.toast {
- background-color: #030303;
-}
-
-.toast-success {
- background-color: #359173;
-}
-
-.toast-error {
- background-color: #CC3F36;
-}
-
-.toast-info {
- background-color: #4ca1a7;
-}
-
-.toast-warning {
- background-color: #D87431;
-}
-
-.toast-progress {
- position: absolute;
- left: 0;
- bottom: 0;
- height: 4px;
- background-color: #000000;
- opacity: 0.4;
- -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);
- filter: alpha(opacity=40);
-}
-
-/*Responsive Design*/
-@media all and (max-width: 240px) {
- #toast-container > div {
- padding: 8px 8px 8px 50px;
- width: 11em;
- }
-
- #toast-container .toast-close-button {
- right: -0.2em;
- top: -0.2em;
- }
-}
-@media all and (min-width: 241px) and (max-width: 480px) {
- #toast-container > div {
- padding: 8px 8px 8px 50px;
- width: 18em;
- }
-
- #toast-container .toast-close-button {
- right: -0.2em;
- top: -0.2em;
- }
-}
-@media all and (min-width: 481px) and (max-width: 768px) {
- #toast-container > div {
- padding: 15px 15px 15px 50px;
- width: 25em;
- }
-}
-.dropdown {
- position: relative;
- display: inline-block;
- cursor: pointer;
-}
-
-.dropdown-content {
- display: none;
- position: absolute;
- background-color: #f1f1f1;
- min-width: 160px;
- overflow: auto;
- box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
- z-index: 1;
-}
-
-.dropdown-content a {
- color: black;
- padding: 12px 16px;
- text-decoration: none;
- display: block;
-}
-
-.show {
- display: block;
-}
-
-#settings-button {
- display: block;
-}
-
-.modal .float-left {
- float: left;
-}
-.modal p#status {
- float: right;
- color: #1b3544;
- font-size: 0.7em;
- margin-right: 2%;
-}
-.modal p#status.error {
- color: #D9534F;
-}
-.modal h4.large {
- font-size: 1.2em;
-}
-.modal p.description {
- line-height: 1em;
- display: inline-block;
- font-size: 0.8em;
- margin: 0;
- margin-top: 0.2em;
- color: #999999;
-}
-.modal .col-1-6.switch-row {
- margin: auto;
-}
-.modal .switch {
- position: absolute;
- display: inline-block;
- width: 60px;
- height: 26px;
- right: 5%;
-}
-.modal .switch input {
- display: none;
-}
-.modal .slider {
- position: absolute;
- cursor: pointer;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background-color: #ccc;
- -webkit-transition: 0.4s;
- transition: 0.4s;
-}
-.modal .slider:before {
- position: absolute;
- content: "";
- height: 18px;
- width: 26px;
- left: 4px;
- bottom: 4px;
- background-color: white;
- -webkit-transition: 0.4s;
- transition: 0.4s;
-}
-.modal input:checked + .slider {
- background-color: #2A735B;
-}
-.modal input:focus + .slider {
- box-shadow: 0 0 1px #2A735B;
-}
-.modal input:checked + .slider:before {
- -webkit-transform: translateX(26px);
- -ms-transform: translateX(26px);
- transform: translateX(26px);
-}
-.modal .row {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -ms-flex-wrap: wrap;
- flex-wrap: wrap;
- margin-right: -15px;
- margin-left: -15px;
-}
-
-/*!
- Ionicons, v2.0.1
- Created by Ben Sperry for the Ionic Framework, http://ionicons.com/
- https://twitter.com/benjsperry https://twitter.com/ionicframework
- MIT License: https://github.com/driftyco/ionicons
-
- Android-style icons originally built by Google’s
- Material Design Icons: https://github.com/google/material-design-icons
- used under CC BY http://creativecommons.org/licenses/by/4.0/
- Modified icons to fit ionicon’s grid from original.
-*/
-@font-face {
- font-family: "Ionicons";
- src: url("../fonts/ionicons.eot?v=2.0.1");
- src: url("../fonts/ionicons.eot?v=2.0.1#iefix") format("embedded-opentype"), url("../fonts/ionicons.ttf?v=2.0.1") format("truetype"), url("../fonts/ionicons.woff?v=2.0.1") format("woff"), url("../fonts/ionicons.svg?v=2.0.1#Ionicons") format("svg");
- font-weight: normal;
- font-style: normal;
-}
-.ion, .ionicons,
-.ion-alert:before,
-.ion-alert-circled:before,
-.ion-android-add:before,
-.ion-android-add-circle:before,
-.ion-android-alarm-clock:before,
-.ion-android-alert:before,
-.ion-android-apps:before,
-.ion-android-archive:before,
-.ion-android-arrow-back:before,
-.ion-android-arrow-down:before,
-.ion-android-arrow-dropdown:before,
-.ion-android-arrow-dropdown-circle:before,
-.ion-android-arrow-dropleft:before,
-.ion-android-arrow-dropleft-circle:before,
-.ion-android-arrow-dropright:before,
-.ion-android-arrow-dropright-circle:before,
-.ion-android-arrow-dropup:before,
-.ion-android-arrow-dropup-circle:before,
-.ion-android-arrow-forward:before,
-.ion-android-arrow-up:before,
-.ion-android-attach:before,
-.ion-android-bar:before,
-.ion-android-bicycle:before,
-.ion-android-boat:before,
-.ion-android-bookmark:before,
-.ion-android-bulb:before,
-.ion-android-bus:before,
-.ion-android-calendar:before,
-.ion-android-call:before,
-.ion-android-camera:before,
-.ion-android-cancel:before,
-.ion-android-car:before,
-.ion-android-cart:before,
-.ion-android-chat:before,
-.ion-android-checkbox:before,
-.ion-android-checkbox-blank:before,
-.ion-android-checkbox-outline:before,
-.ion-android-checkbox-outline-blank:before,
-.ion-android-checkmark-circle:before,
-.ion-android-clipboard:before,
-.ion-android-close:before,
-.ion-android-cloud:before,
-.ion-android-cloud-circle:before,
-.ion-android-cloud-done:before,
-.ion-android-cloud-outline:before,
-.ion-android-color-palette:before,
-.ion-android-compass:before,
-.ion-android-contact:before,
-.ion-android-contacts:before,
-.ion-android-contract:before,
-.ion-android-create:before,
-.ion-android-delete:before,
-.ion-android-desktop:before,
-.ion-android-document:before,
-.ion-android-done:before,
-.ion-android-done-all:before,
-.ion-android-download:before,
-.ion-android-drafts:before,
-.ion-android-exit:before,
-.ion-android-expand:before,
-.ion-android-favorite:before,
-.ion-android-favorite-outline:before,
-.ion-android-film:before,
-.ion-android-folder:before,
-.ion-android-folder-open:before,
-.ion-android-funnel:before,
-.ion-android-globe:before,
-.ion-android-hand:before,
-.ion-android-hangout:before,
-.ion-android-happy:before,
-.ion-android-home:before,
-.ion-android-image:before,
-.ion-android-laptop:before,
-.ion-android-list:before,
-.ion-android-locate:before,
-.ion-android-lock:before,
-.ion-android-mail:before,
-.ion-android-map:before,
-.ion-android-menu:before,
-.ion-android-microphone:before,
-.ion-android-microphone-off:before,
-.ion-android-more-horizontal:before,
-.ion-android-more-vertical:before,
-.ion-android-navigate:before,
-.ion-android-notifications:before,
-.ion-android-notifications-none:before,
-.ion-android-notifications-off:before,
-.ion-android-open:before,
-.ion-android-options:before,
-.ion-android-people:before,
-.ion-android-person:before,
-.ion-android-person-add:before,
-.ion-android-phone-landscape:before,
-.ion-android-phone-portrait:before,
-.ion-android-pin:before,
-.ion-android-plane:before,
-.ion-android-playstore:before,
-.ion-android-print:before,
-.ion-android-radio-button-off:before,
-.ion-android-radio-button-on:before,
-.ion-android-refresh:before,
-.ion-android-remove:before,
-.ion-android-remove-circle:before,
-.ion-android-restaurant:before,
-.ion-android-sad:before,
-.ion-android-search:before,
-.ion-android-send:before,
-.ion-android-settings:before,
-.ion-android-share:before,
-.ion-android-share-alt:before,
-.ion-android-star:before,
-.ion-android-star-half:before,
-.ion-android-star-outline:before,
-.ion-android-stopwatch:before,
-.ion-android-subway:before,
-.ion-android-sunny:before,
-.ion-android-sync:before,
-.ion-android-textsms:before,
-.ion-android-time:before,
-.ion-android-train:before,
-.ion-android-unlock:before,
-.ion-android-upload:before,
-.ion-android-volume-down:before,
-.ion-android-volume-mute:before,
-.ion-android-volume-off:before,
-.ion-android-volume-up:before,
-.ion-android-walk:before,
-.ion-android-warning:before,
-.ion-android-watch:before,
-.ion-android-wifi:before,
-.ion-aperture:before,
-.ion-archive:before,
-.ion-arrow-down-a:before,
-.ion-arrow-down-b:before,
-.ion-arrow-down-c:before,
-.ion-arrow-expand:before,
-.ion-arrow-graph-down-left:before,
-.ion-arrow-graph-down-right:before,
-.ion-arrow-graph-up-left:before,
-.ion-arrow-graph-up-right:before,
-.ion-arrow-left-a:before,
-.ion-arrow-left-b:before,
-.ion-arrow-left-c:before,
-.ion-arrow-move:before,
-.ion-arrow-resize:before,
-.ion-arrow-return-left:before,
-.ion-arrow-return-right:before,
-.ion-arrow-right-a:before,
-.ion-arrow-right-b:before,
-.ion-arrow-right-c:before,
-.ion-arrow-shrink:before,
-.ion-arrow-swap:before,
-.ion-arrow-up-a:before,
-.ion-arrow-up-b:before,
-.ion-arrow-up-c:before,
-.ion-asterisk:before,
-.ion-at:before,
-.ion-backspace:before,
-.ion-backspace-outline:before,
-.ion-bag:before,
-.ion-battery-charging:before,
-.ion-battery-empty:before,
-.ion-battery-full:before,
-.ion-battery-half:before,
-.ion-battery-low:before,
-.ion-beaker:before,
-.ion-beer:before,
-.ion-bluetooth:before,
-.ion-bonfire:before,
-.ion-bookmark:before,
-.ion-bowtie:before,
-.ion-briefcase:before,
-.ion-bug:before,
-.ion-calculator:before,
-.ion-calendar:before,
-.ion-camera:before,
-.ion-card:before,
-.ion-cash:before,
-.ion-chatbox:before,
-.ion-chatbox-working:before,
-.ion-chatboxes:before,
-.ion-chatbubble:before,
-.ion-chatbubble-working:before,
-.ion-chatbubbles:before,
-.ion-checkmark:before,
-.ion-checkmark-circled:before,
-.ion-checkmark-round:before,
-.ion-chevron-down:before,
-.ion-chevron-left:before,
-.ion-chevron-right:before,
-.ion-chevron-up:before,
-.ion-clipboard:before,
-.ion-clock:before,
-.ion-close:before,
-.ion-close-circled:before,
-.ion-close-round:before,
-.ion-closed-captioning:before,
-.ion-cloud:before,
-.ion-code:before,
-.ion-code-download:before,
-.ion-code-working:before,
-.ion-coffee:before,
-.ion-compass:before,
-.ion-compose:before,
-.ion-connection-bars:before,
-.ion-contrast:before,
-.ion-crop:before,
-.ion-cube:before,
-.ion-disc:before,
-.ion-document:before,
-.ion-document-text:before,
-.ion-drag:before,
-.ion-earth:before,
-.ion-easel:before,
-.ion-edit:before,
-.ion-egg:before,
-.ion-eject:before,
-.ion-email:before,
-.ion-email-unread:before,
-.ion-erlenmeyer-flask:before,
-.ion-erlenmeyer-flask-bubbles:before,
-.ion-eye:before,
-.ion-eye-disabled:before,
-.ion-female:before,
-.ion-filing:before,
-.ion-film-marker:before,
-.ion-fireball:before,
-.ion-flag:before,
-.ion-flame:before,
-.ion-flash:before,
-.ion-flash-off:before,
-.ion-folder:before,
-.ion-fork:before,
-.ion-fork-repo:before,
-.ion-forward:before,
-.ion-funnel:before,
-.ion-gear-a:before,
-.ion-gear-b:before,
-.ion-grid:before,
-.ion-hammer:before,
-.ion-happy:before,
-.ion-happy-outline:before,
-.ion-headphone:before,
-.ion-heart:before,
-.ion-heart-broken:before,
-.ion-help:before,
-.ion-help-buoy:before,
-.ion-help-circled:before,
-.ion-home:before,
-.ion-icecream:before,
-.ion-image:before,
-.ion-images:before,
-.ion-information:before,
-.ion-information-circled:before,
-.ion-ionic:before,
-.ion-ios-alarm:before,
-.ion-ios-alarm-outline:before,
-.ion-ios-albums:before,
-.ion-ios-albums-outline:before,
-.ion-ios-americanfootball:before,
-.ion-ios-americanfootball-outline:before,
-.ion-ios-analytics:before,
-.ion-ios-analytics-outline:before,
-.ion-ios-arrow-back:before,
-.ion-ios-arrow-down:before,
-.ion-ios-arrow-forward:before,
-.ion-ios-arrow-left:before,
-.ion-ios-arrow-right:before,
-.ion-ios-arrow-thin-down:before,
-.ion-ios-arrow-thin-left:before,
-.ion-ios-arrow-thin-right:before,
-.ion-ios-arrow-thin-up:before,
-.ion-ios-arrow-up:before,
-.ion-ios-at:before,
-.ion-ios-at-outline:before,
-.ion-ios-barcode:before,
-.ion-ios-barcode-outline:before,
-.ion-ios-baseball:before,
-.ion-ios-baseball-outline:before,
-.ion-ios-basketball:before,
-.ion-ios-basketball-outline:before,
-.ion-ios-bell:before,
-.ion-ios-bell-outline:before,
-.ion-ios-body:before,
-.ion-ios-body-outline:before,
-.ion-ios-bolt:before,
-.ion-ios-bolt-outline:before,
-.ion-ios-book:before,
-.ion-ios-book-outline:before,
-.ion-ios-bookmarks:before,
-.ion-ios-bookmarks-outline:before,
-.ion-ios-box:before,
-.ion-ios-box-outline:before,
-.ion-ios-briefcase:before,
-.ion-ios-briefcase-outline:before,
-.ion-ios-browsers:before,
-.ion-ios-browsers-outline:before,
-.ion-ios-calculator:before,
-.ion-ios-calculator-outline:before,
-.ion-ios-calendar:before,
-.ion-ios-calendar-outline:before,
-.ion-ios-camera:before,
-.ion-ios-camera-outline:before,
-.ion-ios-cart:before,
-.ion-ios-cart-outline:before,
-.ion-ios-chatboxes:before,
-.ion-ios-chatboxes-outline:before,
-.ion-ios-chatbubble:before,
-.ion-ios-chatbubble-outline:before,
-.ion-ios-checkmark:before,
-.ion-ios-checkmark-empty:before,
-.ion-ios-checkmark-outline:before,
-.ion-ios-circle-filled:before,
-.ion-ios-circle-outline:before,
-.ion-ios-clock:before,
-.ion-ios-clock-outline:before,
-.ion-ios-close:before,
-.ion-ios-close-empty:before,
-.ion-ios-close-outline:before,
-.ion-ios-cloud:before,
-.ion-ios-cloud-download:before,
-.ion-ios-cloud-download-outline:before,
-.ion-ios-cloud-outline:before,
-.ion-ios-cloud-upload:before,
-.ion-ios-cloud-upload-outline:before,
-.ion-ios-cloudy:before,
-.ion-ios-cloudy-night:before,
-.ion-ios-cloudy-night-outline:before,
-.ion-ios-cloudy-outline:before,
-.ion-ios-cog:before,
-.ion-ios-cog-outline:before,
-.ion-ios-color-filter:before,
-.ion-ios-color-filter-outline:before,
-.ion-ios-color-wand:before,
-.ion-ios-color-wand-outline:before,
-.ion-ios-compose:before,
-.ion-ios-compose-outline:before,
-.ion-ios-contact:before,
-.ion-ios-contact-outline:before,
-.ion-ios-copy:before,
-.ion-ios-copy-outline:before,
-.ion-ios-crop:before,
-.ion-ios-crop-strong:before,
-.ion-ios-download:before,
-.ion-ios-download-outline:before,
-.ion-ios-drag:before,
-.ion-ios-email:before,
-.ion-ios-email-outline:before,
-.ion-ios-eye:before,
-.ion-ios-eye-outline:before,
-.ion-ios-fastforward:before,
-.ion-ios-fastforward-outline:before,
-.ion-ios-filing:before,
-.ion-ios-filing-outline:before,
-.ion-ios-film:before,
-.ion-ios-film-outline:before,
-.ion-ios-flag:before,
-.ion-ios-flag-outline:before,
-.ion-ios-flame:before,
-.ion-ios-flame-outline:before,
-.ion-ios-flask:before,
-.ion-ios-flask-outline:before,
-.ion-ios-flower:before,
-.ion-ios-flower-outline:before,
-.ion-ios-folder:before,
-.ion-ios-folder-outline:before,
-.ion-ios-football:before,
-.ion-ios-football-outline:before,
-.ion-ios-game-controller-a:before,
-.ion-ios-game-controller-a-outline:before,
-.ion-ios-game-controller-b:before,
-.ion-ios-game-controller-b-outline:before,
-.ion-ios-gear:before,
-.ion-ios-gear-outline:before,
-.ion-ios-glasses:before,
-.ion-ios-glasses-outline:before,
-.ion-ios-grid-view:before,
-.ion-ios-grid-view-outline:before,
-.ion-ios-heart:before,
-.ion-ios-heart-outline:before,
-.ion-ios-help:before,
-.ion-ios-help-empty:before,
-.ion-ios-help-outline:before,
-.ion-ios-home:before,
-.ion-ios-home-outline:before,
-.ion-ios-infinite:before,
-.ion-ios-infinite-outline:before,
-.ion-ios-information:before,
-.ion-ios-information-empty:before,
-.ion-ios-information-outline:before,
-.ion-ios-ionic-outline:before,
-.ion-ios-keypad:before,
-.ion-ios-keypad-outline:before,
-.ion-ios-lightbulb:before,
-.ion-ios-lightbulb-outline:before,
-.ion-ios-list:before,
-.ion-ios-list-outline:before,
-.ion-ios-location:before,
-.ion-ios-location-outline:before,
-.ion-ios-locked:before,
-.ion-ios-locked-outline:before,
-.ion-ios-loop:before,
-.ion-ios-loop-strong:before,
-.ion-ios-medical:before,
-.ion-ios-medical-outline:before,
-.ion-ios-medkit:before,
-.ion-ios-medkit-outline:before,
-.ion-ios-mic:before,
-.ion-ios-mic-off:before,
-.ion-ios-mic-outline:before,
-.ion-ios-minus:before,
-.ion-ios-minus-empty:before,
-.ion-ios-minus-outline:before,
-.ion-ios-monitor:before,
-.ion-ios-monitor-outline:before,
-.ion-ios-moon:before,
-.ion-ios-moon-outline:before,
-.ion-ios-more:before,
-.ion-ios-more-outline:before,
-.ion-ios-musical-note:before,
-.ion-ios-musical-notes:before,
-.ion-ios-navigate:before,
-.ion-ios-navigate-outline:before,
-.ion-ios-nutrition:before,
-.ion-ios-nutrition-outline:before,
-.ion-ios-paper:before,
-.ion-ios-paper-outline:before,
-.ion-ios-paperplane:before,
-.ion-ios-paperplane-outline:before,
-.ion-ios-partlysunny:before,
-.ion-ios-partlysunny-outline:before,
-.ion-ios-pause:before,
-.ion-ios-pause-outline:before,
-.ion-ios-paw:before,
-.ion-ios-paw-outline:before,
-.ion-ios-people:before,
-.ion-ios-people-outline:before,
-.ion-ios-person:before,
-.ion-ios-person-outline:before,
-.ion-ios-personadd:before,
-.ion-ios-personadd-outline:before,
-.ion-ios-photos:before,
-.ion-ios-photos-outline:before,
-.ion-ios-pie:before,
-.ion-ios-pie-outline:before,
-.ion-ios-pint:before,
-.ion-ios-pint-outline:before,
-.ion-ios-play:before,
-.ion-ios-play-outline:before,
-.ion-ios-plus:before,
-.ion-ios-plus-empty:before,
-.ion-ios-plus-outline:before,
-.ion-ios-pricetag:before,
-.ion-ios-pricetag-outline:before,
-.ion-ios-pricetags:before,
-.ion-ios-pricetags-outline:before,
-.ion-ios-printer:before,
-.ion-ios-printer-outline:before,
-.ion-ios-pulse:before,
-.ion-ios-pulse-strong:before,
-.ion-ios-rainy:before,
-.ion-ios-rainy-outline:before,
-.ion-ios-recording:before,
-.ion-ios-recording-outline:before,
-.ion-ios-redo:before,
-.ion-ios-redo-outline:before,
-.ion-ios-refresh:before,
-.ion-ios-refresh-empty:before,
-.ion-ios-refresh-outline:before,
-.ion-ios-reload:before,
-.ion-ios-reverse-camera:before,
-.ion-ios-reverse-camera-outline:before,
-.ion-ios-rewind:before,
-.ion-ios-rewind-outline:before,
-.ion-ios-rose:before,
-.ion-ios-rose-outline:before,
-.ion-ios-search:before,
-.ion-ios-search-strong:before,
-.ion-ios-settings:before,
-.ion-ios-settings-strong:before,
-.ion-ios-shuffle:before,
-.ion-ios-shuffle-strong:before,
-.ion-ios-skipbackward:before,
-.ion-ios-skipbackward-outline:before,
-.ion-ios-skipforward:before,
-.ion-ios-skipforward-outline:before,
-.ion-ios-snowy:before,
-.ion-ios-speedometer:before,
-.ion-ios-speedometer-outline:before,
-.ion-ios-star:before,
-.ion-ios-star-half:before,
-.ion-ios-star-outline:before,
-.ion-ios-stopwatch:before,
-.ion-ios-stopwatch-outline:before,
-.ion-ios-sunny:before,
-.ion-ios-sunny-outline:before,
-.ion-ios-telephone:before,
-.ion-ios-telephone-outline:before,
-.ion-ios-tennisball:before,
-.ion-ios-tennisball-outline:before,
-.ion-ios-thunderstorm:before,
-.ion-ios-thunderstorm-outline:before,
-.ion-ios-time:before,
-.ion-ios-time-outline:before,
-.ion-ios-timer:before,
-.ion-ios-timer-outline:before,
-.ion-ios-toggle:before,
-.ion-ios-toggle-outline:before,
-.ion-ios-trash:before,
-.ion-ios-trash-outline:before,
-.ion-ios-undo:before,
-.ion-ios-undo-outline:before,
-.ion-ios-unlocked:before,
-.ion-ios-unlocked-outline:before,
-.ion-ios-upload:before,
-.ion-ios-upload-outline:before,
-.ion-ios-videocam:before,
-.ion-ios-videocam-outline:before,
-.ion-ios-volume-high:before,
-.ion-ios-volume-low:before,
-.ion-ios-wineglass:before,
-.ion-ios-wineglass-outline:before,
-.ion-ios-world:before,
-.ion-ios-world-outline:before,
-.ion-ipad:before,
-.ion-iphone:before,
-.ion-ipod:before,
-.ion-jet:before,
-.ion-key:before,
-.ion-knife:before,
-.ion-laptop:before,
-.ion-leaf:before,
-.ion-levels:before,
-.ion-lightbulb:before,
-.ion-link:before,
-.ion-load-a:before,
-.ion-load-b:before,
-.ion-load-c:before,
-.ion-load-d:before,
-.ion-location:before,
-.ion-lock-combination:before,
-.ion-locked:before,
-.ion-log-in:before,
-.ion-log-out:before,
-.ion-loop:before,
-.ion-magnet:before,
-.ion-male:before,
-.ion-man:before,
-.ion-map:before,
-.ion-medkit:before,
-.ion-merge:before,
-.ion-mic-a:before,
-.ion-mic-b:before,
-.ion-mic-c:before,
-.ion-minus:before,
-.ion-minus-circled:before,
-.ion-minus-round:before,
-.ion-model-s:before,
-.ion-monitor:before,
-.ion-more:before,
-.ion-mouse:before,
-.ion-music-note:before,
-.ion-navicon:before,
-.ion-navicon-round:before,
-.ion-navigate:before,
-.ion-network:before,
-.ion-no-smoking:before,
-.ion-nuclear:before,
-.ion-outlet:before,
-.ion-paintbrush:before,
-.ion-paintbucket:before,
-.ion-paper-airplane:before,
-.ion-paperclip:before,
-.ion-pause:before,
-.ion-person:before,
-.ion-person-add:before,
-.ion-person-stalker:before,
-.ion-pie-graph:before,
-.ion-pin:before,
-.ion-pinpoint:before,
-.ion-pizza:before,
-.ion-plane:before,
-.ion-planet:before,
-.ion-play:before,
-.ion-playstation:before,
-.ion-plus:before,
-.ion-plus-circled:before,
-.ion-plus-round:before,
-.ion-podium:before,
-.ion-pound:before,
-.ion-power:before,
-.ion-pricetag:before,
-.ion-pricetags:before,
-.ion-printer:before,
-.ion-pull-request:before,
-.ion-qr-scanner:before,
-.ion-quote:before,
-.ion-radio-waves:before,
-.ion-record:before,
-.ion-refresh:before,
-.ion-reply:before,
-.ion-reply-all:before,
-.ion-ribbon-a:before,
-.ion-ribbon-b:before,
-.ion-sad:before,
-.ion-sad-outline:before,
-.ion-scissors:before,
-.ion-search:before,
-.ion-settings:before,
-.ion-share:before,
-.ion-shuffle:before,
-.ion-skip-backward:before,
-.ion-skip-forward:before,
-.ion-social-android:before,
-.ion-social-android-outline:before,
-.ion-social-angular:before,
-.ion-social-angular-outline:before,
-.ion-social-apple:before,
-.ion-social-apple-outline:before,
-.ion-social-bitcoin:before,
-.ion-social-bitcoin-outline:before,
-.ion-social-buffer:before,
-.ion-social-buffer-outline:before,
-.ion-social-chrome:before,
-.ion-social-chrome-outline:before,
-.ion-social-codepen:before,
-.ion-social-codepen-outline:before,
-.ion-social-css3:before,
-.ion-social-css3-outline:before,
-.ion-social-designernews:before,
-.ion-social-designernews-outline:before,
-.ion-social-dribbble:before,
-.ion-social-dribbble-outline:before,
-.ion-social-dropbox:before,
-.ion-social-dropbox-outline:before,
-.ion-social-euro:before,
-.ion-social-euro-outline:before,
-.ion-social-facebook:before,
-.ion-social-facebook-outline:before,
-.ion-social-foursquare:before,
-.ion-social-foursquare-outline:before,
-.ion-social-freebsd-devil:before,
-.ion-social-github:before,
-.ion-social-github-outline:before,
-.ion-social-google:before,
-.ion-social-google-outline:before,
-.ion-social-googleplus:before,
-.ion-social-googleplus-outline:before,
-.ion-social-hackernews:before,
-.ion-social-hackernews-outline:before,
-.ion-social-html5:before,
-.ion-social-html5-outline:before,
-.ion-social-instagram:before,
-.ion-social-instagram-outline:before,
-.ion-social-javascript:before,
-.ion-social-javascript-outline:before,
-.ion-social-linkedin:before,
-.ion-social-linkedin-outline:before,
-.ion-social-markdown:before,
-.ion-social-nodejs:before,
-.ion-social-octocat:before,
-.ion-social-pinterest:before,
-.ion-social-pinterest-outline:before,
-.ion-social-python:before,
-.ion-social-reddit:before,
-.ion-social-reddit-outline:before,
-.ion-social-rss:before,
-.ion-social-rss-outline:before,
-.ion-social-sass:before,
-.ion-social-skype:before,
-.ion-social-skype-outline:before,
-.ion-social-snapchat:before,
-.ion-social-snapchat-outline:before,
-.ion-social-tumblr:before,
-.ion-social-tumblr-outline:before,
-.ion-social-tux:before,
-.ion-social-twitch:before,
-.ion-social-twitch-outline:before,
-.ion-social-twitter:before,
-.ion-social-twitter-outline:before,
-.ion-social-usd:before,
-.ion-social-usd-outline:before,
-.ion-social-vimeo:before,
-.ion-social-vimeo-outline:before,
-.ion-social-whatsapp:before,
-.ion-social-whatsapp-outline:before,
-.ion-social-windows:before,
-.ion-social-windows-outline:before,
-.ion-social-wordpress:before,
-.ion-social-wordpress-outline:before,
-.ion-social-yahoo:before,
-.ion-social-yahoo-outline:before,
-.ion-social-yen:before,
-.ion-social-yen-outline:before,
-.ion-social-youtube:before,
-.ion-social-youtube-outline:before,
-.ion-soup-can:before,
-.ion-soup-can-outline:before,
-.ion-speakerphone:before,
-.ion-speedometer:before,
-.ion-spoon:before,
-.ion-star:before,
-.ion-stats-bars:before,
-.ion-steam:before,
-.ion-stop:before,
-.ion-thermometer:before,
-.ion-thumbsdown:before,
-.ion-thumbsup:before,
-.ion-toggle:before,
-.ion-toggle-filled:before,
-.ion-transgender:before,
-.ion-trash-a:before,
-.ion-trash-b:before,
-.ion-trophy:before,
-.ion-tshirt:before,
-.ion-tshirt-outline:before,
-.ion-umbrella:before,
-.ion-university:before,
-.ion-unlocked:before,
-.ion-upload:before,
-.ion-usb:before,
-.ion-videocamera:before,
-.ion-volume-high:before,
-.ion-volume-low:before,
-.ion-volume-medium:before,
-.ion-volume-mute:before,
-.ion-wand:before,
-.ion-waterdrop:before,
-.ion-wifi:before,
-.ion-wineglass:before,
-.ion-woman:before,
-.ion-wrench:before,
-.ion-xbox:before {
- display: inline-block;
- font-family: "Ionicons";
- speak: none;
- font-style: normal;
- font-weight: normal;
- font-variant: normal;
- text-transform: none;
- text-rendering: auto;
- line-height: 1;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.ion-alert:before {
- content: "";
-}
-
-.ion-alert-circled:before {
- content: "";
-}
-
-.ion-android-add:before {
- content: "";
-}
-
-.ion-android-add-circle:before {
- content: "";
-}
-
-.ion-android-alarm-clock:before {
- content: "";
-}
-
-.ion-android-alert:before {
- content: "";
-}
-
-.ion-android-apps:before {
- content: "";
-}
-
-.ion-android-archive:before {
- content: "";
-}
-
-.ion-android-arrow-back:before {
- content: "";
-}
-
-.ion-android-arrow-down:before {
- content: "";
-}
-
-.ion-android-arrow-dropdown:before {
- content: "";
-}
-
-.ion-android-arrow-dropdown-circle:before {
- content: "";
-}
-
-.ion-android-arrow-dropleft:before {
- content: "";
-}
-
-.ion-android-arrow-dropleft-circle:before {
- content: "";
-}
-
-.ion-android-arrow-dropright:before {
- content: "";
-}
-
-.ion-android-arrow-dropright-circle:before {
- content: "";
-}
-
-.ion-android-arrow-dropup:before {
- content: "";
-}
-
-.ion-android-arrow-dropup-circle:before {
- content: "";
-}
-
-.ion-android-arrow-forward:before {
- content: "";
-}
-
-.ion-android-arrow-up:before {
- content: "";
-}
-
-.ion-android-attach:before {
- content: "";
-}
-
-.ion-android-bar:before {
- content: "";
-}
-
-.ion-android-bicycle:before {
- content: "";
-}
-
-.ion-android-boat:before {
- content: "";
-}
-
-.ion-android-bookmark:before {
- content: "";
-}
-
-.ion-android-bulb:before {
- content: "";
-}
-
-.ion-android-bus:before {
- content: "";
-}
-
-.ion-android-calendar:before {
- content: "";
-}
-
-.ion-android-call:before {
- content: "";
-}
-
-.ion-android-camera:before {
- content: "";
-}
-
-.ion-android-cancel:before {
- content: "";
-}
-
-.ion-android-car:before {
- content: "";
-}
-
-.ion-android-cart:before {
- content: "";
-}
-
-.ion-android-chat:before {
- content: "";
-}
-
-.ion-android-checkbox:before {
- content: "";
-}
-
-.ion-android-checkbox-blank:before {
- content: "";
-}
-
-.ion-android-checkbox-outline:before {
- content: "";
-}
-
-.ion-android-checkbox-outline-blank:before {
- content: "";
-}
-
-.ion-android-checkmark-circle:before {
- content: "";
-}
-
-.ion-android-clipboard:before {
- content: "";
-}
-
-.ion-android-close:before {
- content: "";
-}
-
-.ion-android-cloud:before {
- content: "";
-}
-
-.ion-android-cloud-circle:before {
- content: "";
-}
-
-.ion-android-cloud-done:before {
- content: "";
-}
-
-.ion-android-cloud-outline:before {
- content: "";
-}
-
-.ion-android-color-palette:before {
- content: "";
-}
-
-.ion-android-compass:before {
- content: "";
-}
-
-.ion-android-contact:before {
- content: "";
-}
-
-.ion-android-contacts:before {
- content: "";
-}
-
-.ion-android-contract:before {
- content: "";
-}
-
-.ion-android-create:before {
- content: "";
-}
-
-.ion-android-delete:before {
- content: "";
-}
-
-.ion-android-desktop:before {
- content: "";
-}
-
-.ion-android-document:before {
- content: "";
-}
-
-.ion-android-done:before {
- content: "";
-}
-
-.ion-android-done-all:before {
- content: "";
-}
-
-.ion-android-download:before {
- content: "";
-}
-
-.ion-android-drafts:before {
- content: "";
-}
-
-.ion-android-exit:before {
- content: "";
-}
-
-.ion-android-expand:before {
- content: "";
-}
-
-.ion-android-favorite:before {
- content: "";
-}
-
-.ion-android-favorite-outline:before {
- content: "";
-}
-
-.ion-android-film:before {
- content: "";
-}
-
-.ion-android-folder:before {
- content: "";
-}
-
-.ion-android-folder-open:before {
- content: "";
-}
-
-.ion-android-funnel:before {
- content: "";
-}
-
-.ion-android-globe:before {
- content: "";
-}
-
-.ion-android-hand:before {
- content: "";
-}
-
-.ion-android-hangout:before {
- content: "";
-}
-
-.ion-android-happy:before {
- content: "";
-}
-
-.ion-android-home:before {
- content: "";
-}
-
-.ion-android-image:before {
- content: "";
-}
-
-.ion-android-laptop:before {
- content: "";
-}
-
-.ion-android-list:before {
- content: "";
-}
-
-.ion-android-locate:before {
- content: "";
-}
-
-.ion-android-lock:before {
- content: "";
-}
-
-.ion-android-mail:before {
- content: "";
-}
-
-.ion-android-map:before {
- content: "";
-}
-
-.ion-android-menu:before {
- content: "";
-}
-
-.ion-android-microphone:before {
- content: "";
-}
-
-.ion-android-microphone-off:before {
- content: "";
-}
-
-.ion-android-more-horizontal:before {
- content: "";
-}
-
-.ion-android-more-vertical:before {
- content: "";
-}
-
-.ion-android-navigate:before {
- content: "";
-}
-
-.ion-android-notifications:before {
- content: "";
-}
-
-.ion-android-notifications-none:before {
- content: "";
-}
-
-.ion-android-notifications-off:before {
- content: "";
-}
-
-.ion-android-open:before {
- content: "";
-}
-
-.ion-android-options:before {
- content: "";
-}
-
-.ion-android-people:before {
- content: "";
-}
-
-.ion-android-person:before {
- content: "";
-}
-
-.ion-android-person-add:before {
- content: "";
-}
-
-.ion-android-phone-landscape:before {
- content: "";
-}
-
-.ion-android-phone-portrait:before {
- content: "";
-}
-
-.ion-android-pin:before {
- content: "";
-}
-
-.ion-android-plane:before {
- content: "";
-}
-
-.ion-android-playstore:before {
- content: "";
-}
-
-.ion-android-print:before {
- content: "";
-}
-
-.ion-android-radio-button-off:before {
- content: "";
-}
-
-.ion-android-radio-button-on:before {
- content: "";
-}
-
-.ion-android-refresh:before {
- content: "";
-}
-
-.ion-android-remove:before {
- content: "";
-}
-
-.ion-android-remove-circle:before {
- content: "";
-}
-
-.ion-android-restaurant:before {
- content: "";
-}
-
-.ion-android-sad:before {
- content: "";
-}
-
-.ion-android-search:before {
- content: "";
-}
-
-.ion-android-send:before {
- content: "";
-}
-
-.ion-android-settings:before {
- content: "";
-}
-
-.ion-android-share:before {
- content: "";
-}
-
-.ion-android-share-alt:before {
- content: "";
-}
-
-.ion-android-star:before {
- content: "";
-}
-
-.ion-android-star-half:before {
- content: "";
-}
-
-.ion-android-star-outline:before {
- content: "";
-}
-
-.ion-android-stopwatch:before {
- content: "";
-}
-
-.ion-android-subway:before {
- content: "";
-}
-
-.ion-android-sunny:before {
- content: "";
-}
-
-.ion-android-sync:before {
- content: "";
-}
-
-.ion-android-textsms:before {
- content: "";
-}
-
-.ion-android-time:before {
- content: "";
-}
-
-.ion-android-train:before {
- content: "";
-}
-
-.ion-android-unlock:before {
- content: "";
-}
-
-.ion-android-upload:before {
- content: "";
-}
-
-.ion-android-volume-down:before {
- content: "";
-}
-
-.ion-android-volume-mute:before {
- content: "";
-}
-
-.ion-android-volume-off:before {
- content: "";
-}
-
-.ion-android-volume-up:before {
- content: "";
-}
-
-.ion-android-walk:before {
- content: "";
-}
-
-.ion-android-warning:before {
- content: "";
-}
-
-.ion-android-watch:before {
- content: "";
-}
-
-.ion-android-wifi:before {
- content: "";
-}
-
-.ion-aperture:before {
- content: "";
-}
-
-.ion-archive:before {
- content: "";
-}
-
-.ion-arrow-down-a:before {
- content: "";
-}
-
-.ion-arrow-down-b:before {
- content: "";
-}
-
-.ion-arrow-down-c:before {
- content: "";
-}
-
-.ion-arrow-expand:before {
- content: "";
-}
-
-.ion-arrow-graph-down-left:before {
- content: "";
-}
-
-.ion-arrow-graph-down-right:before {
- content: "";
-}
-
-.ion-arrow-graph-up-left:before {
- content: "";
-}
-
-.ion-arrow-graph-up-right:before {
- content: "";
-}
-
-.ion-arrow-left-a:before {
- content: "";
-}
-
-.ion-arrow-left-b:before {
- content: "";
-}
-
-.ion-arrow-left-c:before {
- content: "";
-}
-
-.ion-arrow-move:before {
- content: "";
-}
-
-.ion-arrow-resize:before {
- content: "";
-}
-
-.ion-arrow-return-left:before {
- content: "";
-}
-
-.ion-arrow-return-right:before {
- content: "";
-}
-
-.ion-arrow-right-a:before {
- content: "";
-}
-
-.ion-arrow-right-b:before {
- content: "";
-}
-
-.ion-arrow-right-c:before {
- content: "";
-}
-
-.ion-arrow-shrink:before {
- content: "";
-}
-
-.ion-arrow-swap:before {
- content: "";
-}
-
-.ion-arrow-up-a:before {
- content: "";
-}
-
-.ion-arrow-up-b:before {
- content: "";
-}
-
-.ion-arrow-up-c:before {
- content: "";
-}
-
-.ion-asterisk:before {
- content: "";
-}
-
-.ion-at:before {
- content: "";
-}
-
-.ion-backspace:before {
- content: "";
-}
-
-.ion-backspace-outline:before {
- content: "";
-}
-
-.ion-bag:before {
- content: "";
-}
-
-.ion-battery-charging:before {
- content: "";
-}
-
-.ion-battery-empty:before {
- content: "";
-}
-
-.ion-battery-full:before {
- content: "";
-}
-
-.ion-battery-half:before {
- content: "";
-}
-
-.ion-battery-low:before {
- content: "";
-}
-
-.ion-beaker:before {
- content: "";
-}
-
-.ion-beer:before {
- content: "";
-}
-
-.ion-bluetooth:before {
- content: "";
-}
-
-.ion-bonfire:before {
- content: "";
-}
-
-.ion-bookmark:before {
- content: "";
-}
-
-.ion-bowtie:before {
- content: "";
-}
-
-.ion-briefcase:before {
- content: "";
-}
-
-.ion-bug:before {
- content: "";
-}
-
-.ion-calculator:before {
- content: "";
-}
-
-.ion-calendar:before {
- content: "";
-}
-
-.ion-camera:before {
- content: "";
-}
-
-.ion-card:before {
- content: "";
-}
-
-.ion-cash:before {
- content: "";
-}
-
-.ion-chatbox:before {
- content: "";
-}
-
-.ion-chatbox-working:before {
- content: "";
-}
-
-.ion-chatboxes:before {
- content: "";
-}
-
-.ion-chatbubble:before {
- content: "";
-}
-
-.ion-chatbubble-working:before {
- content: "";
-}
-
-.ion-chatbubbles:before {
- content: "";
-}
-
-.ion-checkmark:before {
- content: "";
-}
-
-.ion-checkmark-circled:before {
- content: "";
-}
-
-.ion-checkmark-round:before {
- content: "";
-}
-
-.ion-chevron-down:before {
- content: "";
-}
-
-.ion-chevron-left:before {
- content: "";
-}
-
-.ion-chevron-right:before {
- content: "";
-}
-
-.ion-chevron-up:before {
- content: "";
-}
-
-.ion-clipboard:before {
- content: "";
-}
-
-.ion-clock:before {
- content: "";
-}
-
-.ion-close:before {
- content: "";
-}
-
-.ion-close-circled:before {
- content: "";
-}
-
-.ion-close-round:before {
- content: "";
-}
-
-.ion-closed-captioning:before {
- content: "";
-}
-
-.ion-cloud:before {
- content: "";
-}
-
-.ion-code:before {
- content: "";
-}
-
-.ion-code-download:before {
- content: "";
-}
-
-.ion-code-working:before {
- content: "";
-}
-
-.ion-coffee:before {
- content: "";
-}
-
-.ion-compass:before {
- content: "";
-}
-
-.ion-compose:before {
- content: "";
-}
-
-.ion-connection-bars:before {
- content: "";
-}
-
-.ion-contrast:before {
- content: "";
-}
-
-.ion-crop:before {
- content: "";
-}
-
-.ion-cube:before {
- content: "";
-}
-
-.ion-disc:before {
- content: "";
-}
-
-.ion-document:before {
- content: "";
-}
-
-.ion-document-text:before {
- content: "";
-}
-
-.ion-drag:before {
- content: "";
-}
-
-.ion-earth:before {
- content: "";
-}
-
-.ion-easel:before {
- content: "";
-}
-
-.ion-edit:before {
- content: "";
-}
-
-.ion-egg:before {
- content: "";
-}
-
-.ion-eject:before {
- content: "";
-}
-
-.ion-email:before {
- content: "";
-}
-
-.ion-email-unread:before {
- content: "";
-}
-
-.ion-erlenmeyer-flask:before {
- content: "";
-}
-
-.ion-erlenmeyer-flask-bubbles:before {
- content: "";
-}
-
-.ion-eye:before {
- content: "";
-}
-
-.ion-eye-disabled:before {
- content: "";
-}
-
-.ion-female:before {
- content: "";
-}
-
-.ion-filing:before {
- content: "";
-}
-
-.ion-film-marker:before {
- content: "";
-}
-
-.ion-fireball:before {
- content: "";
-}
-
-.ion-flag:before {
- content: "";
-}
-
-.ion-flame:before {
- content: "";
-}
-
-.ion-flash:before {
- content: "";
-}
-
-.ion-flash-off:before {
- content: "";
-}
-
-.ion-folder:before {
- content: "";
-}
-
-.ion-fork:before {
- content: "";
-}
-
-.ion-fork-repo:before {
- content: "";
-}
-
-.ion-forward:before {
- content: "";
-}
-
-.ion-funnel:before {
- content: "";
-}
-
-.ion-gear-a:before {
- content: "";
-}
-
-.ion-gear-b:before {
- content: "";
-}
-
-.ion-grid:before {
- content: "";
-}
-
-.ion-hammer:before {
- content: "";
-}
-
-.ion-happy:before {
- content: "";
-}
-
-.ion-happy-outline:before {
- content: "";
-}
-
-.ion-headphone:before {
- content: "";
-}
-
-.ion-heart:before {
- content: "";
-}
-
-.ion-heart-broken:before {
- content: "";
-}
-
-.ion-help:before {
- content: "";
-}
-
-.ion-help-buoy:before {
- content: "";
-}
-
-.ion-help-circled:before {
- content: "";
-}
-
-.ion-home:before {
- content: "";
-}
-
-.ion-icecream:before {
- content: "";
-}
-
-.ion-image:before {
- content: "";
-}
-
-.ion-images:before {
- content: "";
-}
-
-.ion-information:before {
- content: "";
-}
-
-.ion-information-circled:before {
- content: "";
-}
-
-.ion-ionic:before {
- content: "";
-}
-
-.ion-ios-alarm:before {
- content: "";
-}
-
-.ion-ios-alarm-outline:before {
- content: "";
-}
-
-.ion-ios-albums:before {
- content: "";
-}
-
-.ion-ios-albums-outline:before {
- content: "";
-}
-
-.ion-ios-americanfootball:before {
- content: "";
-}
-
-.ion-ios-americanfootball-outline:before {
- content: "";
-}
-
-.ion-ios-analytics:before {
- content: "";
-}
-
-.ion-ios-analytics-outline:before {
- content: "";
-}
-
-.ion-ios-arrow-back:before {
- content: "";
-}
-
-.ion-ios-arrow-down:before {
- content: "";
-}
-
-.ion-ios-arrow-forward:before {
- content: "";
-}
-
-.ion-ios-arrow-left:before {
- content: "";
-}
-
-.ion-ios-arrow-right:before {
- content: "";
-}
-
-.ion-ios-arrow-thin-down:before {
- content: "";
-}
-
-.ion-ios-arrow-thin-left:before {
- content: "";
-}
-
-.ion-ios-arrow-thin-right:before {
- content: "";
-}
-
-.ion-ios-arrow-thin-up:before {
- content: "";
-}
-
-.ion-ios-arrow-up:before {
- content: "";
-}
-
-.ion-ios-at:before {
- content: "";
-}
-
-.ion-ios-at-outline:before {
- content: "";
-}
-
-.ion-ios-barcode:before {
- content: "";
-}
-
-.ion-ios-barcode-outline:before {
- content: "";
-}
-
-.ion-ios-baseball:before {
- content: "";
-}
-
-.ion-ios-baseball-outline:before {
- content: "";
-}
-
-.ion-ios-basketball:before {
- content: "";
-}
-
-.ion-ios-basketball-outline:before {
- content: "";
-}
-
-.ion-ios-bell:before {
- content: "";
-}
-
-.ion-ios-bell-outline:before {
- content: "";
-}
-
-.ion-ios-body:before {
- content: "";
-}
-
-.ion-ios-body-outline:before {
- content: "";
-}
-
-.ion-ios-bolt:before {
- content: "";
-}
-
-.ion-ios-bolt-outline:before {
- content: "";
-}
-
-.ion-ios-book:before {
- content: "";
-}
-
-.ion-ios-book-outline:before {
- content: "";
-}
-
-.ion-ios-bookmarks:before {
- content: "";
-}
-
-.ion-ios-bookmarks-outline:before {
- content: "";
-}
-
-.ion-ios-box:before {
- content: "";
-}
-
-.ion-ios-box-outline:before {
- content: "";
-}
-
-.ion-ios-briefcase:before {
- content: "";
-}
-
-.ion-ios-briefcase-outline:before {
- content: "";
-}
-
-.ion-ios-browsers:before {
- content: "";
-}
-
-.ion-ios-browsers-outline:before {
- content: "";
-}
-
-.ion-ios-calculator:before {
- content: "";
-}
-
-.ion-ios-calculator-outline:before {
- content: "";
-}
-
-.ion-ios-calendar:before {
- content: "";
-}
-
-.ion-ios-calendar-outline:before {
- content: "";
-}
-
-.ion-ios-camera:before {
- content: "";
-}
-
-.ion-ios-camera-outline:before {
- content: "";
-}
-
-.ion-ios-cart:before {
- content: "";
-}
-
-.ion-ios-cart-outline:before {
- content: "";
-}
-
-.ion-ios-chatboxes:before {
- content: "";
-}
-
-.ion-ios-chatboxes-outline:before {
- content: "";
-}
-
-.ion-ios-chatbubble:before {
- content: "";
-}
-
-.ion-ios-chatbubble-outline:before {
- content: "";
-}
-
-.ion-ios-checkmark:before {
- content: "";
-}
-
-.ion-ios-checkmark-empty:before {
- content: "";
-}
-
-.ion-ios-checkmark-outline:before {
- content: "";
-}
-
-.ion-ios-circle-filled:before {
- content: "";
-}
-
-.ion-ios-circle-outline:before {
- content: "";
-}
-
-.ion-ios-clock:before {
- content: "";
-}
-
-.ion-ios-clock-outline:before {
- content: "";
-}
-
-.ion-ios-close:before {
- content: "";
-}
-
-.ion-ios-close-empty:before {
- content: "";
-}
-
-.ion-ios-close-outline:before {
- content: "";
-}
-
-.ion-ios-cloud:before {
- content: "";
-}
-
-.ion-ios-cloud-download:before {
- content: "";
-}
-
-.ion-ios-cloud-download-outline:before {
- content: "";
-}
-
-.ion-ios-cloud-outline:before {
- content: "";
-}
-
-.ion-ios-cloud-upload:before {
- content: "";
-}
-
-.ion-ios-cloud-upload-outline:before {
- content: "";
-}
-
-.ion-ios-cloudy:before {
- content: "";
-}
-
-.ion-ios-cloudy-night:before {
- content: "";
-}
-
-.ion-ios-cloudy-night-outline:before {
- content: "";
-}
-
-.ion-ios-cloudy-outline:before {
- content: "";
-}
-
-.ion-ios-cog:before {
- content: "";
-}
-
-.ion-ios-cog-outline:before {
- content: "";
-}
-
-.ion-ios-color-filter:before {
- content: "";
-}
-
-.ion-ios-color-filter-outline:before {
- content: "";
-}
-
-.ion-ios-color-wand:before {
- content: "";
-}
-
-.ion-ios-color-wand-outline:before {
- content: "";
-}
-
-.ion-ios-compose:before {
- content: "";
-}
-
-.ion-ios-compose-outline:before {
- content: "";
-}
-
-.ion-ios-contact:before {
- content: "";
-}
-
-.ion-ios-contact-outline:before {
- content: "";
-}
-
-.ion-ios-copy:before {
- content: "";
-}
-
-.ion-ios-copy-outline:before {
- content: "";
-}
-
-.ion-ios-crop:before {
- content: "";
-}
-
-.ion-ios-crop-strong:before {
- content: "";
-}
-
-.ion-ios-download:before {
- content: "";
-}
-
-.ion-ios-download-outline:before {
- content: "";
-}
-
-.ion-ios-drag:before {
- content: "";
-}
-
-.ion-ios-email:before {
- content: "";
-}
-
-.ion-ios-email-outline:before {
- content: "";
-}
-
-.ion-ios-eye:before {
- content: "";
-}
-
-.ion-ios-eye-outline:before {
- content: "";
-}
-
-.ion-ios-fastforward:before {
- content: "";
-}
-
-.ion-ios-fastforward-outline:before {
- content: "";
-}
-
-.ion-ios-filing:before {
- content: "";
-}
-
-.ion-ios-filing-outline:before {
- content: "";
-}
-
-.ion-ios-film:before {
- content: "";
-}
-
-.ion-ios-film-outline:before {
- content: "";
-}
-
-.ion-ios-flag:before {
- content: "";
-}
-
-.ion-ios-flag-outline:before {
- content: "";
-}
-
-.ion-ios-flame:before {
- content: "";
-}
-
-.ion-ios-flame-outline:before {
- content: "";
-}
-
-.ion-ios-flask:before {
- content: "";
-}
-
-.ion-ios-flask-outline:before {
- content: "";
-}
-
-.ion-ios-flower:before {
- content: "";
-}
-
-.ion-ios-flower-outline:before {
- content: "";
-}
-
-.ion-ios-folder:before {
- content: "";
-}
-
-.ion-ios-folder-outline:before {
- content: "";
-}
-
-.ion-ios-football:before {
- content: "";
-}
-
-.ion-ios-football-outline:before {
- content: "";
-}
-
-.ion-ios-game-controller-a:before {
- content: "";
-}
-
-.ion-ios-game-controller-a-outline:before {
- content: "";
-}
-
-.ion-ios-game-controller-b:before {
- content: "";
-}
-
-.ion-ios-game-controller-b-outline:before {
- content: "";
-}
-
-.ion-ios-gear:before {
- content: "";
-}
-
-.ion-ios-gear-outline:before {
- content: "";
-}
-
-.ion-ios-glasses:before {
- content: "";
-}
-
-.ion-ios-glasses-outline:before {
- content: "";
-}
-
-.ion-ios-grid-view:before {
- content: "";
-}
-
-.ion-ios-grid-view-outline:before {
- content: "";
-}
-
-.ion-ios-heart:before {
- content: "";
-}
-
-.ion-ios-heart-outline:before {
- content: "";
-}
-
-.ion-ios-help:before {
- content: "";
-}
-
-.ion-ios-help-empty:before {
- content: "";
-}
-
-.ion-ios-help-outline:before {
- content: "";
-}
-
-.ion-ios-home:before {
- content: "";
-}
-
-.ion-ios-home-outline:before {
- content: "";
-}
-
-.ion-ios-infinite:before {
- content: "";
-}
-
-.ion-ios-infinite-outline:before {
- content: "";
-}
-
-.ion-ios-information:before {
- content: "";
-}
-
-.ion-ios-information-empty:before {
- content: "";
-}
-
-.ion-ios-information-outline:before {
- content: "";
-}
-
-.ion-ios-ionic-outline:before {
- content: "";
-}
-
-.ion-ios-keypad:before {
- content: "";
-}
-
-.ion-ios-keypad-outline:before {
- content: "";
-}
-
-.ion-ios-lightbulb:before {
- content: "";
-}
-
-.ion-ios-lightbulb-outline:before {
- content: "";
-}
-
-.ion-ios-list:before {
- content: "";
-}
-
-.ion-ios-list-outline:before {
- content: "";
-}
-
-.ion-ios-location:before {
- content: "";
-}
-
-.ion-ios-location-outline:before {
- content: "";
-}
-
-.ion-ios-locked:before {
- content: "";
-}
-
-.ion-ios-locked-outline:before {
- content: "";
-}
-
-.ion-ios-loop:before {
- content: "";
-}
-
-.ion-ios-loop-strong:before {
- content: "";
-}
-
-.ion-ios-medical:before {
- content: "";
-}
-
-.ion-ios-medical-outline:before {
- content: "";
-}
-
-.ion-ios-medkit:before {
- content: "";
-}
-
-.ion-ios-medkit-outline:before {
- content: "";
-}
-
-.ion-ios-mic:before {
- content: "";
-}
-
-.ion-ios-mic-off:before {
- content: "";
-}
-
-.ion-ios-mic-outline:before {
- content: "";
-}
-
-.ion-ios-minus:before {
- content: "";
-}
-
-.ion-ios-minus-empty:before {
- content: "";
-}
-
-.ion-ios-minus-outline:before {
- content: "";
-}
-
-.ion-ios-monitor:before {
- content: "";
-}
-
-.ion-ios-monitor-outline:before {
- content: "";
-}
-
-.ion-ios-moon:before {
- content: "";
-}
-
-.ion-ios-moon-outline:before {
- content: "";
-}
-
-.ion-ios-more:before {
- content: "";
-}
-
-.ion-ios-more-outline:before {
- content: "";
-}
-
-.ion-ios-musical-note:before {
- content: "";
-}
-
-.ion-ios-musical-notes:before {
- content: "";
-}
-
-.ion-ios-navigate:before {
- content: "";
-}
-
-.ion-ios-navigate-outline:before {
- content: "";
-}
-
-.ion-ios-nutrition:before {
- content: "";
-}
-
-.ion-ios-nutrition-outline:before {
- content: "";
-}
-
-.ion-ios-paper:before {
- content: "";
-}
-
-.ion-ios-paper-outline:before {
- content: "";
-}
-
-.ion-ios-paperplane:before {
- content: "";
-}
-
-.ion-ios-paperplane-outline:before {
- content: "";
-}
-
-.ion-ios-partlysunny:before {
- content: "";
-}
-
-.ion-ios-partlysunny-outline:before {
- content: "";
-}
-
-.ion-ios-pause:before {
- content: "";
-}
-
-.ion-ios-pause-outline:before {
- content: "";
-}
-
-.ion-ios-paw:before {
- content: "";
-}
-
-.ion-ios-paw-outline:before {
- content: "";
-}
-
-.ion-ios-people:before {
- content: "";
-}
-
-.ion-ios-people-outline:before {
- content: "";
-}
-
-.ion-ios-person:before {
- content: "";
-}
-
-.ion-ios-person-outline:before {
- content: "";
-}
-
-.ion-ios-personadd:before {
- content: "";
-}
-
-.ion-ios-personadd-outline:before {
- content: "";
-}
-
-.ion-ios-photos:before {
- content: "";
-}
-
-.ion-ios-photos-outline:before {
- content: "";
-}
-
-.ion-ios-pie:before {
- content: "";
-}
-
-.ion-ios-pie-outline:before {
- content: "";
-}
-
-.ion-ios-pint:before {
- content: "";
-}
-
-.ion-ios-pint-outline:before {
- content: "";
-}
-
-.ion-ios-play:before {
- content: "";
-}
-
-.ion-ios-play-outline:before {
- content: "";
-}
-
-.ion-ios-plus:before {
- content: "";
-}
-
-.ion-ios-plus-empty:before {
- content: "";
-}
-
-.ion-ios-plus-outline:before {
- content: "";
-}
-
-.ion-ios-pricetag:before {
- content: "";
-}
-
-.ion-ios-pricetag-outline:before {
- content: "";
-}
-
-.ion-ios-pricetags:before {
- content: "";
-}
-
-.ion-ios-pricetags-outline:before {
- content: "";
-}
-
-.ion-ios-printer:before {
- content: "";
-}
-
-.ion-ios-printer-outline:before {
- content: "";
-}
-
-.ion-ios-pulse:before {
- content: "";
-}
-
-.ion-ios-pulse-strong:before {
- content: "";
-}
-
-.ion-ios-rainy:before {
- content: "";
-}
-
-.ion-ios-rainy-outline:before {
- content: "";
-}
-
-.ion-ios-recording:before {
- content: "";
-}
-
-.ion-ios-recording-outline:before {
- content: "";
-}
-
-.ion-ios-redo:before {
- content: "";
-}
-
-.ion-ios-redo-outline:before {
- content: "";
-}
-
-.ion-ios-refresh:before {
- content: "";
-}
-
-.ion-ios-refresh-empty:before {
- content: "";
-}
-
-.ion-ios-refresh-outline:before {
- content: "";
-}
-
-.ion-ios-reload:before {
- content: "";
-}
-
-.ion-ios-reverse-camera:before {
- content: "";
-}
-
-.ion-ios-reverse-camera-outline:before {
- content: "";
-}
-
-.ion-ios-rewind:before {
- content: "";
-}
-
-.ion-ios-rewind-outline:before {
- content: "";
-}
-
-.ion-ios-rose:before {
- content: "";
-}
-
-.ion-ios-rose-outline:before {
- content: "";
-}
-
-.ion-ios-search:before {
- content: "";
-}
-
-.ion-ios-search-strong:before {
- content: "";
-}
-
-.ion-ios-settings:before {
- content: "";
-}
-
-.ion-ios-settings-strong:before {
- content: "";
-}
-
-.ion-ios-shuffle:before {
- content: "";
-}
-
-.ion-ios-shuffle-strong:before {
- content: "";
-}
-
-.ion-ios-skipbackward:before {
- content: "";
-}
-
-.ion-ios-skipbackward-outline:before {
- content: "";
-}
-
-.ion-ios-skipforward:before {
- content: "";
-}
-
-.ion-ios-skipforward-outline:before {
- content: "";
-}
-
-.ion-ios-snowy:before {
- content: "";
-}
-
-.ion-ios-speedometer:before {
- content: "";
-}
-
-.ion-ios-speedometer-outline:before {
- content: "";
-}
-
-.ion-ios-star:before {
- content: "";
-}
-
-.ion-ios-star-half:before {
- content: "";
-}
-
-.ion-ios-star-outline:before {
- content: "";
-}
-
-.ion-ios-stopwatch:before {
- content: "";
-}
-
-.ion-ios-stopwatch-outline:before {
- content: "";
-}
-
-.ion-ios-sunny:before {
- content: "";
-}
-
-.ion-ios-sunny-outline:before {
- content: "";
-}
-
-.ion-ios-telephone:before {
- content: "";
-}
-
-.ion-ios-telephone-outline:before {
- content: "";
-}
-
-.ion-ios-tennisball:before {
- content: "";
-}
-
-.ion-ios-tennisball-outline:before {
- content: "";
-}
-
-.ion-ios-thunderstorm:before {
- content: "";
-}
-
-.ion-ios-thunderstorm-outline:before {
- content: "";
-}
-
-.ion-ios-time:before {
- content: "";
-}
-
-.ion-ios-time-outline:before {
- content: "";
-}
-
-.ion-ios-timer:before {
- content: "";
-}
-
-.ion-ios-timer-outline:before {
- content: "";
-}
-
-.ion-ios-toggle:before {
- content: "";
-}
-
-.ion-ios-toggle-outline:before {
- content: "";
-}
-
-.ion-ios-trash:before {
- content: "";
-}
-
-.ion-ios-trash-outline:before {
- content: "";
-}
-
-.ion-ios-undo:before {
- content: "";
-}
-
-.ion-ios-undo-outline:before {
- content: "";
-}
-
-.ion-ios-unlocked:before {
- content: "";
-}
-
-.ion-ios-unlocked-outline:before {
- content: "";
-}
-
-.ion-ios-upload:before {
- content: "";
-}
-
-.ion-ios-upload-outline:before {
- content: "";
-}
-
-.ion-ios-videocam:before {
- content: "";
-}
-
-.ion-ios-videocam-outline:before {
- content: "";
-}
-
-.ion-ios-volume-high:before {
- content: "";
-}
-
-.ion-ios-volume-low:before {
- content: "";
-}
-
-.ion-ios-wineglass:before {
- content: "";
-}
-
-.ion-ios-wineglass-outline:before {
- content: "";
-}
-
-.ion-ios-world:before {
- content: "";
-}
-
-.ion-ios-world-outline:before {
- content: "";
-}
-
-.ion-ipad:before {
- content: "";
-}
-
-.ion-iphone:before {
- content: "";
-}
-
-.ion-ipod:before {
- content: "";
-}
-
-.ion-jet:before {
- content: "";
-}
-
-.ion-key:before {
- content: "";
-}
-
-.ion-knife:before {
- content: "";
-}
-
-.ion-laptop:before {
- content: "";
-}
-
-.ion-leaf:before {
- content: "";
-}
-
-.ion-levels:before {
- content: "";
-}
-
-.ion-lightbulb:before {
- content: "";
-}
-
-.ion-link:before {
- content: "";
-}
-
-.ion-load-a:before {
- content: "";
-}
-
-.ion-load-b:before {
- content: "";
-}
-
-.ion-load-c:before {
- content: "";
-}
-
-.ion-load-d:before {
- content: "";
-}
-
-.ion-location:before {
- content: "";
-}
-
-.ion-lock-combination:before {
- content: "";
-}
-
-.ion-locked:before {
- content: "";
-}
-
-.ion-log-in:before {
- content: "";
-}
-
-.ion-log-out:before {
- content: "";
-}
-
-.ion-loop:before {
- content: "";
-}
-
-.ion-magnet:before {
- content: "";
-}
-
-.ion-male:before {
- content: "";
-}
-
-.ion-man:before {
- content: "";
-}
-
-.ion-map:before {
- content: "";
-}
-
-.ion-medkit:before {
- content: "";
-}
-
-.ion-merge:before {
- content: "";
-}
-
-.ion-mic-a:before {
- content: "";
-}
-
-.ion-mic-b:before {
- content: "";
-}
-
-.ion-mic-c:before {
- content: "";
-}
-
-.ion-minus:before {
- content: "";
-}
-
-.ion-minus-circled:before {
- content: "";
-}
-
-.ion-minus-round:before {
- content: "";
-}
-
-.ion-model-s:before {
- content: "";
-}
-
-.ion-monitor:before {
- content: "";
-}
-
-.ion-more:before {
- content: "";
-}
-
-.ion-mouse:before {
- content: "";
-}
-
-.ion-music-note:before {
- content: "";
-}
-
-.ion-navicon:before {
- content: "";
-}
-
-.ion-navicon-round:before {
- content: "";
-}
-
-.ion-navigate:before {
- content: "";
-}
-
-.ion-network:before {
- content: "";
-}
-
-.ion-no-smoking:before {
- content: "";
-}
-
-.ion-nuclear:before {
- content: "";
-}
-
-.ion-outlet:before {
- content: "";
-}
-
-.ion-paintbrush:before {
- content: "";
-}
-
-.ion-paintbucket:before {
- content: "";
-}
-
-.ion-paper-airplane:before {
- content: "";
-}
-
-.ion-paperclip:before {
- content: "";
-}
-
-.ion-pause:before {
- content: "";
-}
-
-.ion-person:before {
- content: "";
-}
-
-.ion-person-add:before {
- content: "";
-}
-
-.ion-person-stalker:before {
- content: "";
-}
-
-.ion-pie-graph:before {
- content: "";
-}
-
-.ion-pin:before {
- content: "";
-}
-
-.ion-pinpoint:before {
- content: "";
-}
-
-.ion-pizza:before {
- content: "";
-}
-
-.ion-plane:before {
- content: "";
-}
-
-.ion-planet:before {
- content: "";
-}
-
-.ion-play:before {
- content: "";
-}
-
-.ion-playstation:before {
- content: "";
-}
-
-.ion-plus:before {
- content: "";
-}
-
-.ion-plus-circled:before {
- content: "";
-}
-
-.ion-plus-round:before {
- content: "";
-}
-
-.ion-podium:before {
- content: "";
-}
-
-.ion-pound:before {
- content: "";
-}
-
-.ion-power:before {
- content: "";
-}
-
-.ion-pricetag:before {
- content: "";
-}
-
-.ion-pricetags:before {
- content: "";
-}
-
-.ion-printer:before {
- content: "";
-}
-
-.ion-pull-request:before {
- content: "";
-}
-
-.ion-qr-scanner:before {
- content: "";
-}
-
-.ion-quote:before {
- content: "";
-}
-
-.ion-radio-waves:before {
- content: "";
-}
-
-.ion-record:before {
- content: "";
-}
-
-.ion-refresh:before {
- content: "";
-}
-
-.ion-reply:before {
- content: "";
-}
-
-.ion-reply-all:before {
- content: "";
-}
-
-.ion-ribbon-a:before {
- content: "";
-}
-
-.ion-ribbon-b:before {
- content: "";
-}
-
-.ion-sad:before {
- content: "";
-}
-
-.ion-sad-outline:before {
- content: "";
-}
-
-.ion-scissors:before {
- content: "";
-}
-
-.ion-search:before {
- content: "";
-}
-
-.ion-settings:before {
- content: "";
-}
-
-.ion-share:before {
- content: "";
-}
-
-.ion-shuffle:before {
- content: "";
-}
-
-.ion-skip-backward:before {
- content: "";
-}
-
-.ion-skip-forward:before {
- content: "";
-}
-
-.ion-social-android:before {
- content: "";
-}
-
-.ion-social-android-outline:before {
- content: "";
-}
-
-.ion-social-angular:before {
- content: "";
-}
-
-.ion-social-angular-outline:before {
- content: "";
-}
-
-.ion-social-apple:before {
- content: "";
-}
-
-.ion-social-apple-outline:before {
- content: "";
-}
-
-.ion-social-bitcoin:before {
- content: "";
-}
-
-.ion-social-bitcoin-outline:before {
- content: "";
-}
-
-.ion-social-buffer:before {
- content: "";
-}
-
-.ion-social-buffer-outline:before {
- content: "";
-}
-
-.ion-social-chrome:before {
- content: "";
-}
-
-.ion-social-chrome-outline:before {
- content: "";
-}
-
-.ion-social-codepen:before {
- content: "";
-}
-
-.ion-social-codepen-outline:before {
- content: "";
-}
-
-.ion-social-css3:before {
- content: "";
-}
-
-.ion-social-css3-outline:before {
- content: "";
-}
-
-.ion-social-designernews:before {
- content: "";
-}
-
-.ion-social-designernews-outline:before {
- content: "";
-}
-
-.ion-social-dribbble:before {
- content: "";
-}
-
-.ion-social-dribbble-outline:before {
- content: "";
-}
-
-.ion-social-dropbox:before {
- content: "";
-}
-
-.ion-social-dropbox-outline:before {
- content: "";
-}
-
-.ion-social-euro:before {
- content: "";
-}
-
-.ion-social-euro-outline:before {
- content: "";
-}
-
-.ion-social-facebook:before {
- content: "";
-}
-
-.ion-social-facebook-outline:before {
- content: "";
-}
-
-.ion-social-foursquare:before {
- content: "";
-}
-
-.ion-social-foursquare-outline:before {
- content: "";
-}
-
-.ion-social-freebsd-devil:before {
- content: "";
-}
-
-.ion-social-github:before {
- content: "";
-}
-
-.ion-social-github-outline:before {
- content: "";
-}
-
-.ion-social-google:before {
- content: "";
-}
-
-.ion-social-google-outline:before {
- content: "";
-}
-
-.ion-social-googleplus:before {
- content: "";
-}
-
-.ion-social-googleplus-outline:before {
- content: "";
-}
-
-.ion-social-hackernews:before {
- content: "";
-}
-
-.ion-social-hackernews-outline:before {
- content: "";
-}
-
-.ion-social-html5:before {
- content: "";
-}
-
-.ion-social-html5-outline:before {
- content: "";
-}
-
-.ion-social-instagram:before {
- content: "";
-}
-
-.ion-social-instagram-outline:before {
- content: "";
-}
-
-.ion-social-javascript:before {
- content: "";
-}
-
-.ion-social-javascript-outline:before {
- content: "";
-}
-
-.ion-social-linkedin:before {
- content: "";
-}
-
-.ion-social-linkedin-outline:before {
- content: "";
-}
-
-.ion-social-markdown:before {
- content: "";
-}
-
-.ion-social-nodejs:before {
- content: "";
-}
-
-.ion-social-octocat:before {
- content: "";
-}
-
-.ion-social-pinterest:before {
- content: "";
-}
-
-.ion-social-pinterest-outline:before {
- content: "";
-}
-
-.ion-social-python:before {
- content: "";
-}
-
-.ion-social-reddit:before {
- content: "";
-}
-
-.ion-social-reddit-outline:before {
- content: "";
-}
-
-.ion-social-rss:before {
- content: "";
-}
-
-.ion-social-rss-outline:before {
- content: "";
-}
-
-.ion-social-sass:before {
- content: "";
-}
-
-.ion-social-skype:before {
- content: "";
-}
-
-.ion-social-skype-outline:before {
- content: "";
-}
-
-.ion-social-snapchat:before {
- content: "";
-}
-
-.ion-social-snapchat-outline:before {
- content: "";
-}
-
-.ion-social-tumblr:before {
- content: "";
-}
-
-.ion-social-tumblr-outline:before {
- content: "";
-}
-
-.ion-social-tux:before {
- content: "";
-}
-
-.ion-social-twitch:before {
- content: "";
-}
-
-.ion-social-twitch-outline:before {
- content: "";
-}
-
-.ion-social-twitter:before {
- content: "";
-}
-
-.ion-social-twitter-outline:before {
- content: "";
-}
-
-.ion-social-usd:before {
- content: "";
-}
-
-.ion-social-usd-outline:before {
- content: "";
-}
-
-.ion-social-vimeo:before {
- content: "";
-}
-
-.ion-social-vimeo-outline:before {
- content: "";
-}
-
-.ion-social-whatsapp:before {
- content: "";
-}
-
-.ion-social-whatsapp-outline:before {
- content: "";
-}
-
-.ion-social-windows:before {
- content: "";
-}
-
-.ion-social-windows-outline:before {
- content: "";
-}
-
-.ion-social-wordpress:before {
- content: "";
-}
-
-.ion-social-wordpress-outline:before {
- content: "";
-}
-
-.ion-social-yahoo:before {
- content: "";
-}
-
-.ion-social-yahoo-outline:before {
- content: "";
-}
-
-.ion-social-yen:before {
- content: "";
-}
-
-.ion-social-yen-outline:before {
- content: "";
-}
-
-.ion-social-youtube:before {
- content: "";
-}
-
-.ion-social-youtube-outline:before {
- content: "";
-}
-
-.ion-soup-can:before {
- content: "";
-}
-
-.ion-soup-can-outline:before {
- content: "";
-}
-
-.ion-speakerphone:before {
- content: "";
-}
-
-.ion-speedometer:before {
- content: "";
-}
-
-.ion-spoon:before {
- content: "";
-}
-
-.ion-star:before {
- content: "";
-}
-
-.ion-stats-bars:before {
- content: "";
-}
-
-.ion-steam:before {
- content: "";
-}
-
-.ion-stop:before {
- content: "";
-}
-
-.ion-thermometer:before {
- content: "";
-}
-
-.ion-thumbsdown:before {
- content: "";
-}
-
-.ion-thumbsup:before {
- content: "";
-}
-
-.ion-toggle:before {
- content: "";
-}
-
-.ion-toggle-filled:before {
- content: "";
-}
-
-.ion-transgender:before {
- content: "";
-}
-
-.ion-trash-a:before {
- content: "";
-}
-
-.ion-trash-b:before {
- content: "";
-}
-
-.ion-trophy:before {
- content: "";
-}
-
-.ion-tshirt:before {
- content: "";
-}
-
-.ion-tshirt-outline:before {
- content: "";
-}
-
-.ion-umbrella:before {
- content: "";
-}
-
-.ion-university:before {
- content: "";
-}
-
-.ion-unlocked:before {
- content: "";
-}
-
-.ion-upload:before {
- content: "";
-}
-
-.ion-usb:before {
- content: "";
-}
-
-.ion-videocamera:before {
- content: "";
-}
-
-.ion-volume-high:before {
- content: "";
-}
-
-.ion-volume-low:before {
- content: "";
-}
-
-.ion-volume-medium:before {
- content: "";
-}
-
-.ion-volume-mute:before {
- content: "";
-}
-
-.ion-wand:before {
- content: "";
-}
-
-.ion-waterdrop:before {
- content: "";
-}
-
-.ion-wifi:before {
- content: "";
-}
-
-.ion-wineglass:before {
- content: "";
-}
-
-.ion-woman:before {
- content: "";
-}
-
-.ion-wrench:before {
- content: "";
-}
-
-.ion-xbox:before {
- content: "";
-}
-
-html {
- height: 100%;
-}
-
-body {
- min-height: 100%;
-}
-
-body#card {
- background: #f1f1fa;
- padding-top: 4em;
- font-size: 0.9em;
- text-align: center;
-}
-body#card.dashboard {
- padding-top: 0;
-}
-
-.tooltip {
- font-weight: 600;
- cursor: help;
-}
-
-#title {
- text-align: center;
- margin-bottom: 3em;
-}
-#title h1 {
- font-size: 1.2em;
-}
-#title img {
- max-width: 70px;
-}
-
-.row.section {
- padding-top: 5em;
- padding-bottom: 5em;
- border-bottom: 1px solid #ddd;
-}
-.row.section#header {
- border-color: #359173;
-}
-
-#header {
- border-bottom: 1px solid #ddd;
-}
-#header i {
- font-size: 4em;
- color: #1b3544;
-}
-#header .next {
- opacity: 0.5;
-}
-#header .success i {
- color: #359173;
-}
-#header .error i {
- color: #D9534F;
-}
-#header .done {
- opacity: 0.3;
-}
-#header .done p {
- text-decoration: line-through;
-}
-#header .done i, #header .current i {
- color: #359173;
-}
-
-.container {
- padding-top: 1em;
- padding-bottom: 1em;
-}
-@media (max-width: 760px) {
- .container {
- padding-bottom: 0 !important;
- }
-}
-.container.block {
- padding-bottom: 1.5em;
- padding-top: 1.5em;
-}
-@media (max-width: 760px) {
- .container.block {
- padding-bottom: 0 !important;
- }
-}
-.container.block:first-child {
- padding-top: 0;
-}
-.container.block:last-child {
- padding-bottom: 0;
-}
-@media (min-width: 760px) {
- .container.card {
- max-width: 500px;
- }
-}
-@media (max-width: 760px) {
- .container.card {
- margin-right: 20px;
- margin-left: 20px;
- }
-}
-.container.index-card {
- max-width: 950px;
-}
-
-.card,
-.index-card {
- padding: 0.9em;
- background: #fff;
- border: 1px solid #ddd;
-}
-.card h1,
-.index-card h1 {
- font-size: 1.8em;
-}
-
-.row.grey {
- background: #f1f1fa;
-}
-
-p {
- line-height: 1.5em;
-}
-
-p.code {
- font-size: 0.8em;
- font-family: "source-code-pro", monospace;
- border: 1px solid #ddd;
- background: #fff;
-}
-@media (max-width: 760px) {
- p.code {
- overflow: auto;
- }
-}
-
-span.code {
- font-family: "source-code-pro", monospace;
- display: inline-block;
- padding: 0 0.2em;
- border: 1px solid #ddd;
- background: #fff;
- font-size: 0.9em;
-}
-
-input, textarea {
- font-size: 0.8em;
- font-family: "proxima-nova-soft", sans-serif;
- border: 1px solid #ddd;
- background: #fff;
- padding: 0.9em;
- transition: all 0.3s ease-in-out;
- width: 100%;
-}
-input.code, textarea.code {
- font-family: "source-code-pro", monospace;
-}
-input:focus, textarea:focus {
- border-color: #2A735B;
- outline: none;
- box-shadow: 0 0 5px 1px #359173;
-}
-
-input[type=checkbox],
-input[type=radio] {
- width: auto;
- margin-right: 6px;
-}
-
-form input, form textarea {
- margin-bottom: 0.5em;
-}
-
-table#invoices {
- line-height: 3em;
- overflow-x: auto;
-}
-@media screen and (max-width: 736px) {
- table#invoices {
- border: 0;
- }
- table#invoices thead {
- display: none;
- }
- table#invoices tr {
- margin-bottom: 10px;
- display: block;
- border-bottom: 5px solid #ddd;
- }
- table#invoices tr td {
- display: block;
- font-size: 13px;
- border-bottom: 1px dotted #ccc;
- margin: 10px auto;
- max-width: 100%;
- }
- table#invoices tr td:last-child {
- border-bottom: 0;
- }
- table#invoices tr td:before {
- content: attr(data-label);
- display: block;
- text-transform: uppercase;
- font-weight: bold;
- }
-}
-
-button, a.button {
- font-size: 1em;
- text-transform: uppercase;
- font-weight: 600;
- border: 2px solid #359173;
- color: #359173;
- background: transparent;
- line-height: 1em;
- padding: 0.6em 0.9em;
- transition: all 0.3s ease-in-out;
-}
-button.no-uppercase, a.button.no-uppercase {
- text-transform: none !important;
-}
-button:hover, a.button:hover {
- border-color: #2A735B;
- color: #2A735B;
-}
-button:hover.emphasis, a.button:hover.emphasis {
- color: white;
- background-color: #2A735B;
-}
-button:focus, a.button:focus {
- outline: 0;
-}
-button.destructive, a.button.destructive {
- color: #D9534F;
- border-color: #D9534F;
-}
-button.disabled, a.button.disabled {
- color: #707070;
- border-color: #707070;
-}
-button[disabled], button[disabled]:hover, a.button[disabled], a.button[disabled]:hover {
- color: #b0e2d2;
- border-color: #b0e2d2;
-}
-
-.animate {
- -moz-animation-iteration-count: once;
- -moz-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22);
- -moz-animation-duration: 0.4s;
- -webkit-animation-iteration-count: once;
- -webkit-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22);
- -webkit-animation-duration: 0.4s;
-}
-.animate.dropIn {
- -moz-animation-name: dropIn;
- -webkit-animation-name: dropIn;
-}
-
-@-webkit-keyframes fadeIn {
- 0% {
- -webkit-transform: translate3d(0, 0, 0);
- -moz-transform: translate3d(0, 0, 0);
- opacity: 0;
- }
- 100% {
- -webkit-transform: translate3d(0, 0, 0);
- -moz-transform: translate3d(0, 0, 0);
- opacity: 1;
- }
-}
-@-webkit-keyframes dropIn {
- 0% {
- opacity: 0;
- -webkit-transform: translate3d(0, -150px, 0);
- -moz-transform: translate3d(0, -150px, 0);
- }
- 100% {
- opacity: 1;
- -webkit-transform: translate3d(0, 0, 0);
- -moz-transform: translate3d(0, 0, 0);
- }
-}
-@-webkit-keyframes dropInLong {
- 0% {
- opacity: 0;
- -webkit-transform: translate3d(0, -450px, 0);
- -moz-transform: translate3d(0, -450px, 0);
- }
- 100% {
- opacity: 1;
- -webkit-transform: translate3d(0, 0, 0);
- -moz-transform: translate3d(0, 0, 0);
- }
-}
-@-webkit-keyframes rotate {
- 100% {
- -webkit-transform: rotate(45deg);
- -moz-transform: rotate(45deg);
- }
-}
-@-webkit-keyframes rotateBack {
- 100% {
- -webkit-transform: rotate(0deg);
- -moz-transform: rotate(0deg);
- }
-}
-.overlay {
- position: fixed;
- width: 100%;
- height: 100%;
- top: -10000px;
- left: -10000px;
- opacity: 0;
- transition: opacity 0.4s linear;
- background: rgba(255, 255, 255, 0.96);
-}
-
-body.showOverlay {
- overflow: hidden;
-}
-body.showOverlay .overlay {
- top: 0;
- left: 0;
- opacity: 1;
-}
-body.showOverlay .overlay iframe {
- -webkit-animation-iteration-count: once;
- -webkit-animation-timing-function: cubic-bezier(0.895, 0.03, 0.685, 0.22);
- -webkit-animation-duration: 0.4s;
- -moz-animation-name: dropInLong;
- -webkit-animation-name: dropInLong;
-}
-
-.toggleOverlay {
- cursor: pointer;
- position: fixed;
- top: 20px;
- left: 20px;
- font-size: 2.2em;
- font-weight: 600;
- -moz-animation-iteration-count: once;
- -moz-animation-fill-mode: forwards;
- -moz-animation-timing-function: linear;
- -moz-animation-duration: 0.2s;
- -webkit-animation-iteration-count: once;
- -webkit-animation-fill-mode: forwards;
- -webkit-animation-timing-function: linear;
- -webkit-animation-duration: 0.2s;
-}
-
-body.showOverlay .toggleOverlay {
- -moz-animation-name: rotate;
- -webkit-animation-name: rotate;
-}
-
-#toast-container {
- right: 30%;
- left: 30%;
- width: 40%;
-}
diff --git a/formspree/static/js/bundle.js b/formspree/static/js/bundle.js
deleted file mode 100644
index ef89404..0000000
--- a/formspree/static/js/bundle.js
+++ /dev/null
@@ -1,3531 +0,0 @@
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o nav');
-nav.addClass('js');
-nav.find('.menu').slicknav();
-nav.find('h4').clone().prependTo('.slicknav_menu');
-
-/* adding a shadow at the bottom of the menu bar only when not at the top */
-var w = $(window);
-w.scroll(function () {
- var scrollPos = w.scrollTop();
- if (scrollPos && !nav.hasClass('scrolled')) {
- nav.addClass('scrolled');
- } else if (!scrollPos) {
- nav.removeClass('scrolled');
- }
-});
-
-/* background-color should inherit, but CSS's "inherit" breaks z-index */
-var bgcolor = $(document.body).css('background-color');
-if (bgcolor.split(',').length === 4 || bgcolor === 'transparent') {
- bgcolor = 'white';
-}
-nav.css('background-color', bgcolor);
-
-/* modals -- working with or without JS */
-function modals() {
- $('.modal').each(function () {
- var modal = $(this);
- modal.addClass('js');
- var id = modal.attr('id');
-
- $('[href="#' + id + '"]').click(function (e) {
- // open the modal
- e.preventDefault();
- modal.toggleClass('target');
- });
-
- modal.click(function (e) {
- // close the modal
- if (e.target === modal[0]) {
- cleanHash();
- modal.toggleClass('target');
- e.preventDefault();
- }
- });
- modal.find('.x a').click(function (e) {
- // close the modal
- cleanHash();
- e.preventDefault();
- modal.toggleClass('target');
- });
- });
-
- function cleanHash() {
- if (!window.location.hash) return;
- if (window.history && window.history.replaceState) {
- window.history.replaceState('', document.title, window.location.pathname);
- } else {
- var pos = $(window).scrollTop();
- window.location.hash = '';
- $(window).scrollTop(pos);
- }
- }
-
- // activate modals from url hash #
- setTimeout(function () {
- // setTimeout is needed because :target elements only appear after
- // the page is loaded or something like that.
- var activatedModal = $('*:target');
- if (activatedModal.length && !activatedModal.is('.target')) {
- activatedModal.toggleClass('target');
- }
- }, 0);
-}
-modals();
-
-/* turning flask flash messages into js popup notifications */
-window.popupMessages.forEach(function (m, i) {
- var category = m[0] || 'info';
- var text = m[1];
- setTimeout(function () {
- toastr[category](text);
- }, (1 + i) * 1500);
-});
-
-/* stripe checkout */
-var stripebutton = $('#stripe-upgrade');
-if (stripebutton.length) {
- var handler = StripeCheckout.configure(stripebutton.data());
- stripebutton.on('click', function (e) {
- handler.open({
- token: function token(_token) {
- stripebutton.closest('form').append(' ').append(' ').submit();
- }
- });
- e.preventDefault();
- });
-}
-
-/* quick script for showing the resend confirmation form */
-$('a.resend').on('click', function () {
- $(this).hide();
- $('form.resend').show();
- return false;
-});
-
-/* scripts at other files */
-require('./sitewide')();
-
-/* toggle the card management menu */
-$(function () {
- $("#card-list tr:even").addClass("even");
- $("#card-list tr:not(.even)").hide();
- $("#card-list tr:first-child").show();
-
- $("#card-list tr.even").click(function () {
- $(this).next("tr").toggle();
- $(this).find(".arrow").toggleClass("up");
- $(this).find(".fa-chevron-right").toggleClass("fa-rotate-90");
- });
-});
-
-},{"./sitewide":2}],2:[function(require,module,exports){
-'use strict';
-
-var url = require('url');
-var isValidUrl = require('valid-url').isWebUri;
-var isValidEmail = require('is-valid-email');
-
-var h = require('virtual-dom/h');
-var diff = require('virtual-dom/diff');
-var patch = require('virtual-dom/patch');
-var createElement = require('virtual-dom/create-element');
-
-var $ = window.$;
-var toastr = window.toastr;
-
-/* create-form validation for site-wide forms */
-module.exports = function sitewide() {
- var parentNode = $('#create-form .container');
- if (!parentNode.length) return;
-
- var formActionURL = parentNode.find('form').attr('action');
- var currentUserEmail = parentNode.find('[name="email"]').val();
- var emailPlaceholder = parentNode.find('[name="email"]').attr('placeholder');
- var urlPlaceholder = parentNode.find('[name="url"]').attr('placeholder');
- var sitewideHint = parentNode.find('label[data-hint]').data('hint');
-
- // since we have javascript, let's trash this HTML and recreate with virtual-dom
-
- var data = {
- invalid: null,
- sitewide: false,
- verified: false,
- email: currentUserEmail
- };
- var tree = render(data);
- var rootNode = createElement(tree);
- parentNode[0].replaceChild(rootNode, parentNode.find('form')[0]);
-
- parentNode.on('change', 'input[name="sitewide"]', run);
- parentNode.on('input', 'input[name="url"], input[name="email"]', run);
- parentNode.on('click', '.verify button', check);
-
- function run() {
- var checkbox = parentNode.find('input[name="sitewide"]');
-
- var email = parentNode.find('input[name="email"]').val().trim();
- var urlv = parentNode.find('input[name="url"]').val().trim();
- urlv = /^https?:\/\//.test(urlv) ? urlv : 'http://' + urlv;
- var sitewide = checkbox.is(':checked');
-
- // wrong input
- if (!isValidEmail(email)) {
- // invalid email
- data.invalid = 'email';
- } else if (sitewide && !isValidUrl(urlv)) {
- // invalid url with sitewide
- data.invalid = 'url';
- } else if (!sitewide && urlv && urlv !== 'http://' && !isValidUrl(urlv)) {
- // invalid url without sitewide
- data.invalid = 'url';
- } else {
- data.invalid = null;
- }
-
- data.sitewide = sitewide;
- data.urlv = urlv;
- data.email = email;
-
- apply(render(data));
- }
-
- function check() {
- $.ajax({
- url: '/forms/sitewide-check?' + parentNode.find('form').serialize(),
- success: function success() {
- toastr.success('The file exists! you can create your site-wide form now.');
- data.verified = true;
- apply(render(data));
- },
- error: function error() {
- toastr.warning("The verification file wasn't found.");
- data.verified = false;
- data.disableVerification = true;
- apply(render(data));
-
- setTimeout(function () {
- data.disableVerification = false;
- apply(render(data));
- }, 5000);
- }
- });
-
- return false;
- }
-
- function apply(vtree) {
- var patches = diff(tree, vtree);
- rootNode = patch(rootNode, patches);
- tree = vtree;
- }
-
- function render(_ref) {
- var invalid = _ref.invalid;
- var sitewide = _ref.sitewide;
- var verified = _ref.verified;
- var urlv = _ref.urlv;
- var email = _ref.email;
- var disableVerification = _ref.disableVerification;
-
- return h('form', { method: 'post', action: formActionURL }, [h('.col-1-1', [h('h4', 'Send email to:'), h('input', { type: 'email', name: 'email', placeholder: emailPlaceholder, value: email })]), h('.col-1-1', [h('h4', 'From URL:'), h('input', { type: 'text', name: 'url', placeholder: urlPlaceholder })]), h('.container', [h('.col-1-4', [h('label.hint--bottom', { dataset: { hint: sitewideHint } }, [h('input', { type: 'checkbox', name: 'sitewide', value: 'true' }), ' site-wide'])]), h('.col-3-4.info', [invalid ? h('div.red', invalid === 'email' ? 'Please input a valid email address.' : ['Please input a valid URL. For example: ', h('span.code', url.resolve('http://www.mywebsite.com', sitewide ? '' : '/contact.html'))]) : sitewide && verified || !sitewide ? h('div', { innerHTML: '' }) : h('span', ['Please ensure ', h('span.code', url.resolve(urlv, '/formspree-verify.txt')), ' exists and contains a line with ', h('span.code', email)])]), h('.col-1-3', [h('.verify', [h('button', sitewide && !invalid && !disableVerification ? {} : sitewide ? { disabled: true } : { style: { visibility: 'hidden' }, disabled: true }, 'Verify')])]), h('.col-1-3', { innerHTML: '' }), h('.col-1-3', [h('.create', [sitewide && verified || !sitewide && !invalid ? h('button', { type: 'submit' }, 'Create form') : h('button', { disabled: true }, 'Create form')])])])]);
- }
-};
-
-},{"is-valid-email":10,"url":15,"valid-url":17,"virtual-dom/create-element":18,"virtual-dom/diff":19,"virtual-dom/h":20,"virtual-dom/patch":21}],3:[function(require,module,exports){
-
-},{}],4:[function(require,module,exports){
-/*!
- * Cross-Browser Split 1.1.1
- * Copyright 2007-2012 Steven Levithan
- * Available under the MIT License
- * ECMAScript compliant, uniform cross-browser split method
- */
-
-/**
- * Splits a string into an array of strings using a regex or string separator. Matches of the
- * separator are not included in the result array. However, if `separator` is a regex that contains
- * capturing groups, backreferences are spliced into the result each time `separator` is matched.
- * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
- * cross-browser.
- * @param {String} str String to split.
- * @param {RegExp|String} separator Regex or string to use for separating the string.
- * @param {Number} [limit] Maximum number of items to include in the result array.
- * @returns {Array} Array of substrings.
- * @example
- *
- * // Basic use
- * split('a b c d', ' ');
- * // -> ['a', 'b', 'c', 'd']
- *
- * // With limit
- * split('a b c d', ' ', 2);
- * // -> ['a', 'b']
- *
- * // Backreferences in result array
- * split('..word1 word2..', /([a-z]+)(\d+)/i);
- * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
- */
-module.exports = (function split(undef) {
-
- var nativeSplit = String.prototype.split,
- compliantExecNpcg = /()??/.exec("")[1] === undef,
- // NPCG: nonparticipating capturing group
- self;
-
- self = function(str, separator, limit) {
- // If `separator` is not a regex, use `nativeSplit`
- if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
- return nativeSplit.call(str, separator, limit);
- }
- var output = [],
- flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6
- (separator.sticky ? "y" : ""),
- // Firefox 3+
- lastLastIndex = 0,
- // Make `global` and avoid `lastIndex` issues by working with a copy
- separator = new RegExp(separator.source, flags + "g"),
- separator2, match, lastIndex, lastLength;
- str += ""; // Type-convert
- if (!compliantExecNpcg) {
- // Doesn't need flags gy, but they don't hurt
- separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
- }
- /* Values for `limit`, per the spec:
- * If undefined: 4294967295 // Math.pow(2, 32) - 1
- * If 0, Infinity, or NaN: 0
- * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
- * If negative number: 4294967296 - Math.floor(Math.abs(limit))
- * If other: Type-convert, then use the above rules
- */
- limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1
- limit >>> 0; // ToUint32(limit)
- while (match = separator.exec(str)) {
- // `separator.lastIndex` is not reliable cross-browser
- lastIndex = match.index + match[0].length;
- if (lastIndex > lastLastIndex) {
- output.push(str.slice(lastLastIndex, match.index));
- // Fix browsers whose `exec` methods don't consistently return `undefined` for
- // nonparticipating capturing groups
- if (!compliantExecNpcg && match.length > 1) {
- match[0].replace(separator2, function() {
- for (var i = 1; i < arguments.length - 2; i++) {
- if (arguments[i] === undef) {
- match[i] = undef;
- }
- }
- });
- }
- if (match.length > 1 && match.index < str.length) {
- Array.prototype.push.apply(output, match.slice(1));
- }
- lastLength = match[0].length;
- lastLastIndex = lastIndex;
- if (output.length >= limit) {
- break;
- }
- }
- if (separator.lastIndex === match.index) {
- separator.lastIndex++; // Avoid an infinite loop
- }
- }
- if (lastLastIndex === str.length) {
- if (lastLength || !separator.test("")) {
- output.push("");
- }
- } else {
- output.push(str.slice(lastLastIndex));
- }
- return output.length > limit ? output.slice(0, limit) : output;
- };
-
- return self;
-})();
-
-},{}],5:[function(require,module,exports){
-'use strict';
-
-var OneVersionConstraint = require('individual/one-version');
-
-var MY_VERSION = '7';
-OneVersionConstraint('ev-store', MY_VERSION);
-
-var hashKey = '__EV_STORE_KEY@' + MY_VERSION;
-
-module.exports = EvStore;
-
-function EvStore(elem) {
- var hash = elem[hashKey];
-
- if (!hash) {
- hash = elem[hashKey] = {};
- }
-
- return hash;
-}
-
-},{"individual/one-version":8}],6:[function(require,module,exports){
-(function (global){
-var topLevel = typeof global !== 'undefined' ? global :
- typeof window !== 'undefined' ? window : {}
-var minDoc = require('min-document');
-
-if (typeof document !== 'undefined') {
- module.exports = document;
-} else {
- var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'];
-
- if (!doccy) {
- doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc;
- }
-
- module.exports = doccy;
-}
-
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"min-document":3}],7:[function(require,module,exports){
-(function (global){
-'use strict';
-
-/*global window, global*/
-
-var root = typeof window !== 'undefined' ?
- window : typeof global !== 'undefined' ?
- global : {};
-
-module.exports = Individual;
-
-function Individual(key, value) {
- if (key in root) {
- return root[key];
- }
-
- root[key] = value;
-
- return value;
-}
-
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],8:[function(require,module,exports){
-'use strict';
-
-var Individual = require('./index.js');
-
-module.exports = OneVersion;
-
-function OneVersion(moduleName, version, defaultValue) {
- var key = '__INDIVIDUAL_ONE_VERSION_' + moduleName;
- var enforceKey = key + '_ENFORCE_SINGLETON';
-
- var versionValue = Individual(enforceKey, version);
-
- if (versionValue !== version) {
- throw new Error('Can only have one copy of ' +
- moduleName + '.\n' +
- 'You already have version ' + versionValue +
- ' installed.\n' +
- 'This means you cannot install version ' + version);
- }
-
- return Individual(key, defaultValue);
-}
-
-},{"./index.js":7}],9:[function(require,module,exports){
-"use strict";
-
-module.exports = function isObject(x) {
- return typeof x === "object" && x !== null;
-};
-
-},{}],10:[function(require,module,exports){
-(function(){
-
- function isValidEmail(v) {
- if (!v) return false;
- var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
- return re.test(v);
- }
-
- if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
- module.exports = isValidEmail;
- } else {
- window.isValidEmail = isValidEmail;
- }
-
-})();
-
-},{}],11:[function(require,module,exports){
-(function (global){
-/*! https://mths.be/punycode v1.3.2 by @mathias */
-;(function(root) {
-
- /** Detect free variables */
- var freeExports = typeof exports == 'object' && exports &&
- !exports.nodeType && exports;
- var freeModule = typeof module == 'object' && module &&
- !module.nodeType && module;
- var freeGlobal = typeof global == 'object' && global;
- if (
- freeGlobal.global === freeGlobal ||
- freeGlobal.window === freeGlobal ||
- freeGlobal.self === freeGlobal
- ) {
- root = freeGlobal;
- }
-
- /**
- * The `punycode` object.
- * @name punycode
- * @type Object
- */
- var punycode,
-
- /** Highest positive signed 32-bit float value */
- maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
-
- /** Bootstring parameters */
- base = 36,
- tMin = 1,
- tMax = 26,
- skew = 38,
- damp = 700,
- initialBias = 72,
- initialN = 128, // 0x80
- delimiter = '-', // '\x2D'
-
- /** Regular expressions */
- regexPunycode = /^xn--/,
- regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
- regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
-
- /** Error messages */
- errors = {
- 'overflow': 'Overflow: input needs wider integers to process',
- 'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
- 'invalid-input': 'Invalid input'
- },
-
- /** Convenience shortcuts */
- baseMinusTMin = base - tMin,
- floor = Math.floor,
- stringFromCharCode = String.fromCharCode,
-
- /** Temporary variable */
- key;
-
- /*--------------------------------------------------------------------------*/
-
- /**
- * A generic error utility function.
- * @private
- * @param {String} type The error type.
- * @returns {Error} Throws a `RangeError` with the applicable error message.
- */
- function error(type) {
- throw RangeError(errors[type]);
- }
-
- /**
- * A generic `Array#map` utility function.
- * @private
- * @param {Array} array The array to iterate over.
- * @param {Function} callback The function that gets called for every array
- * item.
- * @returns {Array} A new array of values returned by the callback function.
- */
- function map(array, fn) {
- var length = array.length;
- var result = [];
- while (length--) {
- result[length] = fn(array[length]);
- }
- return result;
- }
-
- /**
- * A simple `Array#map`-like wrapper to work with domain name strings or email
- * addresses.
- * @private
- * @param {String} domain The domain name or email address.
- * @param {Function} callback The function that gets called for every
- * character.
- * @returns {Array} A new string of characters returned by the callback
- * function.
- */
- function mapDomain(string, fn) {
- var parts = string.split('@');
- var result = '';
- if (parts.length > 1) {
- // In email addresses, only the domain name should be punycoded. Leave
- // the local part (i.e. everything up to `@`) intact.
- result = parts[0] + '@';
- string = parts[1];
- }
- // Avoid `split(regex)` for IE8 compatibility. See #17.
- string = string.replace(regexSeparators, '\x2E');
- var labels = string.split('.');
- var encoded = map(labels, fn).join('.');
- return result + encoded;
- }
-
- /**
- * Creates an array containing the numeric code points of each Unicode
- * character in the string. While JavaScript uses UCS-2 internally,
- * this function will convert a pair of surrogate halves (each of which
- * UCS-2 exposes as separate characters) into a single code point,
- * matching UTF-16.
- * @see `punycode.ucs2.encode`
- * @see
- * @memberOf punycode.ucs2
- * @name decode
- * @param {String} string The Unicode input string (UCS-2).
- * @returns {Array} The new array of code points.
- */
- function ucs2decode(string) {
- var output = [],
- counter = 0,
- length = string.length,
- value,
- extra;
- while (counter < length) {
- value = string.charCodeAt(counter++);
- if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
- // high surrogate, and there is a next character
- extra = string.charCodeAt(counter++);
- if ((extra & 0xFC00) == 0xDC00) { // low surrogate
- output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
- } else {
- // unmatched surrogate; only append this code unit, in case the next
- // code unit is the high surrogate of a surrogate pair
- output.push(value);
- counter--;
- }
- } else {
- output.push(value);
- }
- }
- return output;
- }
-
- /**
- * Creates a string based on an array of numeric code points.
- * @see `punycode.ucs2.decode`
- * @memberOf punycode.ucs2
- * @name encode
- * @param {Array} codePoints The array of numeric code points.
- * @returns {String} The new Unicode string (UCS-2).
- */
- function ucs2encode(array) {
- return map(array, function(value) {
- var output = '';
- if (value > 0xFFFF) {
- value -= 0x10000;
- output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
- value = 0xDC00 | value & 0x3FF;
- }
- output += stringFromCharCode(value);
- return output;
- }).join('');
- }
-
- /**
- * Converts a basic code point into a digit/integer.
- * @see `digitToBasic()`
- * @private
- * @param {Number} codePoint The basic numeric code point value.
- * @returns {Number} The numeric value of a basic code point (for use in
- * representing integers) in the range `0` to `base - 1`, or `base` if
- * the code point does not represent a value.
- */
- function basicToDigit(codePoint) {
- if (codePoint - 48 < 10) {
- return codePoint - 22;
- }
- if (codePoint - 65 < 26) {
- return codePoint - 65;
- }
- if (codePoint - 97 < 26) {
- return codePoint - 97;
- }
- return base;
- }
-
- /**
- * Converts a digit/integer into a basic code point.
- * @see `basicToDigit()`
- * @private
- * @param {Number} digit The numeric value of a basic code point.
- * @returns {Number} The basic code point whose value (when used for
- * representing integers) is `digit`, which needs to be in the range
- * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
- * used; else, the lowercase form is used. The behavior is undefined
- * if `flag` is non-zero and `digit` has no uppercase form.
- */
- function digitToBasic(digit, flag) {
- // 0..25 map to ASCII a..z or A..Z
- // 26..35 map to ASCII 0..9
- return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
- }
-
- /**
- * Bias adaptation function as per section 3.4 of RFC 3492.
- * http://tools.ietf.org/html/rfc3492#section-3.4
- * @private
- */
- function adapt(delta, numPoints, firstTime) {
- var k = 0;
- delta = firstTime ? floor(delta / damp) : delta >> 1;
- delta += floor(delta / numPoints);
- for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
- delta = floor(delta / baseMinusTMin);
- }
- return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
- }
-
- /**
- * Converts a Punycode string of ASCII-only symbols to a string of Unicode
- * symbols.
- * @memberOf punycode
- * @param {String} input The Punycode string of ASCII-only symbols.
- * @returns {String} The resulting string of Unicode symbols.
- */
- function decode(input) {
- // Don't use UCS-2
- var output = [],
- inputLength = input.length,
- out,
- i = 0,
- n = initialN,
- bias = initialBias,
- basic,
- j,
- index,
- oldi,
- w,
- k,
- digit,
- t,
- /** Cached calculation results */
- baseMinusT;
-
- // Handle the basic code points: let `basic` be the number of input code
- // points before the last delimiter, or `0` if there is none, then copy
- // the first basic code points to the output.
-
- basic = input.lastIndexOf(delimiter);
- if (basic < 0) {
- basic = 0;
- }
-
- for (j = 0; j < basic; ++j) {
- // if it's not a basic code point
- if (input.charCodeAt(j) >= 0x80) {
- error('not-basic');
- }
- output.push(input.charCodeAt(j));
- }
-
- // Main decoding loop: start just after the last delimiter if any basic code
- // points were copied; start at the beginning otherwise.
-
- for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
-
- // `index` is the index of the next character to be consumed.
- // Decode a generalized variable-length integer into `delta`,
- // which gets added to `i`. The overflow checking is easier
- // if we increase `i` as we go, then subtract off its starting
- // value at the end to obtain `delta`.
- for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
-
- if (index >= inputLength) {
- error('invalid-input');
- }
-
- digit = basicToDigit(input.charCodeAt(index++));
-
- if (digit >= base || digit > floor((maxInt - i) / w)) {
- error('overflow');
- }
-
- i += digit * w;
- t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
-
- if (digit < t) {
- break;
- }
-
- baseMinusT = base - t;
- if (w > floor(maxInt / baseMinusT)) {
- error('overflow');
- }
-
- w *= baseMinusT;
-
- }
-
- out = output.length + 1;
- bias = adapt(i - oldi, out, oldi == 0);
-
- // `i` was supposed to wrap around from `out` to `0`,
- // incrementing `n` each time, so we'll fix that now:
- if (floor(i / out) > maxInt - n) {
- error('overflow');
- }
-
- n += floor(i / out);
- i %= out;
-
- // Insert `n` at position `i` of the output
- output.splice(i++, 0, n);
-
- }
-
- return ucs2encode(output);
- }
-
- /**
- * Converts a string of Unicode symbols (e.g. a domain name label) to a
- * Punycode string of ASCII-only symbols.
- * @memberOf punycode
- * @param {String} input The string of Unicode symbols.
- * @returns {String} The resulting Punycode string of ASCII-only symbols.
- */
- function encode(input) {
- var n,
- delta,
- handledCPCount,
- basicLength,
- bias,
- j,
- m,
- q,
- k,
- t,
- currentValue,
- output = [],
- /** `inputLength` will hold the number of code points in `input`. */
- inputLength,
- /** Cached calculation results */
- handledCPCountPlusOne,
- baseMinusT,
- qMinusT;
-
- // Convert the input in UCS-2 to Unicode
- input = ucs2decode(input);
-
- // Cache the length
- inputLength = input.length;
-
- // Initialize the state
- n = initialN;
- delta = 0;
- bias = initialBias;
-
- // Handle the basic code points
- for (j = 0; j < inputLength; ++j) {
- currentValue = input[j];
- if (currentValue < 0x80) {
- output.push(stringFromCharCode(currentValue));
- }
- }
-
- handledCPCount = basicLength = output.length;
-
- // `handledCPCount` is the number of code points that have been handled;
- // `basicLength` is the number of basic code points.
-
- // Finish the basic string - if it is not empty - with a delimiter
- if (basicLength) {
- output.push(delimiter);
- }
-
- // Main encoding loop:
- while (handledCPCount < inputLength) {
-
- // All non-basic code points < n have been handled already. Find the next
- // larger one:
- for (m = maxInt, j = 0; j < inputLength; ++j) {
- currentValue = input[j];
- if (currentValue >= n && currentValue < m) {
- m = currentValue;
- }
- }
-
- // Increase `delta` enough to advance the decoder's state to ,
- // but guard against overflow
- handledCPCountPlusOne = handledCPCount + 1;
- if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
- error('overflow');
- }
-
- delta += (m - n) * handledCPCountPlusOne;
- n = m;
-
- for (j = 0; j < inputLength; ++j) {
- currentValue = input[j];
-
- if (currentValue < n && ++delta > maxInt) {
- error('overflow');
- }
-
- if (currentValue == n) {
- // Represent delta as a generalized variable-length integer
- for (q = delta, k = base; /* no condition */; k += base) {
- t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
- if (q < t) {
- break;
- }
- qMinusT = q - t;
- baseMinusT = base - t;
- output.push(
- stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
- );
- q = floor(qMinusT / baseMinusT);
- }
-
- output.push(stringFromCharCode(digitToBasic(q, 0)));
- bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
- delta = 0;
- ++handledCPCount;
- }
- }
-
- ++delta;
- ++n;
-
- }
- return output.join('');
- }
-
- /**
- * Converts a Punycode string representing a domain name or an email address
- * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
- * it doesn't matter if you call it on a string that has already been
- * converted to Unicode.
- * @memberOf punycode
- * @param {String} input The Punycoded domain name or email address to
- * convert to Unicode.
- * @returns {String} The Unicode representation of the given Punycode
- * string.
- */
- function toUnicode(input) {
- return mapDomain(input, function(string) {
- return regexPunycode.test(string)
- ? decode(string.slice(4).toLowerCase())
- : string;
- });
- }
-
- /**
- * Converts a Unicode string representing a domain name or an email address to
- * Punycode. Only the non-ASCII parts of the domain name will be converted,
- * i.e. it doesn't matter if you call it with a domain that's already in
- * ASCII.
- * @memberOf punycode
- * @param {String} input The domain name or email address to convert, as a
- * Unicode string.
- * @returns {String} The Punycode representation of the given domain name or
- * email address.
- */
- function toASCII(input) {
- return mapDomain(input, function(string) {
- return regexNonASCII.test(string)
- ? 'xn--' + encode(string)
- : string;
- });
- }
-
- /*--------------------------------------------------------------------------*/
-
- /** Define the public API */
- punycode = {
- /**
- * A string representing the current Punycode.js version number.
- * @memberOf punycode
- * @type String
- */
- 'version': '1.3.2',
- /**
- * An object of methods to convert from JavaScript's internal character
- * representation (UCS-2) to Unicode code points, and back.
- * @see
- * @memberOf punycode
- * @type Object
- */
- 'ucs2': {
- 'decode': ucs2decode,
- 'encode': ucs2encode
- },
- 'decode': decode,
- 'encode': encode,
- 'toASCII': toASCII,
- 'toUnicode': toUnicode
- };
-
- /** Expose `punycode` */
- // Some AMD build optimizers, like r.js, check for specific condition patterns
- // like the following:
- if (
- typeof define == 'function' &&
- typeof define.amd == 'object' &&
- define.amd
- ) {
- define('punycode', function() {
- return punycode;
- });
- } else if (freeExports && freeModule) {
- if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
- freeModule.exports = punycode;
- } else { // in Narwhal or RingoJS v0.7.0-
- for (key in punycode) {
- punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
- }
- }
- } else { // in Rhino or a web browser
- root.punycode = punycode;
- }
-
-}(this));
-
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],12:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'use strict';
-
-// If obj.hasOwnProperty has been overridden, then calling
-// obj.hasOwnProperty(prop) will break.
-// See: https://github.com/joyent/node/issues/1707
-function hasOwnProperty(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-}
-
-module.exports = function(qs, sep, eq, options) {
- sep = sep || '&';
- eq = eq || '=';
- var obj = {};
-
- if (typeof qs !== 'string' || qs.length === 0) {
- return obj;
- }
-
- var regexp = /\+/g;
- qs = qs.split(sep);
-
- var maxKeys = 1000;
- if (options && typeof options.maxKeys === 'number') {
- maxKeys = options.maxKeys;
- }
-
- var len = qs.length;
- // maxKeys <= 0 means that we should not limit keys count
- if (maxKeys > 0 && len > maxKeys) {
- len = maxKeys;
- }
-
- for (var i = 0; i < len; ++i) {
- var x = qs[i].replace(regexp, '%20'),
- idx = x.indexOf(eq),
- kstr, vstr, k, v;
-
- if (idx >= 0) {
- kstr = x.substr(0, idx);
- vstr = x.substr(idx + 1);
- } else {
- kstr = x;
- vstr = '';
- }
-
- k = decodeURIComponent(kstr);
- v = decodeURIComponent(vstr);
-
- if (!hasOwnProperty(obj, k)) {
- obj[k] = v;
- } else if (isArray(obj[k])) {
- obj[k].push(v);
- } else {
- obj[k] = [obj[k], v];
- }
- }
-
- return obj;
-};
-
-var isArray = Array.isArray || function (xs) {
- return Object.prototype.toString.call(xs) === '[object Array]';
-};
-
-},{}],13:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'use strict';
-
-var stringifyPrimitive = function(v) {
- switch (typeof v) {
- case 'string':
- return v;
-
- case 'boolean':
- return v ? 'true' : 'false';
-
- case 'number':
- return isFinite(v) ? v : '';
-
- default:
- return '';
- }
-};
-
-module.exports = function(obj, sep, eq, name) {
- sep = sep || '&';
- eq = eq || '=';
- if (obj === null) {
- obj = undefined;
- }
-
- if (typeof obj === 'object') {
- return map(objectKeys(obj), function(k) {
- var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
- if (isArray(obj[k])) {
- return map(obj[k], function(v) {
- return ks + encodeURIComponent(stringifyPrimitive(v));
- }).join(sep);
- } else {
- return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
- }
- }).join(sep);
-
- }
-
- if (!name) return '';
- return encodeURIComponent(stringifyPrimitive(name)) + eq +
- encodeURIComponent(stringifyPrimitive(obj));
-};
-
-var isArray = Array.isArray || function (xs) {
- return Object.prototype.toString.call(xs) === '[object Array]';
-};
-
-function map (xs, f) {
- if (xs.map) return xs.map(f);
- var res = [];
- for (var i = 0; i < xs.length; i++) {
- res.push(f(xs[i], i));
- }
- return res;
-}
-
-var objectKeys = Object.keys || function (obj) {
- var res = [];
- for (var key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
- }
- return res;
-};
-
-},{}],14:[function(require,module,exports){
-'use strict';
-
-exports.decode = exports.parse = require('./decode');
-exports.encode = exports.stringify = require('./encode');
-
-},{"./decode":12,"./encode":13}],15:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'use strict';
-
-var punycode = require('punycode');
-var util = require('./util');
-
-exports.parse = urlParse;
-exports.resolve = urlResolve;
-exports.resolveObject = urlResolveObject;
-exports.format = urlFormat;
-
-exports.Url = Url;
-
-function Url() {
- this.protocol = null;
- this.slashes = null;
- this.auth = null;
- this.host = null;
- this.port = null;
- this.hostname = null;
- this.hash = null;
- this.search = null;
- this.query = null;
- this.pathname = null;
- this.path = null;
- this.href = null;
-}
-
-// Reference: RFC 3986, RFC 1808, RFC 2396
-
-// define these here so at least they only have to be
-// compiled once on the first module load.
-var protocolPattern = /^([a-z0-9.+-]+:)/i,
- portPattern = /:[0-9]*$/,
-
- // Special case for a simple path URL
- simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
-
- // RFC 2396: characters reserved for delimiting URLs.
- // We actually just auto-escape these.
- delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
-
- // RFC 2396: characters not allowed for various reasons.
- unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
-
- // Allowed by RFCs, but cause of XSS attacks. Always escape these.
- autoEscape = ['\''].concat(unwise),
- // Characters that are never ever allowed in a hostname.
- // Note that any invalid chars are also handled, but these
- // are the ones that are *expected* to be seen, so we fast-path
- // them.
- nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
- hostEndingChars = ['/', '?', '#'],
- hostnameMaxLen = 255,
- hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
- hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
- // protocols that can allow "unsafe" and "unwise" chars.
- unsafeProtocol = {
- 'javascript': true,
- 'javascript:': true
- },
- // protocols that never have a hostname.
- hostlessProtocol = {
- 'javascript': true,
- 'javascript:': true
- },
- // protocols that always contain a // bit.
- slashedProtocol = {
- 'http': true,
- 'https': true,
- 'ftp': true,
- 'gopher': true,
- 'file': true,
- 'http:': true,
- 'https:': true,
- 'ftp:': true,
- 'gopher:': true,
- 'file:': true
- },
- querystring = require('querystring');
-
-function urlParse(url, parseQueryString, slashesDenoteHost) {
- if (url && util.isObject(url) && url instanceof Url) return url;
-
- var u = new Url;
- u.parse(url, parseQueryString, slashesDenoteHost);
- return u;
-}
-
-Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
- if (!util.isString(url)) {
- throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
- }
-
- // Copy chrome, IE, opera backslash-handling behavior.
- // Back slashes before the query string get converted to forward slashes
- // See: https://code.google.com/p/chromium/issues/detail?id=25916
- var queryIndex = url.indexOf('?'),
- splitter =
- (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
- uSplit = url.split(splitter),
- slashRegex = /\\/g;
- uSplit[0] = uSplit[0].replace(slashRegex, '/');
- url = uSplit.join(splitter);
-
- var rest = url;
-
- // trim before proceeding.
- // This is to support parse stuff like " http://foo.com \n"
- rest = rest.trim();
-
- if (!slashesDenoteHost && url.split('#').length === 1) {
- // Try fast path regexp
- var simplePath = simplePathPattern.exec(rest);
- if (simplePath) {
- this.path = rest;
- this.href = rest;
- this.pathname = simplePath[1];
- if (simplePath[2]) {
- this.search = simplePath[2];
- if (parseQueryString) {
- this.query = querystring.parse(this.search.substr(1));
- } else {
- this.query = this.search.substr(1);
- }
- } else if (parseQueryString) {
- this.search = '';
- this.query = {};
- }
- return this;
- }
- }
-
- var proto = protocolPattern.exec(rest);
- if (proto) {
- proto = proto[0];
- var lowerProto = proto.toLowerCase();
- this.protocol = lowerProto;
- rest = rest.substr(proto.length);
- }
-
- // figure out if it's got a host
- // user@server is *always* interpreted as a hostname, and url
- // resolution will treat //foo/bar as host=foo,path=bar because that's
- // how the browser resolves relative URLs.
- if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
- var slashes = rest.substr(0, 2) === '//';
- if (slashes && !(proto && hostlessProtocol[proto])) {
- rest = rest.substr(2);
- this.slashes = true;
- }
- }
-
- if (!hostlessProtocol[proto] &&
- (slashes || (proto && !slashedProtocol[proto]))) {
-
- // there's a hostname.
- // the first instance of /, ?, ;, or # ends the host.
- //
- // If there is an @ in the hostname, then non-host chars *are* allowed
- // to the left of the last @ sign, unless some host-ending character
- // comes *before* the @-sign.
- // URLs are obnoxious.
- //
- // ex:
- // http://a@b@c/ => user:a@b host:c
- // http://a@b?@c => user:a host:c path:/?@c
-
- // v0.12 TODO(isaacs): This is not quite how Chrome does things.
- // Review our test case against browsers more comprehensively.
-
- // find the first instance of any hostEndingChars
- var hostEnd = -1;
- for (var i = 0; i < hostEndingChars.length; i++) {
- var hec = rest.indexOf(hostEndingChars[i]);
- if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
- hostEnd = hec;
- }
-
- // at this point, either we have an explicit point where the
- // auth portion cannot go past, or the last @ char is the decider.
- var auth, atSign;
- if (hostEnd === -1) {
- // atSign can be anywhere.
- atSign = rest.lastIndexOf('@');
- } else {
- // atSign must be in auth portion.
- // http://a@b/c@d => host:b auth:a path:/c@d
- atSign = rest.lastIndexOf('@', hostEnd);
- }
-
- // Now we have a portion which is definitely the auth.
- // Pull that off.
- if (atSign !== -1) {
- auth = rest.slice(0, atSign);
- rest = rest.slice(atSign + 1);
- this.auth = decodeURIComponent(auth);
- }
-
- // the host is the remaining to the left of the first non-host char
- hostEnd = -1;
- for (var i = 0; i < nonHostChars.length; i++) {
- var hec = rest.indexOf(nonHostChars[i]);
- if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
- hostEnd = hec;
- }
- // if we still have not hit it, then the entire thing is a host.
- if (hostEnd === -1)
- hostEnd = rest.length;
-
- this.host = rest.slice(0, hostEnd);
- rest = rest.slice(hostEnd);
-
- // pull out port.
- this.parseHost();
-
- // we've indicated that there is a hostname,
- // so even if it's empty, it has to be present.
- this.hostname = this.hostname || '';
-
- // if hostname begins with [ and ends with ]
- // assume that it's an IPv6 address.
- var ipv6Hostname = this.hostname[0] === '[' &&
- this.hostname[this.hostname.length - 1] === ']';
-
- // validate a little.
- if (!ipv6Hostname) {
- var hostparts = this.hostname.split(/\./);
- for (var i = 0, l = hostparts.length; i < l; i++) {
- var part = hostparts[i];
- if (!part) continue;
- if (!part.match(hostnamePartPattern)) {
- var newpart = '';
- for (var j = 0, k = part.length; j < k; j++) {
- if (part.charCodeAt(j) > 127) {
- // we replace non-ASCII char with a temporary placeholder
- // we need this to make sure size of hostname is not
- // broken by replacing non-ASCII by nothing
- newpart += 'x';
- } else {
- newpart += part[j];
- }
- }
- // we test again with ASCII char only
- if (!newpart.match(hostnamePartPattern)) {
- var validParts = hostparts.slice(0, i);
- var notHost = hostparts.slice(i + 1);
- var bit = part.match(hostnamePartStart);
- if (bit) {
- validParts.push(bit[1]);
- notHost.unshift(bit[2]);
- }
- if (notHost.length) {
- rest = '/' + notHost.join('.') + rest;
- }
- this.hostname = validParts.join('.');
- break;
- }
- }
- }
- }
-
- if (this.hostname.length > hostnameMaxLen) {
- this.hostname = '';
- } else {
- // hostnames are always lower case.
- this.hostname = this.hostname.toLowerCase();
- }
-
- if (!ipv6Hostname) {
- // IDNA Support: Returns a punycoded representation of "domain".
- // It only converts parts of the domain name that
- // have non-ASCII characters, i.e. it doesn't matter if
- // you call it with a domain that already is ASCII-only.
- this.hostname = punycode.toASCII(this.hostname);
- }
-
- var p = this.port ? ':' + this.port : '';
- var h = this.hostname || '';
- this.host = h + p;
- this.href += this.host;
-
- // strip [ and ] from the hostname
- // the host field still retains them, though
- if (ipv6Hostname) {
- this.hostname = this.hostname.substr(1, this.hostname.length - 2);
- if (rest[0] !== '/') {
- rest = '/' + rest;
- }
- }
- }
-
- // now rest is set to the post-host stuff.
- // chop off any delim chars.
- if (!unsafeProtocol[lowerProto]) {
-
- // First, make 100% sure that any "autoEscape" chars get
- // escaped, even if encodeURIComponent doesn't think they
- // need to be.
- for (var i = 0, l = autoEscape.length; i < l; i++) {
- var ae = autoEscape[i];
- if (rest.indexOf(ae) === -1)
- continue;
- var esc = encodeURIComponent(ae);
- if (esc === ae) {
- esc = escape(ae);
- }
- rest = rest.split(ae).join(esc);
- }
- }
-
-
- // chop off from the tail first.
- var hash = rest.indexOf('#');
- if (hash !== -1) {
- // got a fragment string.
- this.hash = rest.substr(hash);
- rest = rest.slice(0, hash);
- }
- var qm = rest.indexOf('?');
- if (qm !== -1) {
- this.search = rest.substr(qm);
- this.query = rest.substr(qm + 1);
- if (parseQueryString) {
- this.query = querystring.parse(this.query);
- }
- rest = rest.slice(0, qm);
- } else if (parseQueryString) {
- // no query string, but parseQueryString still requested
- this.search = '';
- this.query = {};
- }
- if (rest) this.pathname = rest;
- if (slashedProtocol[lowerProto] &&
- this.hostname && !this.pathname) {
- this.pathname = '/';
- }
-
- //to support http.request
- if (this.pathname || this.search) {
- var p = this.pathname || '';
- var s = this.search || '';
- this.path = p + s;
- }
-
- // finally, reconstruct the href based on what has been validated.
- this.href = this.format();
- return this;
-};
-
-// format a parsed object into a url string
-function urlFormat(obj) {
- // ensure it's an object, and not a string url.
- // If it's an obj, this is a no-op.
- // this way, you can call url_format() on strings
- // to clean up potentially wonky urls.
- if (util.isString(obj)) obj = urlParse(obj);
- if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
- return obj.format();
-}
-
-Url.prototype.format = function() {
- var auth = this.auth || '';
- if (auth) {
- auth = encodeURIComponent(auth);
- auth = auth.replace(/%3A/i, ':');
- auth += '@';
- }
-
- var protocol = this.protocol || '',
- pathname = this.pathname || '',
- hash = this.hash || '',
- host = false,
- query = '';
-
- if (this.host) {
- host = auth + this.host;
- } else if (this.hostname) {
- host = auth + (this.hostname.indexOf(':') === -1 ?
- this.hostname :
- '[' + this.hostname + ']');
- if (this.port) {
- host += ':' + this.port;
- }
- }
-
- if (this.query &&
- util.isObject(this.query) &&
- Object.keys(this.query).length) {
- query = querystring.stringify(this.query);
- }
-
- var search = this.search || (query && ('?' + query)) || '';
-
- if (protocol && protocol.substr(-1) !== ':') protocol += ':';
-
- // only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
- // unless they had them to begin with.
- if (this.slashes ||
- (!protocol || slashedProtocol[protocol]) && host !== false) {
- host = '//' + (host || '');
- if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
- } else if (!host) {
- host = '';
- }
-
- if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
- if (search && search.charAt(0) !== '?') search = '?' + search;
-
- pathname = pathname.replace(/[?#]/g, function(match) {
- return encodeURIComponent(match);
- });
- search = search.replace('#', '%23');
-
- return protocol + host + pathname + search + hash;
-};
-
-function urlResolve(source, relative) {
- return urlParse(source, false, true).resolve(relative);
-}
-
-Url.prototype.resolve = function(relative) {
- return this.resolveObject(urlParse(relative, false, true)).format();
-};
-
-function urlResolveObject(source, relative) {
- if (!source) return relative;
- return urlParse(source, false, true).resolveObject(relative);
-}
-
-Url.prototype.resolveObject = function(relative) {
- if (util.isString(relative)) {
- var rel = new Url();
- rel.parse(relative, false, true);
- relative = rel;
- }
-
- var result = new Url();
- var tkeys = Object.keys(this);
- for (var tk = 0; tk < tkeys.length; tk++) {
- var tkey = tkeys[tk];
- result[tkey] = this[tkey];
- }
-
- // hash is always overridden, no matter what.
- // even href="" will remove it.
- result.hash = relative.hash;
-
- // if the relative url is empty, then there's nothing left to do here.
- if (relative.href === '') {
- result.href = result.format();
- return result;
- }
-
- // hrefs like //foo/bar always cut to the protocol.
- if (relative.slashes && !relative.protocol) {
- // take everything except the protocol from relative
- var rkeys = Object.keys(relative);
- for (var rk = 0; rk < rkeys.length; rk++) {
- var rkey = rkeys[rk];
- if (rkey !== 'protocol')
- result[rkey] = relative[rkey];
- }
-
- //urlParse appends trailing / to urls like http://www.example.com
- if (slashedProtocol[result.protocol] &&
- result.hostname && !result.pathname) {
- result.path = result.pathname = '/';
- }
-
- result.href = result.format();
- return result;
- }
-
- if (relative.protocol && relative.protocol !== result.protocol) {
- // if it's a known url protocol, then changing
- // the protocol does weird things
- // first, if it's not file:, then we MUST have a host,
- // and if there was a path
- // to begin with, then we MUST have a path.
- // if it is file:, then the host is dropped,
- // because that's known to be hostless.
- // anything else is assumed to be absolute.
- if (!slashedProtocol[relative.protocol]) {
- var keys = Object.keys(relative);
- for (var v = 0; v < keys.length; v++) {
- var k = keys[v];
- result[k] = relative[k];
- }
- result.href = result.format();
- return result;
- }
-
- result.protocol = relative.protocol;
- if (!relative.host && !hostlessProtocol[relative.protocol]) {
- var relPath = (relative.pathname || '').split('/');
- while (relPath.length && !(relative.host = relPath.shift()));
- if (!relative.host) relative.host = '';
- if (!relative.hostname) relative.hostname = '';
- if (relPath[0] !== '') relPath.unshift('');
- if (relPath.length < 2) relPath.unshift('');
- result.pathname = relPath.join('/');
- } else {
- result.pathname = relative.pathname;
- }
- result.search = relative.search;
- result.query = relative.query;
- result.host = relative.host || '';
- result.auth = relative.auth;
- result.hostname = relative.hostname || relative.host;
- result.port = relative.port;
- // to support http.request
- if (result.pathname || result.search) {
- var p = result.pathname || '';
- var s = result.search || '';
- result.path = p + s;
- }
- result.slashes = result.slashes || relative.slashes;
- result.href = result.format();
- return result;
- }
-
- var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
- isRelAbs = (
- relative.host ||
- relative.pathname && relative.pathname.charAt(0) === '/'
- ),
- mustEndAbs = (isRelAbs || isSourceAbs ||
- (result.host && relative.pathname)),
- removeAllDots = mustEndAbs,
- srcPath = result.pathname && result.pathname.split('/') || [],
- relPath = relative.pathname && relative.pathname.split('/') || [],
- psychotic = result.protocol && !slashedProtocol[result.protocol];
-
- // if the url is a non-slashed url, then relative
- // links like ../.. should be able
- // to crawl up to the hostname, as well. This is strange.
- // result.protocol has already been set by now.
- // Later on, put the first path part into the host field.
- if (psychotic) {
- result.hostname = '';
- result.port = null;
- if (result.host) {
- if (srcPath[0] === '') srcPath[0] = result.host;
- else srcPath.unshift(result.host);
- }
- result.host = '';
- if (relative.protocol) {
- relative.hostname = null;
- relative.port = null;
- if (relative.host) {
- if (relPath[0] === '') relPath[0] = relative.host;
- else relPath.unshift(relative.host);
- }
- relative.host = null;
- }
- mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
- }
-
- if (isRelAbs) {
- // it's absolute.
- result.host = (relative.host || relative.host === '') ?
- relative.host : result.host;
- result.hostname = (relative.hostname || relative.hostname === '') ?
- relative.hostname : result.hostname;
- result.search = relative.search;
- result.query = relative.query;
- srcPath = relPath;
- // fall through to the dot-handling below.
- } else if (relPath.length) {
- // it's relative
- // throw away the existing file, and take the new path instead.
- if (!srcPath) srcPath = [];
- srcPath.pop();
- srcPath = srcPath.concat(relPath);
- result.search = relative.search;
- result.query = relative.query;
- } else if (!util.isNullOrUndefined(relative.search)) {
- // just pull out the search.
- // like href='?foo'.
- // Put this after the other two cases because it simplifies the booleans
- if (psychotic) {
- result.hostname = result.host = srcPath.shift();
- //occationaly the auth can get stuck only in host
- //this especially happens in cases like
- //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
- var authInHost = result.host && result.host.indexOf('@') > 0 ?
- result.host.split('@') : false;
- if (authInHost) {
- result.auth = authInHost.shift();
- result.host = result.hostname = authInHost.shift();
- }
- }
- result.search = relative.search;
- result.query = relative.query;
- //to support http.request
- if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
- result.path = (result.pathname ? result.pathname : '') +
- (result.search ? result.search : '');
- }
- result.href = result.format();
- return result;
- }
-
- if (!srcPath.length) {
- // no path at all. easy.
- // we've already handled the other stuff above.
- result.pathname = null;
- //to support http.request
- if (result.search) {
- result.path = '/' + result.search;
- } else {
- result.path = null;
- }
- result.href = result.format();
- return result;
- }
-
- // if a url ENDs in . or .., then it must get a trailing slash.
- // however, if it ends in anything else non-slashy,
- // then it must NOT get a trailing slash.
- var last = srcPath.slice(-1)[0];
- var hasTrailingSlash = (
- (result.host || relative.host || srcPath.length > 1) &&
- (last === '.' || last === '..') || last === '');
-
- // strip single dots, resolve double dots to parent dir
- // if the path tries to go above the root, `up` ends up > 0
- var up = 0;
- for (var i = srcPath.length; i >= 0; i--) {
- last = srcPath[i];
- if (last === '.') {
- srcPath.splice(i, 1);
- } else if (last === '..') {
- srcPath.splice(i, 1);
- up++;
- } else if (up) {
- srcPath.splice(i, 1);
- up--;
- }
- }
-
- // if the path is allowed to go above the root, restore leading ..s
- if (!mustEndAbs && !removeAllDots) {
- for (; up--; up) {
- srcPath.unshift('..');
- }
- }
-
- if (mustEndAbs && srcPath[0] !== '' &&
- (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
- srcPath.unshift('');
- }
-
- if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
- srcPath.push('');
- }
-
- var isAbsolute = srcPath[0] === '' ||
- (srcPath[0] && srcPath[0].charAt(0) === '/');
-
- // put the host back
- if (psychotic) {
- result.hostname = result.host = isAbsolute ? '' :
- srcPath.length ? srcPath.shift() : '';
- //occationaly the auth can get stuck only in host
- //this especially happens in cases like
- //url.resolveObject('mailto:local1@domain1', 'local2@domain2')
- var authInHost = result.host && result.host.indexOf('@') > 0 ?
- result.host.split('@') : false;
- if (authInHost) {
- result.auth = authInHost.shift();
- result.host = result.hostname = authInHost.shift();
- }
- }
-
- mustEndAbs = mustEndAbs || (result.host && srcPath.length);
-
- if (mustEndAbs && !isAbsolute) {
- srcPath.unshift('');
- }
-
- if (!srcPath.length) {
- result.pathname = null;
- result.path = null;
- } else {
- result.pathname = srcPath.join('/');
- }
-
- //to support request.http
- if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
- result.path = (result.pathname ? result.pathname : '') +
- (result.search ? result.search : '');
- }
- result.auth = relative.auth || result.auth;
- result.slashes = result.slashes || relative.slashes;
- result.href = result.format();
- return result;
-};
-
-Url.prototype.parseHost = function() {
- var host = this.host;
- var port = portPattern.exec(host);
- if (port) {
- port = port[0];
- if (port !== ':') {
- this.port = port.substr(1);
- }
- host = host.substr(0, host.length - port.length);
- }
- if (host) this.hostname = host;
-};
-
-},{"./util":16,"punycode":11,"querystring":14}],16:[function(require,module,exports){
-'use strict';
-
-module.exports = {
- isString: function(arg) {
- return typeof(arg) === 'string';
- },
- isObject: function(arg) {
- return typeof(arg) === 'object' && arg !== null;
- },
- isNull: function(arg) {
- return arg === null;
- },
- isNullOrUndefined: function(arg) {
- return arg == null;
- }
-};
-
-},{}],17:[function(require,module,exports){
-(function(module) {
- 'use strict';
-
- module.exports.is_uri = is_iri;
- module.exports.is_http_uri = is_http_iri;
- module.exports.is_https_uri = is_https_iri;
- module.exports.is_web_uri = is_web_iri;
- // Create aliases
- module.exports.isUri = is_iri;
- module.exports.isHttpUri = is_http_iri;
- module.exports.isHttpsUri = is_https_iri;
- module.exports.isWebUri = is_web_iri;
-
-
- // private function
- // internal URI spitter method - direct from RFC 3986
- var splitUri = function(uri) {
- var splitted = uri.match(/(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);
- return splitted;
- };
-
- function is_iri(value) {
- if (!value) {
- return;
- }
-
- // check for illegal characters
- if (/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i.test(value)) return;
-
- // check for hex escapes that aren't complete
- if (/%[^0-9a-f]/i.test(value)) return;
- if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value)) return;
-
- var splitted = [];
- var scheme = '';
- var authority = '';
- var path = '';
- var query = '';
- var fragment = '';
- var out = '';
-
- // from RFC 3986
- splitted = splitUri(value);
- scheme = splitted[1];
- authority = splitted[2];
- path = splitted[3];
- query = splitted[4];
- fragment = splitted[5];
-
- // scheme and path are required, though the path can be empty
- if (!(scheme && scheme.length && path.length >= 0)) return;
-
- // if authority is present, the path must be empty or begin with a /
- if (authority && authority.length) {
- if (!(path.length === 0 || /^\//.test(path))) return;
- } else {
- // if authority is not present, the path must not start with //
- if (/^\/\//.test(path)) return;
- }
-
- // scheme must begin with a letter, then consist of letters, digits, +, ., or -
- if (!/^[a-z][a-z0-9\+\-\.]*$/.test(scheme.toLowerCase())) return;
-
- // re-assemble the URL per section 5.3 in RFC 3986
- out += scheme + ':';
- if (authority && authority.length) {
- out += '//' + authority;
- }
-
- out += path;
-
- if (query && query.length) {
- out += '?' + query;
- }
-
- if (fragment && fragment.length) {
- out += '#' + fragment;
- }
-
- return out;
- }
-
- function is_http_iri(value, allowHttps) {
- if (!is_iri(value)) {
- return;
- }
-
- var splitted = [];
- var scheme = '';
- var authority = '';
- var path = '';
- var port = '';
- var query = '';
- var fragment = '';
- var out = '';
-
- // from RFC 3986
- splitted = splitUri(value);
- scheme = splitted[1];
- authority = splitted[2];
- path = splitted[3];
- query = splitted[4];
- fragment = splitted[5];
-
- if (!scheme) return;
-
- if(allowHttps) {
- if (scheme.toLowerCase() != 'https') return;
- } else {
- if (scheme.toLowerCase() != 'http') return;
- }
-
- // fully-qualified URIs must have an authority section that is
- // a valid host
- if (!authority) {
- return;
- }
-
- // enable port component
- if (/:(\d+)$/.test(authority)) {
- port = authority.match(/:(\d+)$/)[0];
- authority = authority.replace(/:\d+$/, '');
- }
-
- out += scheme + ':';
- out += '//' + authority;
-
- if (port) {
- out += port;
- }
-
- out += path;
-
- if(query && query.length){
- out += '?' + query;
- }
-
- if(fragment && fragment.length){
- out += '#' + fragment;
- }
-
- return out;
- }
-
- function is_https_iri(value) {
- return is_http_iri(value, true);
- }
-
- function is_web_iri(value) {
- return (is_http_iri(value) || is_https_iri(value));
- }
-
-})(module);
-
-},{}],18:[function(require,module,exports){
-var createElement = require("./vdom/create-element.js")
-
-module.exports = createElement
-
-},{"./vdom/create-element.js":23}],19:[function(require,module,exports){
-var diff = require("./vtree/diff.js")
-
-module.exports = diff
-
-},{"./vtree/diff.js":43}],20:[function(require,module,exports){
-var h = require("./virtual-hyperscript/index.js")
-
-module.exports = h
-
-},{"./virtual-hyperscript/index.js":30}],21:[function(require,module,exports){
-var patch = require("./vdom/patch.js")
-
-module.exports = patch
-
-},{"./vdom/patch.js":26}],22:[function(require,module,exports){
-var isObject = require("is-object")
-var isHook = require("../vnode/is-vhook.js")
-
-module.exports = applyProperties
-
-function applyProperties(node, props, previous) {
- for (var propName in props) {
- var propValue = props[propName]
-
- if (propValue === undefined) {
- removeProperty(node, propName, propValue, previous);
- } else if (isHook(propValue)) {
- removeProperty(node, propName, propValue, previous)
- if (propValue.hook) {
- propValue.hook(node,
- propName,
- previous ? previous[propName] : undefined)
- }
- } else {
- if (isObject(propValue)) {
- patchObject(node, props, previous, propName, propValue);
- } else {
- node[propName] = propValue
- }
- }
- }
-}
-
-function removeProperty(node, propName, propValue, previous) {
- if (previous) {
- var previousValue = previous[propName]
-
- if (!isHook(previousValue)) {
- if (propName === "attributes") {
- for (var attrName in previousValue) {
- node.removeAttribute(attrName)
- }
- } else if (propName === "style") {
- for (var i in previousValue) {
- node.style[i] = ""
- }
- } else if (typeof previousValue === "string") {
- node[propName] = ""
- } else {
- node[propName] = null
- }
- } else if (previousValue.unhook) {
- previousValue.unhook(node, propName, propValue)
- }
- }
-}
-
-function patchObject(node, props, previous, propName, propValue) {
- var previousValue = previous ? previous[propName] : undefined
-
- // Set attributes
- if (propName === "attributes") {
- for (var attrName in propValue) {
- var attrValue = propValue[attrName]
-
- if (attrValue === undefined) {
- node.removeAttribute(attrName)
- } else {
- node.setAttribute(attrName, attrValue)
- }
- }
-
- return
- }
-
- if(previousValue && isObject(previousValue) &&
- getPrototype(previousValue) !== getPrototype(propValue)) {
- node[propName] = propValue
- return
- }
-
- if (!isObject(node[propName])) {
- node[propName] = {}
- }
-
- var replacer = propName === "style" ? "" : undefined
-
- for (var k in propValue) {
- var value = propValue[k]
- node[propName][k] = (value === undefined) ? replacer : value
- }
-}
-
-function getPrototype(value) {
- if (Object.getPrototypeOf) {
- return Object.getPrototypeOf(value)
- } else if (value.__proto__) {
- return value.__proto__
- } else if (value.constructor) {
- return value.constructor.prototype
- }
-}
-
-},{"../vnode/is-vhook.js":34,"is-object":9}],23:[function(require,module,exports){
-var document = require("global/document")
-
-var applyProperties = require("./apply-properties")
-
-var isVNode = require("../vnode/is-vnode.js")
-var isVText = require("../vnode/is-vtext.js")
-var isWidget = require("../vnode/is-widget.js")
-var handleThunk = require("../vnode/handle-thunk.js")
-
-module.exports = createElement
-
-function createElement(vnode, opts) {
- var doc = opts ? opts.document || document : document
- var warn = opts ? opts.warn : null
-
- vnode = handleThunk(vnode).a
-
- if (isWidget(vnode)) {
- return vnode.init()
- } else if (isVText(vnode)) {
- return doc.createTextNode(vnode.text)
- } else if (!isVNode(vnode)) {
- if (warn) {
- warn("Item is not a valid virtual dom node", vnode)
- }
- return null
- }
-
- var node = (vnode.namespace === null) ?
- doc.createElement(vnode.tagName) :
- doc.createElementNS(vnode.namespace, vnode.tagName)
-
- var props = vnode.properties
- applyProperties(node, props)
-
- var children = vnode.children
-
- for (var i = 0; i < children.length; i++) {
- var childNode = createElement(children[i], opts)
- if (childNode) {
- node.appendChild(childNode)
- }
- }
-
- return node
-}
-
-},{"../vnode/handle-thunk.js":32,"../vnode/is-vnode.js":35,"../vnode/is-vtext.js":36,"../vnode/is-widget.js":37,"./apply-properties":22,"global/document":6}],24:[function(require,module,exports){
-// Maps a virtual DOM tree onto a real DOM tree in an efficient manner.
-// We don't want to read all of the DOM nodes in the tree so we use
-// the in-order tree indexing to eliminate recursion down certain branches.
-// We only recurse into a DOM node if we know that it contains a child of
-// interest.
-
-var noChild = {}
-
-module.exports = domIndex
-
-function domIndex(rootNode, tree, indices, nodes) {
- if (!indices || indices.length === 0) {
- return {}
- } else {
- indices.sort(ascending)
- return recurse(rootNode, tree, indices, nodes, 0)
- }
-}
-
-function recurse(rootNode, tree, indices, nodes, rootIndex) {
- nodes = nodes || {}
-
-
- if (rootNode) {
- if (indexInRange(indices, rootIndex, rootIndex)) {
- nodes[rootIndex] = rootNode
- }
-
- var vChildren = tree.children
-
- if (vChildren) {
-
- var childNodes = rootNode.childNodes
-
- for (var i = 0; i < tree.children.length; i++) {
- rootIndex += 1
-
- var vChild = vChildren[i] || noChild
- var nextIndex = rootIndex + (vChild.count || 0)
-
- // skip recursion down the tree if there are no nodes down here
- if (indexInRange(indices, rootIndex, nextIndex)) {
- recurse(childNodes[i], vChild, indices, nodes, rootIndex)
- }
-
- rootIndex = nextIndex
- }
- }
- }
-
- return nodes
-}
-
-// Binary search for an index in the interval [left, right]
-function indexInRange(indices, left, right) {
- if (indices.length === 0) {
- return false
- }
-
- var minIndex = 0
- var maxIndex = indices.length - 1
- var currentIndex
- var currentItem
-
- while (minIndex <= maxIndex) {
- currentIndex = ((maxIndex + minIndex) / 2) >> 0
- currentItem = indices[currentIndex]
-
- if (minIndex === maxIndex) {
- return currentItem >= left && currentItem <= right
- } else if (currentItem < left) {
- minIndex = currentIndex + 1
- } else if (currentItem > right) {
- maxIndex = currentIndex - 1
- } else {
- return true
- }
- }
-
- return false;
-}
-
-function ascending(a, b) {
- return a > b ? 1 : -1
-}
-
-},{}],25:[function(require,module,exports){
-var applyProperties = require("./apply-properties")
-
-var isWidget = require("../vnode/is-widget.js")
-var VPatch = require("../vnode/vpatch.js")
-
-var updateWidget = require("./update-widget")
-
-module.exports = applyPatch
-
-function applyPatch(vpatch, domNode, renderOptions) {
- var type = vpatch.type
- var vNode = vpatch.vNode
- var patch = vpatch.patch
-
- switch (type) {
- case VPatch.REMOVE:
- return removeNode(domNode, vNode)
- case VPatch.INSERT:
- return insertNode(domNode, patch, renderOptions)
- case VPatch.VTEXT:
- return stringPatch(domNode, vNode, patch, renderOptions)
- case VPatch.WIDGET:
- return widgetPatch(domNode, vNode, patch, renderOptions)
- case VPatch.VNODE:
- return vNodePatch(domNode, vNode, patch, renderOptions)
- case VPatch.ORDER:
- reorderChildren(domNode, patch)
- return domNode
- case VPatch.PROPS:
- applyProperties(domNode, patch, vNode.properties)
- return domNode
- case VPatch.THUNK:
- return replaceRoot(domNode,
- renderOptions.patch(domNode, patch, renderOptions))
- default:
- return domNode
- }
-}
-
-function removeNode(domNode, vNode) {
- var parentNode = domNode.parentNode
-
- if (parentNode) {
- parentNode.removeChild(domNode)
- }
-
- destroyWidget(domNode, vNode);
-
- return null
-}
-
-function insertNode(parentNode, vNode, renderOptions) {
- var newNode = renderOptions.render(vNode, renderOptions)
-
- if (parentNode) {
- parentNode.appendChild(newNode)
- }
-
- return parentNode
-}
-
-function stringPatch(domNode, leftVNode, vText, renderOptions) {
- var newNode
-
- if (domNode.nodeType === 3) {
- domNode.replaceData(0, domNode.length, vText.text)
- newNode = domNode
- } else {
- var parentNode = domNode.parentNode
- newNode = renderOptions.render(vText, renderOptions)
-
- if (parentNode && newNode !== domNode) {
- parentNode.replaceChild(newNode, domNode)
- }
- }
-
- return newNode
-}
-
-function widgetPatch(domNode, leftVNode, widget, renderOptions) {
- var updating = updateWidget(leftVNode, widget)
- var newNode
-
- if (updating) {
- newNode = widget.update(leftVNode, domNode) || domNode
- } else {
- newNode = renderOptions.render(widget, renderOptions)
- }
-
- var parentNode = domNode.parentNode
-
- if (parentNode && newNode !== domNode) {
- parentNode.replaceChild(newNode, domNode)
- }
-
- if (!updating) {
- destroyWidget(domNode, leftVNode)
- }
-
- return newNode
-}
-
-function vNodePatch(domNode, leftVNode, vNode, renderOptions) {
- var parentNode = domNode.parentNode
- var newNode = renderOptions.render(vNode, renderOptions)
-
- if (parentNode && newNode !== domNode) {
- parentNode.replaceChild(newNode, domNode)
- }
-
- return newNode
-}
-
-function destroyWidget(domNode, w) {
- if (typeof w.destroy === "function" && isWidget(w)) {
- w.destroy(domNode)
- }
-}
-
-function reorderChildren(domNode, moves) {
- var childNodes = domNode.childNodes
- var keyMap = {}
- var node
- var remove
- var insert
-
- for (var i = 0; i < moves.removes.length; i++) {
- remove = moves.removes[i]
- node = childNodes[remove.from]
- if (remove.key) {
- keyMap[remove.key] = node
- }
- domNode.removeChild(node)
- }
-
- var length = childNodes.length
- for (var j = 0; j < moves.inserts.length; j++) {
- insert = moves.inserts[j]
- node = keyMap[insert.key]
- // this is the weirdest bug i've ever seen in webkit
- domNode.insertBefore(node, insert.to >= length++ ? null : childNodes[insert.to])
- }
-}
-
-function replaceRoot(oldRoot, newRoot) {
- if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) {
- oldRoot.parentNode.replaceChild(newRoot, oldRoot)
- }
-
- return newRoot;
-}
-
-},{"../vnode/is-widget.js":37,"../vnode/vpatch.js":40,"./apply-properties":22,"./update-widget":27}],26:[function(require,module,exports){
-var document = require("global/document")
-var isArray = require("x-is-array")
-
-var render = require("./create-element")
-var domIndex = require("./dom-index")
-var patchOp = require("./patch-op")
-module.exports = patch
-
-function patch(rootNode, patches, renderOptions) {
- renderOptions = renderOptions || {}
- renderOptions.patch = renderOptions.patch && renderOptions.patch !== patch
- ? renderOptions.patch
- : patchRecursive
- renderOptions.render = renderOptions.render || render
-
- return renderOptions.patch(rootNode, patches, renderOptions)
-}
-
-function patchRecursive(rootNode, patches, renderOptions) {
- var indices = patchIndices(patches)
-
- if (indices.length === 0) {
- return rootNode
- }
-
- var index = domIndex(rootNode, patches.a, indices)
- var ownerDocument = rootNode.ownerDocument
-
- if (!renderOptions.document && ownerDocument !== document) {
- renderOptions.document = ownerDocument
- }
-
- for (var i = 0; i < indices.length; i++) {
- var nodeIndex = indices[i]
- rootNode = applyPatch(rootNode,
- index[nodeIndex],
- patches[nodeIndex],
- renderOptions)
- }
-
- return rootNode
-}
-
-function applyPatch(rootNode, domNode, patchList, renderOptions) {
- if (!domNode) {
- return rootNode
- }
-
- var newNode
-
- if (isArray(patchList)) {
- for (var i = 0; i < patchList.length; i++) {
- newNode = patchOp(patchList[i], domNode, renderOptions)
-
- if (domNode === rootNode) {
- rootNode = newNode
- }
- }
- } else {
- newNode = patchOp(patchList, domNode, renderOptions)
-
- if (domNode === rootNode) {
- rootNode = newNode
- }
- }
-
- return rootNode
-}
-
-function patchIndices(patches) {
- var indices = []
-
- for (var key in patches) {
- if (key !== "a") {
- indices.push(Number(key))
- }
- }
-
- return indices
-}
-
-},{"./create-element":23,"./dom-index":24,"./patch-op":25,"global/document":6,"x-is-array":44}],27:[function(require,module,exports){
-var isWidget = require("../vnode/is-widget.js")
-
-module.exports = updateWidget
-
-function updateWidget(a, b) {
- if (isWidget(a) && isWidget(b)) {
- if ("name" in a && "name" in b) {
- return a.id === b.id
- } else {
- return a.init === b.init
- }
- }
-
- return false
-}
-
-},{"../vnode/is-widget.js":37}],28:[function(require,module,exports){
-'use strict';
-
-var EvStore = require('ev-store');
-
-module.exports = EvHook;
-
-function EvHook(value) {
- if (!(this instanceof EvHook)) {
- return new EvHook(value);
- }
-
- this.value = value;
-}
-
-EvHook.prototype.hook = function (node, propertyName) {
- var es = EvStore(node);
- var propName = propertyName.substr(3);
-
- es[propName] = this.value;
-};
-
-EvHook.prototype.unhook = function(node, propertyName) {
- var es = EvStore(node);
- var propName = propertyName.substr(3);
-
- es[propName] = undefined;
-};
-
-},{"ev-store":5}],29:[function(require,module,exports){
-'use strict';
-
-module.exports = SoftSetHook;
-
-function SoftSetHook(value) {
- if (!(this instanceof SoftSetHook)) {
- return new SoftSetHook(value);
- }
-
- this.value = value;
-}
-
-SoftSetHook.prototype.hook = function (node, propertyName) {
- if (node[propertyName] !== this.value) {
- node[propertyName] = this.value;
- }
-};
-
-},{}],30:[function(require,module,exports){
-'use strict';
-
-var isArray = require('x-is-array');
-
-var VNode = require('../vnode/vnode.js');
-var VText = require('../vnode/vtext.js');
-var isVNode = require('../vnode/is-vnode');
-var isVText = require('../vnode/is-vtext');
-var isWidget = require('../vnode/is-widget');
-var isHook = require('../vnode/is-vhook');
-var isVThunk = require('../vnode/is-thunk');
-
-var parseTag = require('./parse-tag.js');
-var softSetHook = require('./hooks/soft-set-hook.js');
-var evHook = require('./hooks/ev-hook.js');
-
-module.exports = h;
-
-function h(tagName, properties, children) {
- var childNodes = [];
- var tag, props, key, namespace;
-
- if (!children && isChildren(properties)) {
- children = properties;
- props = {};
- }
-
- props = props || properties || {};
- tag = parseTag(tagName, props);
-
- // support keys
- if (props.hasOwnProperty('key')) {
- key = props.key;
- props.key = undefined;
- }
-
- // support namespace
- if (props.hasOwnProperty('namespace')) {
- namespace = props.namespace;
- props.namespace = undefined;
- }
-
- // fix cursor bug
- if (tag === 'INPUT' &&
- !namespace &&
- props.hasOwnProperty('value') &&
- props.value !== undefined &&
- !isHook(props.value)
- ) {
- props.value = softSetHook(props.value);
- }
-
- transformProperties(props);
-
- if (children !== undefined && children !== null) {
- addChild(children, childNodes, tag, props);
- }
-
-
- return new VNode(tag, props, childNodes, key, namespace);
-}
-
-function addChild(c, childNodes, tag, props) {
- if (typeof c === 'string') {
- childNodes.push(new VText(c));
- } else if (typeof c === 'number') {
- childNodes.push(new VText(String(c)));
- } else if (isChild(c)) {
- childNodes.push(c);
- } else if (isArray(c)) {
- for (var i = 0; i < c.length; i++) {
- addChild(c[i], childNodes, tag, props);
- }
- } else if (c === null || c === undefined) {
- return;
- } else {
- throw UnexpectedVirtualElement({
- foreignObject: c,
- parentVnode: {
- tagName: tag,
- properties: props
- }
- });
- }
-}
-
-function transformProperties(props) {
- for (var propName in props) {
- if (props.hasOwnProperty(propName)) {
- var value = props[propName];
-
- if (isHook(value)) {
- continue;
- }
-
- if (propName.substr(0, 3) === 'ev-') {
- // add ev-foo support
- props[propName] = evHook(value);
- }
- }
- }
-}
-
-function isChild(x) {
- return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x);
-}
-
-function isChildren(x) {
- return typeof x === 'string' || isArray(x) || isChild(x);
-}
-
-function UnexpectedVirtualElement(data) {
- var err = new Error();
-
- err.type = 'virtual-hyperscript.unexpected.virtual-element';
- err.message = 'Unexpected virtual child passed to h().\n' +
- 'Expected a VNode / Vthunk / VWidget / string but:\n' +
- 'got:\n' +
- errorString(data.foreignObject) +
- '.\n' +
- 'The parent vnode is:\n' +
- errorString(data.parentVnode)
- '\n' +
- 'Suggested fix: change your `h(..., [ ... ])` callsite.';
- err.foreignObject = data.foreignObject;
- err.parentVnode = data.parentVnode;
-
- return err;
-}
-
-function errorString(obj) {
- try {
- return JSON.stringify(obj, null, ' ');
- } catch (e) {
- return String(obj);
- }
-}
-
-},{"../vnode/is-thunk":33,"../vnode/is-vhook":34,"../vnode/is-vnode":35,"../vnode/is-vtext":36,"../vnode/is-widget":37,"../vnode/vnode.js":39,"../vnode/vtext.js":41,"./hooks/ev-hook.js":28,"./hooks/soft-set-hook.js":29,"./parse-tag.js":31,"x-is-array":44}],31:[function(require,module,exports){
-'use strict';
-
-var split = require('browser-split');
-
-var classIdSplit = /([\.#]?[a-zA-Z0-9\u007F-\uFFFF_:-]+)/;
-var notClassId = /^\.|#/;
-
-module.exports = parseTag;
-
-function parseTag(tag, props) {
- if (!tag) {
- return 'DIV';
- }
-
- var noId = !(props.hasOwnProperty('id'));
-
- var tagParts = split(tag, classIdSplit);
- var tagName = null;
-
- if (notClassId.test(tagParts[1])) {
- tagName = 'DIV';
- }
-
- var classes, part, type, i;
-
- for (i = 0; i < tagParts.length; i++) {
- part = tagParts[i];
-
- if (!part) {
- continue;
- }
-
- type = part.charAt(0);
-
- if (!tagName) {
- tagName = part;
- } else if (type === '.') {
- classes = classes || [];
- classes.push(part.substring(1, part.length));
- } else if (type === '#' && noId) {
- props.id = part.substring(1, part.length);
- }
- }
-
- if (classes) {
- if (props.className) {
- classes.push(props.className);
- }
-
- props.className = classes.join(' ');
- }
-
- return props.namespace ? tagName : tagName.toUpperCase();
-}
-
-},{"browser-split":4}],32:[function(require,module,exports){
-var isVNode = require("./is-vnode")
-var isVText = require("./is-vtext")
-var isWidget = require("./is-widget")
-var isThunk = require("./is-thunk")
-
-module.exports = handleThunk
-
-function handleThunk(a, b) {
- var renderedA = a
- var renderedB = b
-
- if (isThunk(b)) {
- renderedB = renderThunk(b, a)
- }
-
- if (isThunk(a)) {
- renderedA = renderThunk(a, null)
- }
-
- return {
- a: renderedA,
- b: renderedB
- }
-}
-
-function renderThunk(thunk, previous) {
- var renderedThunk = thunk.vnode
-
- if (!renderedThunk) {
- renderedThunk = thunk.vnode = thunk.render(previous)
- }
-
- if (!(isVNode(renderedThunk) ||
- isVText(renderedThunk) ||
- isWidget(renderedThunk))) {
- throw new Error("thunk did not return a valid node");
- }
-
- return renderedThunk
-}
-
-},{"./is-thunk":33,"./is-vnode":35,"./is-vtext":36,"./is-widget":37}],33:[function(require,module,exports){
-module.exports = isThunk
-
-function isThunk(t) {
- return t && t.type === "Thunk"
-}
-
-},{}],34:[function(require,module,exports){
-module.exports = isHook
-
-function isHook(hook) {
- return hook &&
- (typeof hook.hook === "function" && !hook.hasOwnProperty("hook") ||
- typeof hook.unhook === "function" && !hook.hasOwnProperty("unhook"))
-}
-
-},{}],35:[function(require,module,exports){
-var version = require("./version")
-
-module.exports = isVirtualNode
-
-function isVirtualNode(x) {
- return x && x.type === "VirtualNode" && x.version === version
-}
-
-},{"./version":38}],36:[function(require,module,exports){
-var version = require("./version")
-
-module.exports = isVirtualText
-
-function isVirtualText(x) {
- return x && x.type === "VirtualText" && x.version === version
-}
-
-},{"./version":38}],37:[function(require,module,exports){
-module.exports = isWidget
-
-function isWidget(w) {
- return w && w.type === "Widget"
-}
-
-},{}],38:[function(require,module,exports){
-module.exports = "2"
-
-},{}],39:[function(require,module,exports){
-var version = require("./version")
-var isVNode = require("./is-vnode")
-var isWidget = require("./is-widget")
-var isThunk = require("./is-thunk")
-var isVHook = require("./is-vhook")
-
-module.exports = VirtualNode
-
-var noProperties = {}
-var noChildren = []
-
-function VirtualNode(tagName, properties, children, key, namespace) {
- this.tagName = tagName
- this.properties = properties || noProperties
- this.children = children || noChildren
- this.key = key != null ? String(key) : undefined
- this.namespace = (typeof namespace === "string") ? namespace : null
-
- var count = (children && children.length) || 0
- var descendants = 0
- var hasWidgets = false
- var hasThunks = false
- var descendantHooks = false
- var hooks
-
- for (var propName in properties) {
- if (properties.hasOwnProperty(propName)) {
- var property = properties[propName]
- if (isVHook(property) && property.unhook) {
- if (!hooks) {
- hooks = {}
- }
-
- hooks[propName] = property
- }
- }
- }
-
- for (var i = 0; i < count; i++) {
- var child = children[i]
- if (isVNode(child)) {
- descendants += child.count || 0
-
- if (!hasWidgets && child.hasWidgets) {
- hasWidgets = true
- }
-
- if (!hasThunks && child.hasThunks) {
- hasThunks = true
- }
-
- if (!descendantHooks && (child.hooks || child.descendantHooks)) {
- descendantHooks = true
- }
- } else if (!hasWidgets && isWidget(child)) {
- if (typeof child.destroy === "function") {
- hasWidgets = true
- }
- } else if (!hasThunks && isThunk(child)) {
- hasThunks = true;
- }
- }
-
- this.count = count + descendants
- this.hasWidgets = hasWidgets
- this.hasThunks = hasThunks
- this.hooks = hooks
- this.descendantHooks = descendantHooks
-}
-
-VirtualNode.prototype.version = version
-VirtualNode.prototype.type = "VirtualNode"
-
-},{"./is-thunk":33,"./is-vhook":34,"./is-vnode":35,"./is-widget":37,"./version":38}],40:[function(require,module,exports){
-var version = require("./version")
-
-VirtualPatch.NONE = 0
-VirtualPatch.VTEXT = 1
-VirtualPatch.VNODE = 2
-VirtualPatch.WIDGET = 3
-VirtualPatch.PROPS = 4
-VirtualPatch.ORDER = 5
-VirtualPatch.INSERT = 6
-VirtualPatch.REMOVE = 7
-VirtualPatch.THUNK = 8
-
-module.exports = VirtualPatch
-
-function VirtualPatch(type, vNode, patch) {
- this.type = Number(type)
- this.vNode = vNode
- this.patch = patch
-}
-
-VirtualPatch.prototype.version = version
-VirtualPatch.prototype.type = "VirtualPatch"
-
-},{"./version":38}],41:[function(require,module,exports){
-var version = require("./version")
-
-module.exports = VirtualText
-
-function VirtualText(text) {
- this.text = String(text)
-}
-
-VirtualText.prototype.version = version
-VirtualText.prototype.type = "VirtualText"
-
-},{"./version":38}],42:[function(require,module,exports){
-var isObject = require("is-object")
-var isHook = require("../vnode/is-vhook")
-
-module.exports = diffProps
-
-function diffProps(a, b) {
- var diff
-
- for (var aKey in a) {
- if (!(aKey in b)) {
- diff = diff || {}
- diff[aKey] = undefined
- }
-
- var aValue = a[aKey]
- var bValue = b[aKey]
-
- if (aValue === bValue) {
- continue
- } else if (isObject(aValue) && isObject(bValue)) {
- if (getPrototype(bValue) !== getPrototype(aValue)) {
- diff = diff || {}
- diff[aKey] = bValue
- } else if (isHook(bValue)) {
- diff = diff || {}
- diff[aKey] = bValue
- } else {
- var objectDiff = diffProps(aValue, bValue)
- if (objectDiff) {
- diff = diff || {}
- diff[aKey] = objectDiff
- }
- }
- } else {
- diff = diff || {}
- diff[aKey] = bValue
- }
- }
-
- for (var bKey in b) {
- if (!(bKey in a)) {
- diff = diff || {}
- diff[bKey] = b[bKey]
- }
- }
-
- return diff
-}
-
-function getPrototype(value) {
- if (Object.getPrototypeOf) {
- return Object.getPrototypeOf(value)
- } else if (value.__proto__) {
- return value.__proto__
- } else if (value.constructor) {
- return value.constructor.prototype
- }
-}
-
-},{"../vnode/is-vhook":34,"is-object":9}],43:[function(require,module,exports){
-var isArray = require("x-is-array")
-
-var VPatch = require("../vnode/vpatch")
-var isVNode = require("../vnode/is-vnode")
-var isVText = require("../vnode/is-vtext")
-var isWidget = require("../vnode/is-widget")
-var isThunk = require("../vnode/is-thunk")
-var handleThunk = require("../vnode/handle-thunk")
-
-var diffProps = require("./diff-props")
-
-module.exports = diff
-
-function diff(a, b) {
- var patch = { a: a }
- walk(a, b, patch, 0)
- return patch
-}
-
-function walk(a, b, patch, index) {
- if (a === b) {
- return
- }
-
- var apply = patch[index]
- var applyClear = false
-
- if (isThunk(a) || isThunk(b)) {
- thunks(a, b, patch, index)
- } else if (b == null) {
-
- // If a is a widget we will add a remove patch for it
- // Otherwise any child widgets/hooks must be destroyed.
- // This prevents adding two remove patches for a widget.
- if (!isWidget(a)) {
- clearState(a, patch, index)
- apply = patch[index]
- }
-
- apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b))
- } else if (isVNode(b)) {
- if (isVNode(a)) {
- if (a.tagName === b.tagName &&
- a.namespace === b.namespace &&
- a.key === b.key) {
- var propsPatch = diffProps(a.properties, b.properties)
- if (propsPatch) {
- apply = appendPatch(apply,
- new VPatch(VPatch.PROPS, a, propsPatch))
- }
- apply = diffChildren(a, b, patch, apply, index)
- } else {
- apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))
- applyClear = true
- }
- } else {
- apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b))
- applyClear = true
- }
- } else if (isVText(b)) {
- if (!isVText(a)) {
- apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))
- applyClear = true
- } else if (a.text !== b.text) {
- apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b))
- }
- } else if (isWidget(b)) {
- if (!isWidget(a)) {
- applyClear = true
- }
-
- apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b))
- }
-
- if (apply) {
- patch[index] = apply
- }
-
- if (applyClear) {
- clearState(a, patch, index)
- }
-}
-
-function diffChildren(a, b, patch, apply, index) {
- var aChildren = a.children
- var orderedSet = reorder(aChildren, b.children)
- var bChildren = orderedSet.children
-
- var aLen = aChildren.length
- var bLen = bChildren.length
- var len = aLen > bLen ? aLen : bLen
-
- for (var i = 0; i < len; i++) {
- var leftNode = aChildren[i]
- var rightNode = bChildren[i]
- index += 1
-
- if (!leftNode) {
- if (rightNode) {
- // Excess nodes in b need to be added
- apply = appendPatch(apply,
- new VPatch(VPatch.INSERT, null, rightNode))
- }
- } else {
- walk(leftNode, rightNode, patch, index)
- }
-
- if (isVNode(leftNode) && leftNode.count) {
- index += leftNode.count
- }
- }
-
- if (orderedSet.moves) {
- // Reorder nodes last
- apply = appendPatch(apply, new VPatch(
- VPatch.ORDER,
- a,
- orderedSet.moves
- ))
- }
-
- return apply
-}
-
-function clearState(vNode, patch, index) {
- // TODO: Make this a single walk, not two
- unhook(vNode, patch, index)
- destroyWidgets(vNode, patch, index)
-}
-
-// Patch records for all destroyed widgets must be added because we need
-// a DOM node reference for the destroy function
-function destroyWidgets(vNode, patch, index) {
- if (isWidget(vNode)) {
- if (typeof vNode.destroy === "function") {
- patch[index] = appendPatch(
- patch[index],
- new VPatch(VPatch.REMOVE, vNode, null)
- )
- }
- } else if (isVNode(vNode) && (vNode.hasWidgets || vNode.hasThunks)) {
- var children = vNode.children
- var len = children.length
- for (var i = 0; i < len; i++) {
- var child = children[i]
- index += 1
-
- destroyWidgets(child, patch, index)
-
- if (isVNode(child) && child.count) {
- index += child.count
- }
- }
- } else if (isThunk(vNode)) {
- thunks(vNode, null, patch, index)
- }
-}
-
-// Create a sub-patch for thunks
-function thunks(a, b, patch, index) {
- var nodes = handleThunk(a, b)
- var thunkPatch = diff(nodes.a, nodes.b)
- if (hasPatches(thunkPatch)) {
- patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch)
- }
-}
-
-function hasPatches(patch) {
- for (var index in patch) {
- if (index !== "a") {
- return true
- }
- }
-
- return false
-}
-
-// Execute hooks when two nodes are identical
-function unhook(vNode, patch, index) {
- if (isVNode(vNode)) {
- if (vNode.hooks) {
- patch[index] = appendPatch(
- patch[index],
- new VPatch(
- VPatch.PROPS,
- vNode,
- undefinedKeys(vNode.hooks)
- )
- )
- }
-
- if (vNode.descendantHooks || vNode.hasThunks) {
- var children = vNode.children
- var len = children.length
- for (var i = 0; i < len; i++) {
- var child = children[i]
- index += 1
-
- unhook(child, patch, index)
-
- if (isVNode(child) && child.count) {
- index += child.count
- }
- }
- }
- } else if (isThunk(vNode)) {
- thunks(vNode, null, patch, index)
- }
-}
-
-function undefinedKeys(obj) {
- var result = {}
-
- for (var key in obj) {
- result[key] = undefined
- }
-
- return result
-}
-
-// List diff, naive left to right reordering
-function reorder(aChildren, bChildren) {
- // O(M) time, O(M) memory
- var bChildIndex = keyIndex(bChildren)
- var bKeys = bChildIndex.keys
- var bFree = bChildIndex.free
-
- if (bFree.length === bChildren.length) {
- return {
- children: bChildren,
- moves: null
- }
- }
-
- // O(N) time, O(N) memory
- var aChildIndex = keyIndex(aChildren)
- var aKeys = aChildIndex.keys
- var aFree = aChildIndex.free
-
- if (aFree.length === aChildren.length) {
- return {
- children: bChildren,
- moves: null
- }
- }
-
- // O(MAX(N, M)) memory
- var newChildren = []
-
- var freeIndex = 0
- var freeCount = bFree.length
- var deletedItems = 0
-
- // Iterate through a and match a node in b
- // O(N) time,
- for (var i = 0 ; i < aChildren.length; i++) {
- var aItem = aChildren[i]
- var itemIndex
-
- if (aItem.key) {
- if (bKeys.hasOwnProperty(aItem.key)) {
- // Match up the old keys
- itemIndex = bKeys[aItem.key]
- newChildren.push(bChildren[itemIndex])
-
- } else {
- // Remove old keyed items
- itemIndex = i - deletedItems++
- newChildren.push(null)
- }
- } else {
- // Match the item in a with the next free item in b
- if (freeIndex < freeCount) {
- itemIndex = bFree[freeIndex++]
- newChildren.push(bChildren[itemIndex])
- } else {
- // There are no free items in b to match with
- // the free items in a, so the extra free nodes
- // are deleted.
- itemIndex = i - deletedItems++
- newChildren.push(null)
- }
- }
- }
-
- var lastFreeIndex = freeIndex >= bFree.length ?
- bChildren.length :
- bFree[freeIndex]
-
- // Iterate through b and append any new keys
- // O(M) time
- for (var j = 0; j < bChildren.length; j++) {
- var newItem = bChildren[j]
-
- if (newItem.key) {
- if (!aKeys.hasOwnProperty(newItem.key)) {
- // Add any new keyed items
- // We are adding new items to the end and then sorting them
- // in place. In future we should insert new items in place.
- newChildren.push(newItem)
- }
- } else if (j >= lastFreeIndex) {
- // Add any leftover non-keyed items
- newChildren.push(newItem)
- }
- }
-
- var simulate = newChildren.slice()
- var simulateIndex = 0
- var removes = []
- var inserts = []
- var simulateItem
-
- for (var k = 0; k < bChildren.length;) {
- var wantedItem = bChildren[k]
- simulateItem = simulate[simulateIndex]
-
- // remove items
- while (simulateItem === null && simulate.length) {
- removes.push(remove(simulate, simulateIndex, null))
- simulateItem = simulate[simulateIndex]
- }
-
- if (!simulateItem || simulateItem.key !== wantedItem.key) {
- // if we need a key in this position...
- if (wantedItem.key) {
- if (simulateItem && simulateItem.key) {
- // if an insert doesn't put this key in place, it needs to move
- if (bKeys[simulateItem.key] !== k + 1) {
- removes.push(remove(simulate, simulateIndex, simulateItem.key))
- simulateItem = simulate[simulateIndex]
- // if the remove didn't put the wanted item in place, we need to insert it
- if (!simulateItem || simulateItem.key !== wantedItem.key) {
- inserts.push({key: wantedItem.key, to: k})
- }
- // items are matching, so skip ahead
- else {
- simulateIndex++
- }
- }
- else {
- inserts.push({key: wantedItem.key, to: k})
- }
- }
- else {
- inserts.push({key: wantedItem.key, to: k})
- }
- k++
- }
- // a key in simulate has no matching wanted key, remove it
- else if (simulateItem && simulateItem.key) {
- removes.push(remove(simulate, simulateIndex, simulateItem.key))
- }
- }
- else {
- simulateIndex++
- k++
- }
- }
-
- // remove all the remaining nodes from simulate
- while(simulateIndex < simulate.length) {
- simulateItem = simulate[simulateIndex]
- removes.push(remove(simulate, simulateIndex, simulateItem && simulateItem.key))
- }
-
- // If the only moves we have are deletes then we can just
- // let the delete patch remove these items.
- if (removes.length === deletedItems && !inserts.length) {
- return {
- children: newChildren,
- moves: null
- }
- }
-
- return {
- children: newChildren,
- moves: {
- removes: removes,
- inserts: inserts
- }
- }
-}
-
-function remove(arr, index, key) {
- arr.splice(index, 1)
-
- return {
- from: index,
- key: key
- }
-}
-
-function keyIndex(children) {
- var keys = {}
- var free = []
- var length = children.length
-
- for (var i = 0; i < length; i++) {
- var child = children[i]
-
- if (child.key) {
- keys[child.key] = i
- } else {
- free.push(i)
- }
- }
-
- return {
- keys: keys, // A hash of key name to index
- free: free // An array of unkeyed item indices
- }
-}
-
-function appendPatch(apply, patch) {
- if (apply) {
- if (isArray(apply)) {
- apply.push(patch)
- } else {
- apply = [apply, patch]
- }
-
- return apply
- } else {
- return patch
- }
-}
-
-},{"../vnode/handle-thunk":32,"../vnode/is-thunk":33,"../vnode/is-vnode":35,"../vnode/is-vtext":36,"../vnode/is-widget":37,"../vnode/vpatch":40,"./diff-props":42,"x-is-array":44}],44:[function(require,module,exports){
-var nativeIsArray = Array.isArray
-var toString = Object.prototype.toString
-
-module.exports = nativeIsArray || isArray
-
-function isArray(obj) {
- return toString.call(obj) === "[object Array]"
-}
-
-},{}]},{},[1]);
diff --git a/formspree/static/js/main.js b/formspree/static/js/main.js
deleted file mode 100644
index 94af907..0000000
--- a/formspree/static/js/main.js
+++ /dev/null
@@ -1,128 +0,0 @@
-const $ = window.$
-const StripeCheckout = window.StripeCheckout
-const toastr = window.toastr
-
-toastr.options = { positionClass: 'toast-top-center' }
-
-/* top navbar */
-var nav = $('body > nav')
-nav.addClass('js')
-nav.find('.menu').slicknav()
-nav.find('h4').clone().prependTo('.slicknav_menu')
-
-/* adding a shadow at the bottom of the menu bar only when not at the top */
-var w = $(window)
-w.scroll(function () {
- var scrollPos = w.scrollTop()
- if (scrollPos && !nav.hasClass('scrolled')) {
- nav.addClass('scrolled')
- } else if (!scrollPos) {
- nav.removeClass('scrolled')
- }
-})
-
-/* background-color should inherit, but CSS's "inherit" breaks z-index */
-var bgcolor = $(document.body).css('background-color')
-if (bgcolor.split(',').length === 4 || bgcolor === 'transparent') {
- bgcolor = 'white'
-}
-nav.css('background-color', bgcolor)
-
-/* modals -- working with or without JS */
-function modals () {
- $('.modal').each(function () {
- let modal = $(this)
- modal.addClass('js')
- let id = modal.attr('id')
-
- $(`[href="#${id}"]`).click(function (e) {
- // open the modal
- e.preventDefault()
- modal.toggleClass('target')
- })
-
- modal.click(function (e) {
- // close the modal
- if (e.target === modal[0]) {
- cleanHash()
- modal.toggleClass('target')
- e.preventDefault()
- }
- })
- modal.find('.x a').click(function (e) {
- // close the modal
- cleanHash()
- e.preventDefault()
- modal.toggleClass('target')
- })
- })
-
- function cleanHash () {
- if (!window.location.hash) return
- if (window.history && window.history.replaceState) {
- window.history.replaceState('', document.title, window.location.pathname)
- } else {
- let pos = $(window).scrollTop()
- window.location.hash = ''
- $(window).scrollTop(pos)
- }
- }
-
- // activate modals from url hash #
- setTimeout(() => {
- // setTimeout is needed because :target elements only appear after
- // the page is loaded or something like that.
- let activatedModal = $('*:target')
- if (activatedModal.length && !activatedModal.is('.target')) {
- activatedModal.toggleClass('target')
- }
- }, 0)
-}
-modals()
-
-/* turning flask flash messages into js popup notifications */
-window.popupMessages.forEach(function (m, i) {
- var category = m[0] || 'info'
- var text = m[1]
- setTimeout(function () { toastr[category](text) }, (1 + i) * 1500)
-})
-
-/* stripe checkout */
-var stripebutton = $('#stripe-upgrade')
-if (stripebutton.length) {
- var handler = StripeCheckout.configure(stripebutton.data())
- stripebutton.on('click', function (e) {
- handler.open({
- token: function (token) {
- stripebutton.closest('form')
- .append(` `)
- .append(` `)
- .submit()
- }
- })
- e.preventDefault()
- })
-}
-
-/* quick script for showing the resend confirmation form */
-$('a.resend').on('click', function () {
- $(this).hide()
- $('form.resend').show()
- return false
-})
-
-/* scripts at other files */
-require('./sitewide')()
-
-/* toggle the card management menu */
- $(function () {
- $("#card-list tr:even").addClass("even");
- $("#card-list tr:not(.even)").hide();
- $("#card-list tr:first-child").show();
-
- $("#card-list tr.even").click(function () {
- $(this).next("tr").toggle();
- $(this).find(".arrow").toggleClass("up");
- $(this).find(".fa-chevron-right").toggleClass("fa-rotate-90");
- });
- });
diff --git a/formspree/static/js/submissions.js b/formspree/static/js/submissions.js
deleted file mode 100644
index e6382a6..0000000
--- a/formspree/static/js/submissions.js
+++ /dev/null
@@ -1,57 +0,0 @@
-var settingsDropDownContent = $("#settings-dropdown-content")[0];
-
-$(window).click(function(e) {
- if(!e.target.matches('#settings-button') && e.target.nodeName != 'path' && e.target.nodeName != 'svg') {
-
- if (settingsDropDownContent.classList.contains("show")) {
- settingsDropDownContent.classList.remove("show");
- }
- }
-});
-
-$(document).ready(function() {
- $("#settings-button").click(function() {
- settingsDropDownContent.classList.toggle("show");
- });
-});
-
-$(document).ready(function() {
- $(':checkbox').change(function() {
- targetAttributeBox = this;
- var target;
- var checkedStatus = this.checked;
- var status = $("#status");
-
- if (this.id == 'recaptcha') {
- target = '/forms/' + hashid + '/toggle-recaptcha';
- } else if (this.id == 'email-notifications') {
- target = '/forms/' + hashid + '/toggle-emails';
- } else if (this.id == 'submission-storage') {
- target = '/forms/' + hashid + '/toggle-storage';
- }
-
- $.ajax({
- url: target,
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify({
- checked: checkedStatus
- }),
- dataType: 'json',
- beforeSend: function() {
- status.removeClass("error");
- status.html('Saving... ');
- },
- success: function (data) {
- status.html('Saved ');
- console.log(data);
- },
- error: function (data) {
- status.html('Error saving ');
- status.addClass("error");
- targetAttributeBox.checked = !checkedStatus;
- console.log(data);
- }
- });
- })
-});
diff --git a/formspree/static/js/vendor/jquery.min.js b/formspree/static/js/vendor/jquery.min.js
deleted file mode 100644
index 18bdbed..0000000
--- a/formspree/static/js/vendor/jquery.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*! 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>$2>")+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>$2>");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("")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:"0",fontWeight:"400"},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||tb(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?tb(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xb,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xb(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Lb=n.now();b1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))
-},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=n.now(),dc=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var ec=/#.*$/,fc=/([?&])_=[^&]*/,gc=/^(.*?):[ \t]*([^\r\n]*)$/gm,hc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ic=/^(?:GET|HEAD)$/,jc=/^\/\//,kc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lc={},mc={},nc="*/".concat("*"),oc=a.location.href,pc=kc.exec(oc.toLowerCase())||[];function qc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rc(a,b,c,d){var e={},f=a===mc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function uc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:oc,type:"GET",isLocal:hc.test(pc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sc(sc(a,n.ajaxSettings),b):sc(n.ajaxSettings,a)},ajaxPrefilter:qc(lc),ajaxTransport:qc(mc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gc.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||oc)+"").replace(ec,"").replace(jc,pc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pc[1]&&h[2]===pc[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pc[3]||("http:"===pc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rc(lc,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ic.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fc.test(d)?d.replace(fc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rc(mc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tc(k,v,f)),u=uc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vc=/%20/g,wc=/\[\]$/,xc=/\r?\n/g,yc=/^(?:submit|button|image|reset|file)$/i,zc=/^(?:input|select|textarea|keygen)/i;function Ac(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wc.test(a)?d(a,e):Ac(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ac(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ac(c,a[c],b,e);return d.join("&").replace(vc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zc.test(this.nodeName)&&!yc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xc,"\r\n")}}):{name:b.name,value:c.replace(xc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bc=0,Cc={},Dc={0:200,1223:204},Ec=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cc)Cc[a]()}),k.cors=!!Ec&&"withCredentials"in Ec,k.ajax=Ec=!!Ec,n.ajaxTransport(function(a){var b;return k.cors||Ec&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Dc[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cc[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("
-
-
-{% endblock %}
diff --git a/formspree/templates/layouts/base.html b/formspree/templates/layouts/base.html
index 4904bd1..ca6104a 100644
--- a/formspree/templates/layouts/base.html
+++ b/formspree/templates/layouts/base.html
@@ -22,18 +22,15 @@
-
-{# #}
-{# #}
-
-
+
{% block head_scripts %}{% endblock %}
+
@@ -65,7 +62,7 @@