From 25dbf545cc385f0f9c85d8b85430362a73d84f47 Mon Sep 17 00:00:00 2001 From: Nikolai Kristiansen Date: Wed, 17 Jun 2015 21:19:42 +0200 Subject: [PATCH] Initial commit --- .gitignore | 8 + apps/__init__.py | 0 apps/kassa/__init__.py | 0 apps/kassa/admin.py | 3 + apps/kassa/migrations/__init__.py | 0 apps/kassa/models.py | 3 + apps/kassa/templates/base.html | 13 + apps/kassa/templates/kassa/register.html | 2 + apps/kassa/tests.py | 3 + apps/kassa/urls.py | 6 + apps/kassa/views.py | 14 + kassasite/__init__.py | 0 kassasite/settings.py | 114 + kassasite/urls.py | 23 + kassasite/wsgi.py | 16 + manage.py | 10 + static/app/scripts/app.js | 0 static/app/scripts/documents_edit.js | 95 + static/app/scripts/fd-slider.js | 1341 ++ static/app/scripts/graphs.js | 186 + static/app/scripts/presentation_edit.js | 121 + static/app/scripts/presentation_list.js | 9 + static/app/scripts/product_calculator.js | 541 + static/app/scripts/slide_edit.js | 276 + static/app/scripts/slides.js | 440 + static/app/styles/_header.scss | 0 static/app/styles/_settings.scss | 1457 ++ static/app/styles/app.scss | 30 + static/bower.json | 28 + static/dist/fonts/fontawesome-webfont.eot | Bin 0 -> 60767 bytes static/dist/fonts/fontawesome-webfont.svg | 565 + static/dist/fonts/fontawesome-webfont.ttf | Bin 0 -> 122092 bytes static/dist/fonts/fontawesome-webfont.woff | Bin 0 -> 71508 bytes static/dist/fonts/fontawesome-webfont.woff2 | Bin 0 -> 56780 bytes static/dist/scripts/app.js | 0 static/dist/scripts/documents_edit.js | 95 + static/dist/scripts/fd-slider.js | 1341 ++ static/dist/scripts/graphs.js | 186 + static/dist/scripts/presentation_edit.js | 121 + static/dist/scripts/presentation_list.js | 9 + static/dist/scripts/product_calculator.js | 541 + static/dist/scripts/slide_edit.js | 276 + static/dist/scripts/slides.js | 440 + static/dist/scripts/vendor.js | 19779 ++++++++++++++++++ static/dist/styles/app.css | 1 + static/dist/styles/vendor.css | 8127 +++++++ static/gulpfile.js | 131 + static/package.json | 32 + 48 files changed, 36383 insertions(+) create mode 100644 .gitignore create mode 100644 apps/__init__.py create mode 100644 apps/kassa/__init__.py create mode 100644 apps/kassa/admin.py create mode 100644 apps/kassa/migrations/__init__.py create mode 100644 apps/kassa/models.py create mode 100644 apps/kassa/templates/base.html create mode 100644 apps/kassa/templates/kassa/register.html create mode 100644 apps/kassa/tests.py create mode 100644 apps/kassa/urls.py create mode 100644 apps/kassa/views.py create mode 100644 kassasite/__init__.py create mode 100644 kassasite/settings.py create mode 100644 kassasite/urls.py create mode 100644 kassasite/wsgi.py create mode 100755 manage.py create mode 100644 static/app/scripts/app.js create mode 100644 static/app/scripts/documents_edit.js create mode 100644 static/app/scripts/fd-slider.js create mode 100644 static/app/scripts/graphs.js create mode 100644 static/app/scripts/presentation_edit.js create mode 100644 static/app/scripts/presentation_list.js create mode 100644 static/app/scripts/product_calculator.js create mode 100644 static/app/scripts/slide_edit.js create mode 100644 static/app/scripts/slides.js create mode 100644 static/app/styles/_header.scss create mode 100644 static/app/styles/_settings.scss create mode 100644 static/app/styles/app.scss create mode 100644 static/bower.json create mode 100644 static/dist/fonts/fontawesome-webfont.eot create mode 100644 static/dist/fonts/fontawesome-webfont.svg create mode 100644 static/dist/fonts/fontawesome-webfont.ttf create mode 100644 static/dist/fonts/fontawesome-webfont.woff create mode 100644 static/dist/fonts/fontawesome-webfont.woff2 create mode 100644 static/dist/scripts/app.js create mode 100644 static/dist/scripts/documents_edit.js create mode 100644 static/dist/scripts/fd-slider.js create mode 100644 static/dist/scripts/graphs.js create mode 100644 static/dist/scripts/presentation_edit.js create mode 100644 static/dist/scripts/presentation_list.js create mode 100644 static/dist/scripts/product_calculator.js create mode 100644 static/dist/scripts/slide_edit.js create mode 100644 static/dist/scripts/slides.js create mode 100644 static/dist/scripts/vendor.js create mode 100644 static/dist/styles/app.css create mode 100644 static/dist/styles/vendor.css create mode 100644 static/gulpfile.js create mode 100644 static/package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7ead038 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.swp +*.pyc +.idea +local_settings.py +db.sqlite3 +venv +node_modules +bower_components diff --git a/apps/__init__.py b/apps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/kassa/__init__.py b/apps/kassa/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/kassa/admin.py b/apps/kassa/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/apps/kassa/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/apps/kassa/migrations/__init__.py b/apps/kassa/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/kassa/models.py b/apps/kassa/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/apps/kassa/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/apps/kassa/templates/base.html b/apps/kassa/templates/base.html new file mode 100644 index 0000000..20829af --- /dev/null +++ b/apps/kassa/templates/base.html @@ -0,0 +1,13 @@ +{% load staticfiles %} + + + + + {% block title %}Registrer medlemskap{% endblock %} + + + + +{% block content %}{% endblock %} + + \ No newline at end of file diff --git a/apps/kassa/templates/kassa/register.html b/apps/kassa/templates/kassa/register.html new file mode 100644 index 0000000..0da588b --- /dev/null +++ b/apps/kassa/templates/kassa/register.html @@ -0,0 +1,2 @@ +{% extends "base.html" %} +{% block content %}LOL{% endblock %} \ No newline at end of file diff --git a/apps/kassa/tests.py b/apps/kassa/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/apps/kassa/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/apps/kassa/urls.py b/apps/kassa/urls.py new file mode 100644 index 0000000..3b37955 --- /dev/null +++ b/apps/kassa/urls.py @@ -0,0 +1,6 @@ +from django.conf.urls import url +from apps.kassa.views import register + +urlpatterns = [ + url(r'register/', register) +] \ No newline at end of file diff --git a/apps/kassa/views.py b/apps/kassa/views.py new file mode 100644 index 0000000..0db9131 --- /dev/null +++ b/apps/kassa/views.py @@ -0,0 +1,14 @@ +# coding: utf-8 +from __future__ import unicode_literals +from django.contrib.auth.decorators import login_required +from django.shortcuts import render + +@login_required +def register(request): + context = {} + return render(request, 'kassa/register.html', context) + + +def home(request): + context = {} + return render(request, 'kassa/register.html', context) diff --git a/kassasite/__init__.py b/kassasite/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/kassasite/settings.py b/kassasite/settings.py new file mode 100644 index 0000000..ca9ceb2 --- /dev/null +++ b/kassasite/settings.py @@ -0,0 +1,114 @@ +""" +Generated by 'django-admin startproject' using Django 1.8.2. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/1.8/ref/settings/ +""" + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +import os + +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = '79l0@&(^ra9=s783rqeo2awhs6@c!j&wan6t-0wi8azyd@!x+7' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = ( + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', +) + +LOCAL_APPS = ('apps.kassa',) + +INSTALLED_APPS += LOCAL_APPS + +MIDDLEWARE_CLASSES = ( + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.middleware.security.SecurityMiddleware', +) + +ROOT_URLCONF = 'kassasite.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'kassasite.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/1.8/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Internationalization +# https://docs.djangoproject.com/en/1.8/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'Europe/Oslo' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/1.8/howto/static-files/ + +STATIC_URL = '/static/' + +STATICFILES_DIRS = ( + os.path.join(BASE_DIR, 'static'), +) + +# Local settings +try: + from local_settings import * +except ImportError: + pass diff --git a/kassasite/urls.py b/kassasite/urls.py new file mode 100644 index 0000000..8751c7a --- /dev/null +++ b/kassasite/urls.py @@ -0,0 +1,23 @@ +"""neuf_kassa URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/1.8/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') +Including another URLconf + 1. Add an import: from blog import urls as blog_urls + 2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls)) +""" +from django.conf.urls import include, url +from django.contrib import admin +from apps.kassa import urls as kassa_urls + +urlpatterns = [ + url(r'^admin/', include(admin.site.urls)), + url(r'^', include(kassa_urls)), +] diff --git a/kassasite/wsgi.py b/kassasite/wsgi.py new file mode 100644 index 0000000..5b00411 --- /dev/null +++ b/kassasite/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for neuf_kassa project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "neuf_kassa.settings") + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100755 index 0000000..290eac6 --- /dev/null +++ b/manage.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kassasite.settings") + + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/static/app/scripts/app.js b/static/app/scripts/app.js new file mode 100644 index 0000000..e69de29 diff --git a/static/app/scripts/documents_edit.js b/static/app/scripts/documents_edit.js new file mode 100644 index 0000000..eca4572 --- /dev/null +++ b/static/app/scripts/documents_edit.js @@ -0,0 +1,95 @@ + +$(function(){ + var urls = { + save_document: '/api/document/', + update_document: '/api/document/{pk}/' + }; + var _dom = { + document_table: $('.document-table'), + progress_bar: $("#progress .bar"), + }; + var csrf_token = $.cookie('csrftoken'); + + /* inplace edit */ + _dom.document_table.on('click', "[data-model-field]", function() { + var input_field = $(this).siblings("input"); + if($(this).siblings("input").length) { + input_field.val($(this).text()).css('display', 'inline-block'); + } else { + $(this).after(''); + input_field = $(this).siblings("input"); + } + input_field.css('width', $(this).width() + 30); + $(this).hide(); + $("[data-editable-field]").focus(); + }); + + /* save on blur and */ + _dom.document_table.on('blur keyup', 'input[type=text]', function(e) { + if(e.type == 'keyup' && e.keyCode != 13) { + return; + } + /* anything changed ? */ + if( $(this).siblings("[data-model-field]").text() !== $(this).val() ) { + /* update text */ + $(this).siblings("[data-model-field]").text($(this).val()); + + var document_pk = $(this).siblings("[data-model-field]").attr('data-pk'); + var model_field = $(this).siblings("[data-model-field]").attr('data-model-field'); + var field_value = $(this).val(); + + var data = {}; + data[model_field] = field_value; + + $.ajax({ + url: urls.update_document.replace('{pk}', document_pk), + method: 'PATCH', + dataType: 'json', + data: data, + headers: { + 'X-CSRFToken': csrf_token + }, + success: function(response, newValue) { + console.log('Field '+model_field+' updated with value "'+field_value+'".'); + } + }); + } + /* Back to original view */ + $("[data-model-field]").show(); + $(this).hide(); + }); + + /* Document file upload */ + $('.upload-document').fileupload({ + dataType: 'json', // TODO: why no JSON? + url: urls.save_document, + done: function(e, data) { + _dom.progress_bar.fadeOut('slow'); + var result = data.result; + /* insert document row */ + + var filename = result.filename.slice(0, 40); + console.log(result); + + $('.document-table').prepend(''+ result.name +' '+ filename +''+ result.updated +''); + }, + fail: function(e, data) { + console.log("Failed uploading file: ",e, data); + }, + headers: { + 'X-CSRFToken': csrf_token, + 'cache-control': 'no-cache' + }, + send: function(e, data) { + _dom.progress_bar.css('width', '0%'); + _dom.progress_bar.show(); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + _dom.progress_bar.css( + 'width', + progress + '%' + ); + } + }); +}); diff --git a/static/app/scripts/fd-slider.js b/static/app/scripts/fd-slider.js new file mode 100644 index 0000000..940ee49 --- /dev/null +++ b/static/app/scripts/fd-slider.js @@ -0,0 +1,1341 @@ +/*! Unobtrusive Slider Control / HTML5 Input Range polyfill - MIT/GPL2 @freqdec */ +/*jshint sub:true, evil:true, boss:true */ +var fdSlider = (function() { + var sliders = {}, + uniqueid = 0, + mouseWheelEnabled = true, + fullARIA = true, + describedBy = "fd-slider-describedby", + varSetRules = { + onfocus:true, + onvalue:true + }, + noRangeBar = false, + html5Animation = "jump", + useDOMAttrModEvt = false, + isOpera = Object.prototype.toString.call(window.opera) === "[object Opera]", + fpRegExp = /^([\-]{0,1}[0-9]+(\.[0-9]+){0,1})$/, + stepRegExp = /^([0-9]+(\.[0-9]+){0,1})$/; + + var parseJSON = function(str) { + if(typeof str !== "string" || str === "") { + return {}; + } + try { + // Does a JSON (native or not) Object exist + if(typeof JSON === "object" && typeof(JSON.parse) === "function") { + return JSON.parse(str); + // Genious code taken from: http://kentbrewster.com/badges/ + } else if(/mousewheelenabled|fullaria|describedby|norangebar|html5animation|varsetrules/.test(str.toLowerCase())) { + var f = Function(['var document,top,self,window,parent,Number,Date,Object,Function,', + 'Array,String,Math,RegExp,Image,ActiveXObject;', + 'return (' , str.replace(/<\!--.+-->/gim,'').replace(/\bfunction\b/g,'function-') , ');'].join('')); + return f(); + } + } catch (e) { } + + return {"err":"Could not parse the JSON object"}; + }; + + var affectJSON = function(json) { + if(typeof json !== "object") { + return; + } + for(var key in json) { + value = json[key]; + switch(key.toLowerCase()) { + case "mousewheelenabled": + mouseWheelEnabled = !!value; + break; + case "fullaria": + fullARIA = !!value; + break; + case "describedby": + describedBy = String(value); + break; + case "norangebar": + noRangeBar = !!value; + break; + case "html5animation": + html5Animation = String(value).search(/^(jump|tween|timed)$/i) != -1 ? String(value).toLowerCase() : "jump"; + break; + case "watchattributes": + useDOMAttrModEvt = !!value; + break; + case "varsetrules": + if("onfocus" in value) { + varSetRules.onfocus = !!value.onfocus; + } + if("onvalue" in value) { + varSetRules.onvalue = !!value.onvalue; + } + break; + } + } + }; + var addEvent = function(obj, type, fn) { + if(obj.addEventListener) { + obj.addEventListener(type, fn, true); + } else if(obj.attachEvent) { + obj.attachEvent("on"+type, fn); + } + }; + var removeEvent = function(obj, type, fn) { + try { + if(obj.removeEventListener) { + obj.removeEventListener(type, fn, true); + } else if(obj.detachEvent) { + obj.detachEvent("on"+type, fn); + } + } catch(err) {} + }; + var stopEvent = function(e) { + e = e || window.event; + if(e.stopPropagation) { + e.stopPropagation(); + e.preventDefault(); + } + + /*@cc_on@*/ + /*@if(@_win32) + e.cancelBubble = true; + e.returnValue = false; + /*@end@*/ + + return false; + }; + var preventDefault = function(e) { + e = e || window.event; + if(e.preventDefault) { + e.preventDefault(); + return; + } + e.returnValue = false; + }; + // Add/Remove classname utility functions + var addClass = function(e,c) { + if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) { + return; + } + e.className += ( e.className ? " " : "" ) + c; + }; + var removeClass = function(e,c) { + e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + }; + // Returns an Object of key value pairs indicating which sliders have values + // that have been "set" by the user. Normally used within form validation code + var getValueSet = function() { + var obj = {}; + for(var id in sliders) { + obj[id] = sliders[id].getValueSet(); + } + return obj; + }; + // Sets the valueSet variable for a specific slider + var setValueSet = function(sliderId, tf) { + sliders[sliderId].setValueSet(!!tf); + }; + // Does the slider exist in memory + var sliderExists = function(slider) { + return !!(slider in sliders && sliders.hasOwnProperty(slider)); + }; + // Javascript instantiation of a slider (input type="text|range" or select list) + var createSlider = function(options) { + if(!options || !options.inp || !options.inp.tagName || options.inp.tagName.search(/^input|select/i) == -1) { return false; } + + options.html5Shim = false; + + if(options.inp.tagName.toLowerCase() == "select") { + if(options.inp.options.length < 2) { + return false; + } + options.min = 0; + options.max = options.inp.options.length - 1; + options.step = 1; + options.precision = 0; + options.scale = false; + options.forceValue = true; + } else { + if(String(options.inp.type).search(/^(text|range)$/i) == -1) { + return false; + } + options.min = options.min && String(options.min).search(fpRegExp) != -1 ? +options.min : 0; + options.max = options.max && String(options.max).search(fpRegExp) != -1 ? +options.max : 100; + options.step = options.step && String(options.step).search(stepRegExp) != -1 ? options.step : 1; + options.precision = options.precision && String(options.precision).search(/^[0-9]+$/) != -1 ? options.precision : (String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0); + options.scale = options.scale || false; + options.forceValue = ("forceValue" in options) ? !!options.forceValue : false; + options.userSnap = ("userSnap" in options) ? !!options.userSnap : false; + } + options.ariaFormat = ("ariaFormat" in options) && typeof options.ariaFormat == "function" ? options.ariaFormat : false; + options.maxStep = options.maxStep && String(options.maxStep).search(stepRegExp) != -1 ? +options.maxStep : +options.step * 2; + options.classNames = options.classNames || ""; + options.callbacks = options.callbacks || false; + + destroySingleSlider(options.inp.id); + sliders[options.inp.id] = new fdRange(options); + return true; + }; + var getAttribute = function(elem, att) { + return elem.getAttribute(att) || ""; + }; + // HTML5 input type="range" shim - called onload or onDomReady + var init = function() { + var inputs = document.getElementsByTagName("input"), + options, + defs; + + for(var i = 0, inp; inp = inputs[i]; i++) { + + if(inp.tagName.toLowerCase() == "input" && + (getAttribute(inp,"type") && getAttribute(inp,"type").toLowerCase() == "range") && + (getAttribute(inp, "min") && getAttribute(inp, "min").search(fpRegExp) != -1 || + getAttribute(inp, "max") && getAttribute(inp, "max").search(fpRegExp) != -1 || + getAttribute(inp, "step") && getAttribute(inp, "step").search(/^(any|([0-9]+(\.[0-9]+){0,1}))$/i) != -1 + )) { + + // Skip elements that have already been created are are resident in the DOM + if(inp.id && document.getElementById("fd-slider-"+inp.id)) { + continue; + // Destroy elements that have already been created but not resident in the DOM + } else if(inp.id && !document.getElementById("fd-slider-"+inp.id)) { + destroySingleSlider(inp.id); + } + + // Create an id for the form element if necessary + if(!inp.id) { + inp.id = "fd-slider-form-elem-" + uniqueid++; + } + + // Basic option Object + options = { + inp: inp, + callbacks: [], + animation: html5Animation, + vertical: getAttribute(inp, "data-fd-slider-vertical") ? true : (inp.offsetHeight > inp.offsetWidth), + classNames: getAttribute(inp, "data-fd-slider-vertical"), + html5Shim: true + }; + + if(options.vertical && !getAttribute(inp, "data-fd-slider-vertical")) { + options.inpHeight = inp.offsetHeight; + } + + defs = getInputAttributes(inp); + + options.min = defs.min; + options.max = defs.max; + options.step = defs.step; + options.precision = String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0; + options.maxStep = options.step * 2; + + destroySingleSlider(options.inp.id); + sliders[options.inp.id] = new fdRange(options); + } + } + + return true; + }; + var getInputAttributes = function(inp) { + return { + "min":+(getAttribute(inp, "min") || 0), + "max":+(getAttribute(inp, "max") || 100), + "step":+(getAttribute(inp, "step").search(stepRegExp) != -1 ? inp.getAttribute("step") : 1) + }; + }; + var destroySingleSlider = function(id) { + if(id in sliders && sliders.hasOwnProperty(id)) { + sliders[id].destroy(); + delete sliders[id]; + return true; + } + return false; + }; + var destroyAllsliders = function(e) { + for(var slider in sliders) { + if(sliders.hasOwnProperty(slider)) { + sliders[slider].destroy(); + } + } + sliders = []; + }; + var unload = function(e) { + destroyAllsliders(); + sliders = null; + }; + var resize = function(e) { + for(var slider in sliders) { + if(sliders.hasOwnProperty(slider)) { + sliders[slider].onResize(); + } + } + }; + var rescanAttributes = function() { + for(var slider in sliders) { + if(sliders.hasOwnProperty(slider)) { + sliders[slider].rescan(); + } + } + }; + var onDomReady = function() { + removeOnLoadEvent(); + init(); + }; + var removeOnLoadEvent = function() { + removeEvent(window, "load", init); + }; + function fdRange(options) { + var inp = options.inp, + disabled = false, + tagName = inp.tagName.toLowerCase(), + min = +options.min, + max = +options.max, + rMin = +options.min, + rMax = +options.max, + range = Math.abs(max - min), + step = tagName == "select" ? 1 : +options.step, + maxStep = options.maxStep ? +options.maxStep : step * 2, + precision = options.precision || 0, + steps = Math.ceil(range / step), + scale = options.scale || false, + hideInput = !!options.hideInput, + animation = options.animation || "", + vertical = !!options.vertical, + callbacks = options.callbacks || {}, + classNames = options.classNames || "", + html5Shim = !!options.html5Shim, + defaultVal = max < min ? min : min + ((max - min) / 2), + resetDef = tagName == "select" ? inp.selectedIndex : inp.defaultValue || defaultVal, + forceValue = html5Shim || !!options.forceValue, + inpHeight = html5Shim && vertical && ("inpHeight" in options) ? options.inpHeight : false, + ariaFormat = !html5Shim && options.ariaFormat ? options.ariaFormat : false, + userSnap = !html5Shim && (tagName != "select") && ("userSnap" in options) ? !!options.userSnap : false, + userInput = false, + timer = null, + kbEnabled = true, + initialVal = tagName == "select" ? inp.selectedIndex : inp.value, + sliderH = 0, + sliderW = 0, + tweenX = 0, + tweenB = 0, + tweenC = 0, + tweenD = 0, + frame = 0, + x = 0, + y = 0, + rMaxPx = 0, + rMinPx = 0, + handlePos = 0, + destPos = 0, + mousePos = 0, + stepPx = 0, + userSet = false, + touchEvents = false, + outerWrapper, + innerWrapper, + ieBlur, + handle, + rangeBar, + bar; + + // For the reset event to work we have to set a defaultValue + if(tagName == "input" && forceValue && !inp.defaultValue) { + inp.defaultValue = getWorkingValueFromInput(); + } + + // Make sure we have a negative step if the max < min + if(max < min) { + step = -Math.abs(step); + maxStep = -Math.abs(maxStep); + } + + // Add the 100% scale mark if needs be. This is hacky. + if(scale) { + scale[100] = max; + } + + // Set the "userSet" variable programmatically for this slider + function valueSet(tf) { + tf = !!tf; + if(tf != userSet) { + userSet = tf; + valueToPixels(getWorkingValueFromInput()); + } + } + + function rescanAttrs() { + if(!useDOMAttrModEvt || tagName == "select") { + return; + } + + var defs = getInputAttributes(inp); + + if(defs.min == min && defs.max == max && defs.step == step) { + return; + } + + min = +defs.min; + max = +defs.max; + rMin = min; + rMax = max; + step = +defs.step; + range = Math.abs(max - min); + maxStep = step * 2; + steps = Math.ceil(range / step); + userSet = false; + setSliderRange(min, max); + } + + function disableSlider(noCallback) { + if(disabled && !noCallback) { + return; + } + + try { + setTabIndex(handle, -1); + removeEvent(handle, "focus", onFocus); + removeEvent(handle, "blur", onBlur); + + if(!isOpera) { + removeEvent(handle, "keydown", onKeyDown); + removeEvent(handle, "keypress", onKeyPress); + } else { + removeEvent(handle, "keypress", onKeyDown); + } + + removeEvent(outerWrapper, "mouseover", onMouseOver); + removeEvent(outerWrapper, "mouseout", onMouseOut); + removeEvent(outerWrapper, "mousedown", onMouseDown); + removeEvent(outerWrapper, "touchstart", onMouseDown); + + if(mouseWheelEnabled) { + if (window.addEventListener && !window.devicePixelRatio) window.removeEventListener('DOMMouseScroll', trackMouseWheel, false); + else { + removeEvent(document, "mousewheel", trackMouseWheel); + removeEvent(window, "mousewheel", trackMouseWheel); + } + } + } catch(err) {} + + removeClass(innerWrapper, "fd-slider-focused"); + removeClass(innerWrapper, "fd-slider-active"); + + addClass(innerWrapper, "fd-slider-disabled"); + outerWrapper.setAttribute("aria-disabled", true); + inp.disabled = disabled = true; + clearTimeout(timer); + + if(!noCallback) { + callback("disable"); + } + } + + function enableSlider(noCallback) { + if(!disabled && !noCallback) { + return; + } + + setTabIndex(handle, 0); + addEvent(handle, "focus", onFocus); + addEvent(handle, "blur", onBlur); + + if(!isOpera) { + addEvent(handle, "keydown", onKeyDown); + addEvent(handle, "keypress", onKeyPress); + } else { + addEvent(handle, "keypress", onKeyDown); + } + + addEvent(outerWrapper, "touchstart", onMouseDown); + addEvent(outerWrapper, "mousedown", onMouseDown); + addEvent(outerWrapper, "mouseover", onMouseOver); + addEvent(outerWrapper, "mouseout", onMouseOut); + + removeClass(innerWrapper, "fd-slider-disabled"); + outerWrapper.setAttribute("aria-disabled", false); + inp.disabled = disabled = touchEvents = false; + + if(!noCallback) { + callback("enable"); + } + } + + // Destroys a slider + function destroySlider() { + clearTimeout(timer); + ieBlur = bar = handle = outerWrapper = innerWrapper = timer = null; + callback("destroy"); + callbacks = null; + } + + // Calculates the pixel increment etc + function redraw() { + locate(); + // Internet Explorer requires the try catch as hidden + // elements throw errors + try { + var sW = outerWrapper.offsetWidth, + sH = outerWrapper.offsetHeight, + hW = handle.offsetWidth, + hH = handle.offsetHeight, + bH = bar.offsetHeight, + bW = bar.offsetWidth, + mPx = vertical ? sH - hH : sW - hW; + + stepPx = mPx / steps; + rMinPx = Math.max(scale ? percentToPixels(valueToPercent(rMin)) : Math.abs((rMin - min) / step) * stepPx, 0); + rMaxPx = Math.min(scale ? percentToPixels(valueToPercent(rMax)) : Math.abs((rMax - min) / step) * stepPx, Math.floor(vertical ? sH - hH : sW - hW)); + + sliderW = sW; + sliderH = sH; + + valueToPixels(forceValue ? getWorkingValueFromInput() : (tagName == "select" ? inp.selectedIndex : parseFloat(inp.value)), false); + + } catch(err) {} + callback("redraw"); + } + + // Calls a callback function + function callback(type) { + if(!html5Shim) { + if(callbacks.hasOwnProperty(type)) { + var cbObj = {"userSet":userSet, "disabled":disabled, "elem":inp, "value":tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value}; + + // Call all functions in sequence + for(var i = 0, func; func = callbacks[type][i]; i++) { + func.call(inp, cbObj); + } + } + } else if(type.match(/^(blur|focus|change)$/i)) { + var e; + if(typeof(document.createEvent) != 'undefined') { + e = document.createEvent('HTMLEvents'); + e.initEvent(type, true, true); + inp.dispatchEvent(e); + } else if(typeof(document.createEventObject) != 'undefined') { + try { + e = document.createEventObject(); + inp.fireEvent('on' + type.toLowerCase(), e); + } catch(err){ } + } + } + } + + // FOCUS & BLUR events + function onFocus(e) { + addClass(innerWrapper, 'fd-slider-focused'); + + // Is the value said to have been set by the user onfocus + if(varSetRules.onfocus) { + userSet = true; + valueToPixels(getWorkingValueFromInput()); + } + + // If mousewheel events required then add them + if(mouseWheelEnabled) { + addEvent(window, 'DOMMouseScroll', trackMouseWheel); + addEvent(document, 'mousewheel', trackMouseWheel); + if(!isOpera) { + addEvent(window, 'mousewheel', trackMouseWheel); + } + } + + callback("focus"); + return true; + } + + function onBlur(e) { + removeClass(innerWrapper, 'fd-slider-focused'); + + // Remove mousewheel events if necessary + if(mouseWheelEnabled) { + removeEvent(document, 'mousewheel', trackMouseWheel); + removeEvent(window, 'DOMMouseScroll', trackMouseWheel); + if(!isOpera) { + removeEvent(window, 'mousewheel', trackMouseWheel); + } + } + + kbEnabled = true; + callback("blur"); + } + + // MOUSEWHEEL events + function trackMouseWheel(e) { + if(!kbEnabled) { + return; + } + + e = e || window.event; + var delta = 0, + value; + + if (e.wheelDelta) { + delta = e.wheelDelta/120; + // Older versions of Opera require a small hack to inverse the delta + if (isOpera && window.opera.version() < 9.2) { + delta = -delta; + } + } else if(e.detail) { + delta = -e.detail/3; + } + + if(vertical) { + delta = -delta; + } + + if(delta) { + value = getWorkingValueFromInput(); + value += (delta < 0) ? -step : step; + userSet = true; + valueToPixels(getValidValue(value)); + } + + preventDefault(e); + } + + // KEYBOARD events + function onKeyPress(e) { + e = e || window.event; + // Let all non-hijacked keyboard events pass + if((e.keyCode >= 33 && e.keyCode <= 40) || !kbEnabled || e.keyCode == 45 || e.keyCode == 46) { + return stopEvent(e); + } + return true; + } + + function onKeyDown(e) { + if(!kbEnabled) { + return true; + } + + e = e || window.event; + var kc = e.keyCode !== null ? e.keyCode : e.charCode, + value; + + if(kc < 33 || (kc > 40 && (kc != 45 && kc != 46))) { + return true; + } + + value = getWorkingValueFromInput(); + + if( kc == 37 || kc == 40 || kc == 46 || kc == 34) { + // left, down, ins, page down + value -= (e.ctrlKey || kc == 34 ? +maxStep : +step); + } else if( kc == 39 || kc == 38 || kc == 45 || kc == 33) { + // right, up, del, page up + value += (e.ctrlKey || kc == 33 ? +maxStep : +step); + } else if( kc == 35 ) { + // max + value = rMax; + } else if( kc == 36 ) { + // min + value = rMin; + } + + userSet = true; + valueToPixels(getValidValue(value)); + + callback("update"); + + // Opera doesn't let us cancel key events so the up/down arrows and home/end buttons will scroll the screen - which sucks + preventDefault(e); + } + + // MOUSE & TOUCH events + + function onMouseOver(e) { + addClass(innerWrapper, 'fd-slider-hover'); + } + + function onMouseOut(e) { + // Should really check we are not still in the slider + removeClass(innerWrapper, 'fd-slider-hover'); + } + + // Mousedown on the slider + function onMouseDown(e) { + e = e || window.event; + + // Stop page scrolling + preventDefault(e); + + // Grab the event target + var targ; + if (e.target) { + targ = e.target; + } else if (e.srcElement) { + targ = e.srcElement; + } + if(targ && targ.nodeType == 3) { + targ = targ.parentNode; + } + + // Are we using touchEvents + if(e.touches) { + // Skip gestures + if(e.targetTouches && e.targetTouches.length != 1) { + return false; + } + + e = e.touches[0]; + touchEvents = true; + } + + // Stop any animation timers + clearTimeout(timer); + timer = null; + + // Not keyboard enabled + kbEnabled = false; + + // User has set a value + userSet = true; + + // Handle mousedown - initiate drag + if(targ.className.search("fd-slider-handle") != -1) { + mousePos = vertical ? e.clientY : e.clientX; + handlePos = parseInt(vertical ? handle.offsetTop : handle.offsetLeft)||0; + + // Set a value on first click even if no movement + trackMouse(e); + + if(!touchEvents) { + addEvent(document, 'mousemove', trackMouse); + addEvent(document, 'mouseup', stopDrag); + } else { + addEvent(document, 'touchmove', trackMouse); + addEvent(document, 'touchend', stopDrag); + // Remove mouseEvents to stop them firing after the touch event + removeEvent(outerWrapper, "mousedown", onMouseDown); + } + + addClass(innerWrapper, 'fd-slider-active'); + addClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); + + callback("dragstart"); + + // Wrapper mousedown - initiate animation to click point + } else { + locate(); + + var posx = 0; + + if(e.pageX || e.pageY) { + posx = vertical ? e.pageY : e.pageX; + } else if (e.clientX || e.clientY) { + posx = vertical ? e.clientY + document.body.scrollTop + document.documentElement.scrollTop : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + } + + posx -= vertical ? y + Math.round(handle.offsetHeight / 2) : x + Math.round(handle.offsetWidth / 2); + posx = snapToPxValue(posx); + + // Tween animation to click point + if(animation == "tween") { + addClass(innerWrapper, 'fd-slider-active'); + tweenTo(posx); + // Progressive increment to click point + } else if(animation == "timed") { + addClass(innerWrapper, 'fd-slider-active'); + addEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); + destPos = posx; + onTimer(); + // Immediate jump to click point + } else { + pixelsToValue(posx); + //addEvent(document, touchEvents ? 'touchend' : 'mouseup', onMouseUp); + } + } + + return false; + } + + // Progressive increment to click point - clear the animation timer and remove the mouseup/touchend event + function onDocMouseUp( e ) { + e = e || window.event; + + preventDefault(e); + removeEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); + removeClass(innerWrapper, "fd-slider-active"); + + clearTimeout(timer); + timer = null; + kbEnabled = true; + + return false; + } + + // Mouseup or touchend event on the document to stop drag + function stopDrag(e) { + e = e || window.event; + + preventDefault(e); + + if(touchEvents) { + removeEvent(document, 'touchmove', trackMouse); + removeEvent(document, 'touchend', stopDrag); + } else { + removeEvent(document, 'mousemove', trackMouse); + removeEvent(document, 'mouseup', stopDrag); + } + + kbEnabled = true; + removeClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); + removeClass(innerWrapper, "fd-slider-active"); + + callback("dragend"); + + return false; + } + + // Mousemove or touchmove event on the drag handle + function trackMouse(e) { + e = e || window.event; + + preventDefault(e); + + if(e.touches) { + // Skip gestures + if(e.targetTouches && e.targetTouches.length != 1) { + return false; + } + e = e.touches[0]; + } + + pixelsToValue(snapToPxValue(handlePos + (vertical ? e.clientY - mousePos : e.clientX - mousePos))); + + return false; + } + + // Increments the slider by "inc" steps + function increment(inc) { + var value = getWorkingValueFromInput(); + userSet = true; + value += inc * step; + valueToPixels(getValidValue(value)); + } + + // Attempts to locate the on-screen position of the slider + function locate(){ + var curleft = 0, + curtop = 0, + obj = outerWrapper; + + // Try catch for IE's benefit + try { + do { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + } while(obj = obj.offsetParent); + } catch(err) {} + x = curleft; + y = curtop; + } + + // Used during the progressive animation to click point + function onTimer() { + var xtmp = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); + xtmp = Math.round((destPos < xtmp) ? Math.max(destPos, Math.floor(xtmp - stepPx)) : Math.min(destPos, Math.ceil(xtmp + stepPx))); + + pixelsToValue(snapToPxValue(xtmp)); + if(xtmp != destPos) { + timer = setTimeout(onTimer, steps > 20 ? 50 : 100); + } else { + kbEnabled = true; + removeClass(innerWrapper, "fd-slider-active"); + callback("finalise"); + } + } + + var tween = function(){ + frame++; + var c = tweenC, + d = 20, + t = frame, + b = tweenB, + x = Math.ceil((t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b); + + pixelsToValue(t == d ? tweenX : x); + + if(t!=d) { + // Call the "move" callback on each animation increment + callback("move"); + timer = setTimeout(tween, 20); + } else { + clearTimeout(timer); + timer = null; + kbEnabled = true; + + removeClass(innerWrapper, "fd-slider-focused"); + removeClass(innerWrapper, "fd-slider-active"); + + // Call the "finalise" callback whenever the animation is complete + callback("finalise"); + } + }; + + function tweenTo(tx){ + kbEnabled = false; + tweenX = parseInt(tx, 10); + tweenB = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); + tweenC = tweenX - tweenB; + tweenD = 20; + frame = 0; + + if(!timer) { + timer = setTimeout(tween, 20); + } + } + + // Returns a value within the range & sets the userSet var + // i.e. has the user entered a valid value + function checkValue(value) { + if(isNaN(value) || value === "" || typeof value == "undefined") { + userSet = false; + return defaultVal; + } else if(value < Math.min(rMin,rMax)) { + userSet = false; + return Math.min(rMin,rMax); + } else if(value > Math.max(rMin,rMax)) { + userSet = false; + return Math.max(rMin,rMax); + } + userSet = true; + return value; + } + + // Returns a value within a range - uses the form element value as base + function getWorkingValueFromInput() { + return getValidValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + } + + // Returns a value within the range + function getValidValue(value) { + return (isNaN(value) || value === "" || typeof value == "undefined") ? defaultVal : Math.min(Math.max(value, Math.min(rMin,rMax)), Math.max(rMin,rMax)); + } + + // Calculates value according to pixel position of slider handle + function pixelsToValue(px) { + var val = getValidValue(scale ? percentToValue(pixelsToPercent(px)) : vertical ? max - (Math.round(px / stepPx) * step) : min + (Math.round(px / stepPx) * step)); + + handle.style[vertical ? "top" : "left"] = (px || 0) + "px"; + redrawRange(); + setInputValue((tagName == "select" || step == 1) ? Math.round(val) : val); + } + + // Calculates pixel position according to form element value + function valueToPixels(val, updateInputValue) { + var clearVal = false, + value; + + // Allow empty values for non-polyfill sliders + if((typeof val === "undefined" || isNaN(val) || val === "") && tagName == "input" && !forceValue) { + value = defaultVal; + clearVal = true; + userSet = false; + } else { + value = checkValue(val); + } + + handle.style[vertical ? "top" : "left"] = (scale ? percentToPixels(valueToPercent(value)) : vertical ? Math.round(((max - value) / step) * stepPx) : Math.round(((value - min) / step) * stepPx)) + "px"; + redrawRange(); + if(typeof updateInputValue !== false) { + setInputValue(clearVal ? "" : value); + } + } + + // Rounds a pixel value to the nearest "snap" point on the slider scale + function snapToPxValue(px) { + if(scale) { + return Math.max(Math.min(rMaxPx, px), rMinPx); + } else { + var rem = px % stepPx; + if(rem && rem >= (stepPx / 2)) { + px += (stepPx - rem); + } else { + px -= rem; + } + + if(px < Math.min(Math.abs(rMinPx), Math.abs(rMaxPx))) { + px = Math.min(Math.abs(rMinPx), Math.abs(rMaxPx)); + } else if(px > Math.max(Math.abs(rMinPx), Math.abs(rMaxPx))) { + px = Math.max(Math.abs(rMinPx), Math.abs(rMaxPx)); + } + + return Math.min(Math.max(px, 0), rMaxPx); + } + } + + // Calculates a value according to percentage of distance handle has travelled + function percentToValue(pct) { + var st = 0, + fr = min, + value; + + for(var s in scale) { + if(!scale.hasOwnProperty(s)) { + continue; + } + + if(pct >= st && pct <= +s ) { + value = fr + ((pct - st) * (+scale[s] - fr) ) / (+s - st); + } + + st = +s; + fr = +scale[s]; + } + + return value; + } + + // Calculates the percentage handle position according to form element value + function valueToPercent(value) { + var st = 0, + fr = min, + pct = 0; + + for(var s in scale) { + if(!scale.hasOwnProperty(s)) { + continue; + } + + if(value >= fr && value <= +scale[s]){ + pct = st + (value - fr) * (+s - st) / (+scale[s] - fr); + } + + st = +s; + fr = +scale[s]; + } + + return pct; + } + + function percentToPixels(percent) { + return ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - handle[vertical ? "offsetHeight" : "offsetWidth"]) / 100) * percent; + } + + function pixelsToPercent(pixels) { + return pixels / ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - outerWrapper[handle ? "offsetHeight" : "offsetWidth"]) / 100); + } + + // Sets the form element with a valid value + function setInputValue(val) { + // The update callback doesn't mean the input value has changed + callback("update"); + + // If the user has not set this value or has entered an incorrect value then set a class + // to enable styling of the slider + if(!userSet) { + addClass(innerWrapper, "fd-slider-no-value"); + } else { + removeClass(innerWrapper, "fd-slider-no-value"); + } + + if(tagName == "select") { + try { + val = parseInt(val, 10); + if(inp.selectedIndex === val) { + updateAriaValues(); + return; + } + inp.options[val].selected = true; + } catch (err) {} + } else { + if(val !== "" && !userInput) { + val = (min + (Math.round((+val - min) / step) * step)).toFixed(precision); + } + if(inp.value === val) { + updateAriaValues(); + return; + } + inp.value = val; + } + + updateAriaValues(); + callback("change"); + } + + function checkInputValue(value) { + return !(isNaN(value) || value === "" || value < Math.min(rMin,rMax) || value > Math.max(rMin,rMax)); + } + + function setSliderRange(newMin, newMax) { + if(rMin > rMax) { + newMin = Math.min(min, Math.max(newMin, newMax)); + newMax = Math.max(max, Math.min(newMin, newMax)); + rMin = Math.max(newMin, newMax); + rMax = Math.min(newMin, newMax); + } else { + newMin = Math.max(min, Math.min(newMin, newMax)); + newMax = Math.min(max, Math.max(newMin, newMax)); + rMin = Math.min(newMin, newMax); + rMax = Math.max(newMin, newMax); + } + + if(defaultVal < Math.min(rMin, rMax)) { + defaultVal = Math.min(rMin, rMax); + } else if(defaultVal > Math.max(rMin, rMax)) { + defaultVal = Math.max(rMin, rMax); + } + + handle.setAttribute("aria-valuemin", rMin); + handle.setAttribute("aria-valuemax", rMax); + + checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + redraw(); + } + + function redrawRange() { + if(noRangeBar) { + return; + } + if(vertical) { + rangeBar.style["height"] = Math.max(1, (bar.offsetHeight - handle.offsetTop)) + "px"; + } else { + rangeBar.style["width"] = Math.max(1, handle.offsetLeft) + "px"; + } + } + + function findLabel() { + var label = false, + labelList = document.getElementsByTagName('label'); + // loop through label array attempting to match each 'for' attribute to the id of the current element + for(var i = 0, lbl; lbl = labelList[i]; i++) { + // Internet Explorer requires the htmlFor test + if((lbl['htmlFor'] && lbl['htmlFor'] == inp.id) || (lbl.getAttribute('for') == inp.id)) { + label = lbl; + break; + } + } + + if(label && !label.id) { + label.id = inp.id + "_label"; + } + + return label; + } + + function updateAriaValues() { + var val = tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value, + valTxt = ariaFormat ? ariaFormat(val) : tagName == "select" ? (inp.options[inp.selectedIndex].text ? inp.options[inp.selectedIndex].text : val) : val; + + handle.setAttribute("aria-valuenow", val); + handle.setAttribute("aria-valuetext", valTxt); + } + + function onInputChange(e) { + userSet = true; + userInput = userSnap; + valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + updateAriaValues(); + userInput = false; + } + + function onReset(e) { + if(tagName == "input") { + inp.value = inp.defaultValue; + } else { + inp.selectedIndex = resetDef; + } + checkValue(tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value); + redraw(); + updateAriaValues(); + } + + // Sets a tabindex attribute on an element, bends over for IE. + function setTabIndex(e, i) { + e.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", i); + e.tabIndex = i; + } + + (function() { + if(html5Shim || hideInput) { + addClass(inp, "fd-form-element-hidden"); + try { + // FF21 hack to change input type to text + if(inp.type != "range" && + getAttribute(inp, "type") == "range" && + document.defaultView.getComputedStyle(inp, null).getPropertyValue("display") == "inline-block") { + inp.type="number"; + } + } catch(err){} + } else { + addEvent(inp, 'change', onInputChange); + } + + // Add stepUp & stepDown methods to input element if using the html5Shim + if(html5Shim) { + inp.setAttribute("fd-range-enabled", 1); + inp.stepUp = function(n) { increment(n||1); }; + inp.stepDown = function(n) { increment(n||-1); }; + + if(useDOMAttrModEvt) { + addEvent(inp, typeof(inp.onpropertychange) == "object" ? "propertychange" : "DOMAttrModified", rescanAttrs); + } + } + + outerWrapper = document.createElement('span'); + outerWrapper.className = "fd-slider" + (vertical ? "-vertical " : " ") + classNames; + outerWrapper.id = "fd-slider-" + inp.id; + + if(vertical && inpHeight) { + outerWrapper.style.height = inpHeight + "px"; + } + + innerWrapper = document.createElement('span'); + innerWrapper.className = "fd-slider-wrapper" + (!html5Shim ? " fd-slider-no-value" : ""); + + ieBlur = document.createElement('span'); + ieBlur.className = "fd-slider-inner"; + + bar = document.createElement('span'); + bar.className = "fd-slider-bar"; + + if(fullARIA) { + handle = document.createElement('span'); + } else { + handle = document.createElement('a'); + handle.setAttribute("href", "#"); + addEvent(handle, "click", stopEvent); + } + + setTabIndex(handle, 0); + + handle.className = "fd-slider-handle"; + handle.appendChild(document.createTextNode(String.fromCharCode(160))); + + innerWrapper.appendChild(ieBlur); + + if(!noRangeBar) { + rangeBar = document.createElement('span'); + rangeBar.className = "fd-slider-range"; + innerWrapper.appendChild(rangeBar); + } + + innerWrapper.appendChild(bar); + innerWrapper.appendChild(handle); + outerWrapper.appendChild(innerWrapper); + + inp.parentNode.insertBefore(outerWrapper, inp); + + if(isOpera || /*@cc_on!@*/!true) { + handle.unselectable = "on"; + bar.unselectable = "on"; + ieBlur.unselectable = "on"; + outerWrapper.unselectable = "on"; + innerWrapper.unselectable = "on"; + if(!noRangeBar) { + rangeBar.unselectable = "on"; + } + } + + // Add ARIA accessibility info programmatically + outerWrapper.setAttribute("role", "application"); + + handle.setAttribute("role", "slider"); + handle.setAttribute("aria-valuemin", tagName == "select" ? inp.options[0].value : min); + handle.setAttribute("aria-valuemax", tagName == "select" ? inp.options[inp.options.length - 1].value : max); + + var lbl = findLabel(); + if(lbl) { + handle.setAttribute("aria-labelledby", lbl.id); + handle.id = "fd-slider-handle-" + inp.id; + /*@cc_on@*/ + /*@if(@_win32) + lbl.setAttribute("htmlFor", handle.id); + @else @*/ + lbl.setAttribute("for", handle.id); + /*@end@*/ + } + + // Are there page instructions + if(document.getElementById(describedBy)) { + handle.setAttribute("aria-describedby", describedBy); + } + + // Is the form element initially disabled + if(inp.getAttribute("disabled") === true || inp.getAttribute("disabled") == "disabled") { + disableSlider(true); + } else { + enableSlider(true); + } + + // Does an initial form element value mean the user has set a valid value? + // Also called onload in case browsers have automatically set the input value + if(varSetRules.onvalue) { + userSet = true; + checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + } + + // Catch form reset events + if(inp.form) { + addEvent(inp.form, "reset", onReset); + } + + updateAriaValues(); + callback("create"); + redraw(); + })(); + + return { + onResize: function(e) { if(outerWrapper.offsetHeight != sliderH || outerWrapper.offsetWidth != sliderW) { redraw(); } }, + destroy: function() { destroySlider(); }, + reset: function() { valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); }, + stepUp: function(n) { increment(Math.abs(n)||1); }, + stepDown: function(n) { increment(-Math.abs(n)||-1); }, + increment: function(n) { increment(n); }, + disable: function() { disableSlider(); }, + enable: function() { enableSlider(); }, + setRange: function(mi, mx) { setSliderRange(mi, mx); }, + getValueSet: function() { return !!userSet; }, + setValueSet: function(tf) { valueSet(tf); }, + rescan: function() { rescanAttrs(); }, + checkValue: function() { if(varSetRules.onvalue) { userSet = true; checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); } updateAriaValues(); redraw(); } + }; + } + + addEvent(window, "load", init); + addEvent(window, "load", function() { setTimeout(function() { var slider; for(slider in sliders) { sliders[slider].checkValue(); } }, 0); }); + addEvent(window, "resize", resize); + addEvent(window, "unload", unload); + + // Have we been passed JSON within the including script tag + (function() { + var scriptFiles = document.getElementsByTagName('script'), + json = parseJSON(String(scriptFiles[scriptFiles.length - 1].innerHTML).replace(/[\n\r\s\t]+/g, " ").replace(/^\s+/, "").replace(/\s+$/, "")); + + if(typeof json === "object" && !("err" in json)) { + affectJSON(json); + } + })(); + + // Add oldie class if needed for IE < 9 + /*@cc_on@*/ + /*@if (@_jscript_version < 9) + addClass(document.documentElement, "oldie"); + /*@end@*/ + + return { + rescanDocument: init, + createSlider: function(opts) { return createSlider(opts); }, + onDomReady: function() { onDomReady(); }, + destroyAll: function() { destroyAllsliders(); }, + destroySlider: function(id) { return destroySingleSlider(id); }, + redrawAll: function() { resize(); }, + addEvent: addEvent, + removeEvent: removeEvent, + stopEvent: stopEvent, + increment: function(id, numSteps) { if(!sliderExists(id)) { return false; } sliders[id].increment(numSteps); }, + stepUp: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepUp(Math.abs(n)||1); }, + stepDown: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepDown(-Math.abs(n)||-1); }, + setRange: function(id, newMin, newMax) { if(!sliderExists(id)) { return false; } sliders[id].setRange(newMin, newMax); }, + updateSlider: function(id) { if(!sliderExists(id)) { return false; } sliders[id].onResize(); sliders[id].reset(); }, + disable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].disable(); }, + enable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].enable(); }, + getValueSet: function() { return getValueSet(); }, + setValueSet: function(a, tf) { if(!sliderExists(id)) { return false; } setValueSet(a, tf); }, + setGlobalVariables: function(json) { affectJSON(json); }, + removeOnload: function() { removeOnLoadEvent(); }, + rescanAttributes: rescanAttributes + }; +})(); diff --git a/static/app/scripts/graphs.js b/static/app/scripts/graphs.js new file mode 100644 index 0000000..7c05998 --- /dev/null +++ b/static/app/scripts/graphs.js @@ -0,0 +1,186 @@ +/* Extend jquery */ +(function ( $ ) { + $.fn.graph = function(action, options) { + // These are the defaults + var settings = $.extend({ + width: undefined, + height: undefined, + animation_duration: 1000 // ms + }, options ); + /* The slug of each Graph object map to a function in the graphs object */ + var graphs = { + treatment: function(element) { + $(element).highcharts({ + chart: { + type: 'column', + width: settings.width, + height: settings.height, + animation: { + duration: settings.animation_duration + } + }, + title: { + text: 'Antall behandlinger' + }, + xAxis: { + title: { + text: 'År' + }, + minRange : 30 * 24 * 3600 * 1000, // + minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year + type: 'datetime' + }, + yAxis: { + title: { + text: 'Antall behandlinger' + } + + }, + series: [{ + name: 'Antall behandlinger', + data: [ + [Date.UTC(2007, 1), 35000], + [Date.UTC(2008, 1), 40000], + [Date.UTC(2009, 1), 60000], + [Date.UTC(2010, 1), 67000], + [Date.UTC(2011, 1), 70000], + [Date.UTC(2012, 1), 78000], + [Date.UTC(2013, 1), 97000], + [Date.UTC(2014, 1), 109000]], + enabled: false + + }], + legend: { + enabled: false + } + }); + }, + treatment_distribution: function(element) { + var last_year = new Date().getFullYear() - 1; + $(element).highcharts({ + chart: { + type: 'column', + width: settings.width, + height: settings.height, + animation: { + duration: settings.animation_duration + } + }, + title: { + text: 'Fordeling behandlinger' + }, + xAxis: { + title: { + text: 'Måned' + }, + minRange : 30 * 24 * 3600 * 1000, // + minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year + type: 'datetime' + }, + yAxis: { + title: { + text: 'Fordeling' + } + + }, + series: [{ + name: 'Preeksisterende', + data: [ + [Date.UTC(last_year, 0), 2], + [Date.UTC(last_year, 1), 5], + [Date.UTC(last_year, 2), 10], + [Date.UTC(last_year, 3), 20], + [Date.UTC(last_year, 4), 40], + [Date.UTC(last_year, 5), 70], + [Date.UTC(last_year, 6), 40], + [Date.UTC(last_year, 7), 40], + [Date.UTC(last_year, 8), 40]] + }, + { + name: 'Nye lidelser', + data: [ + [Date.UTC(last_year, 0), 8], + [Date.UTC(last_year, 1), 10], + [Date.UTC(last_year, 2), 15], + [Date.UTC(last_year, 3), 18], + [Date.UTC(last_year, 4), 20], + [Date.UTC(last_year, 5), 30], + [Date.UTC(last_year, 6), 40], + [Date.UTC(last_year, 7), 40], + [Date.UTC(last_year, 8), 40]] + }], + plotOptions: { + column: { + stacking: 'normal' + } + } + }); + }, + num_insured: function(element) { + $(element).highcharts({ + chart: { + type: 'column', + width: settings.width, + height: settings.height, + animation: { + duration: settings.animation_duration + } + }, + title: { + text: 'Antall forsikrede (behandlingsforsikring) per 30. juni 2003-2014' + }, + xAxis: { + title: { + text: 'År' + }, + tickInterval: Date.UTC(1902, 0, 1) - Date.UTC(1901, 0, 1), // A year + year: '%Y', + type: 'datetime' + }, + yAxis: { + title: { + text: 'Antall forsikrede' + } + + }, + series: [{ + name: 'Antall forsikrede', + data: [ + [Date.UTC(2003, 0), 14587], + [Date.UTC(2004, 0), 20634], + [Date.UTC(2005, 0), 35418], + [Date.UTC(2006, 0), 42073], + [Date.UTC(2007, 0), 74435], + [Date.UTC(2008, 0), 97661], + [Date.UTC(2009, 0), 115651], + [Date.UTC(2010, 0), 141742], + [Date.UTC(2011, 0), 233739], + [Date.UTC(2012, 0), 357468], + [Date.UTC(2013, 0), 404320], + [Date.UTC(2014, 0), 437137]], + enabled: false + + }], + legend: { + enabled: false + } + }); + } + }; + + /* What do do? */ + if(action == 'load') { + /* For each element get attr and load appropriate graph */ + return this.each(function() { + var slug = $(this).attr('data-graph-slug'); + // Create a graphs[slug] of this. + graphs[slug](this); + }); + } else if(action == 'get') { + /* Not used + return Highcharts.charts[loaded_graphs[slug].data('highchartsChart')]; + */ + } + }; + +}( jQuery )); diff --git a/static/app/scripts/presentation_edit.js b/static/app/scripts/presentation_edit.js new file mode 100644 index 0000000..4ce5f7a --- /dev/null +++ b/static/app/scripts/presentation_edit.js @@ -0,0 +1,121 @@ +function get_offset(col, grid_height, min_widget_height) { + var num_slides = $('.slide[data-col="'+ col +'"]').length; + return (grid_height - (num_slides * min_widget_height)) * -1; +} + +/* Push add buttons up x px, close to the lowest slide in its section */ +function reposition_add_buttons(min_widget_height) { + var max_rows = _.max($(".slide"), function(slide){ return parseInt($(slide).attr('data-row')); }); + var grid_height = $(max_rows).attr('data-row') * min_widget_height; + + $(".slide-add").each(function() { + var offset = get_offset($(this).attr('data-col'), grid_height, min_widget_height); + $(this).css({ top: offset }); + }); +} +$(function(){ + // TODO: on document ready, to load: loading icon + var margin_x = 8; + var margin_y = 4; + var csrf_token = $.cookie('csrftoken'); + var grid = $(".gridster ul").gridster({ + widget_selector: "li.slide", + widget_margins: [margin_x, margin_y], + widget_base_dimensions: [113, 80], + min_cols: 6, + serialize_params: function($w, wgd) { + return { + slide: $w.attr('data-slide'), + section: $('.sections li[data-col="'+ wgd.col +'"]').attr('data-section'), + order: wgd.row + }; + }, + draggable: { + // https://github.com/ducksboard/gridster.js/issues/161 + handle: 'img', // FIXME: Edit link is not working on touch + stop: function() { + /* reposition add buttons */ + reposition_add_buttons(this.min_widget_height); + + /* Save grid order */ + var grid = this.serialize_changed(); + + var slides = []; + for(var i in grid ) { + slides.push({ name: "slide-order-"+grid[i].slide, value: grid[i].order }); + slides.push({ name: "slide-section-"+grid[i].slide, value: grid[i].section }); + } + /* Prepare data */ + var data = $("#presentation-form").serializeArray(); + data = data.concat(slides); + /* http post json */ + var url = $("#presentation").attr('data-save-url'); + $.ajax({ + type: "POST", + url: url, + data: data, + async: false, // FIXME: Make async + headers: { + 'X-CSRFToken': csrf_token + }, + success: function (result,l,o) { + if(result !== undefined && result.success) { + /* redirect to edit url */ + window.location = "/slideshow/" + result.presentation_id + "/edit/"; + } else { + //console.log("Saved"); //FIXME notify + } + }, + error: function (request, text_status, error_thrown) { + console.log("uffda..."); //FIXME notify + } + }); + } + } + }); + /* Note: gridster api add, remove, serialize */ + var gridster = grid.data('gridster'); + + /* reposition add buttons */ + reposition_add_buttons(gridster.min_widget_height); + + /* Datepicker */ + $("#id_datetime").datepicker({ + dateFormat: "yy-mm-dd" + }); + /* Disable slide controls */ + $(".slide-toggle").on('click', function(e) { + /* Set slide.active=false */ + var that = $(this); + var current_slide = $(this).parent().parent(); + var new_state = current_slide.hasClass("disabled"); + var url = $(this).attr('data-save-url'); + $.ajax({ + type: "PATCH", + url: url, + data: { + active: new_state + }, + headers: { + 'X-CSRFToken': csrf_token + }, + success: function (result,l,o) { + + /* toggle 'disabled' class */ + current_slide.toggleClass("disabled"); + /* switch icons class */ + var icon = that.find("i"); + if(icon.hasClass("fa-square-o")) { + icon.removeClass("fa-square-o").addClass("fa-check-square-o"); + } else { + icon.removeClass("fa-check-square-o").addClass("fa-square-o"); + } + }, + error: function (request, text_status, error_thrown) { + console.log("uffda..."); //FIXME notify + } + }); + + }); + +}); \ No newline at end of file diff --git a/static/app/scripts/presentation_list.js b/static/app/scripts/presentation_list.js new file mode 100644 index 0000000..5edc624 --- /dev/null +++ b/static/app/scripts/presentation_list.js @@ -0,0 +1,9 @@ + +$(function(){ + //var options = { +    // valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] +    //}; + +    //var featureList = new List('presentation-table-sortable', options); + //featureList.sort('waittime', { asc: false }); +}); diff --git a/static/app/scripts/product_calculator.js b/static/app/scripts/product_calculator.js new file mode 100644 index 0000000..1036188 --- /dev/null +++ b/static/app/scripts/product_calculator.js @@ -0,0 +1,541 @@ +$(document).ready( function() { + /* Slide: Product calculator */ + /* + * TODO: set discount based on url or user/session data + * + * */ + function set_progress(percent) { + if( percent < 1 || percent > 100 ) { + return; + } + $(".stb-progress .meter").css('width', percent+"%"); + } + function product_select(products, treatments, counceling) { + /* Searches products and returns the correct price */ + //console.log(products, treatments, counceling); + var selected = products; + if(counceling !== undefined) { + selected = _.filter(selected, function(product) { + return product.counceling_service == counceling; + }); + } + if(selected.length == 1) { + return selected[0]; + } + if(treatments !== undefined) { + selected = _.filter(selected, function(product) { + return product.treatments == treatments; + }); + } + if(selected.length == 1) { + return selected[0]; + } + //console.log("Fant ingen produkter, returnerer siste"); + return products[products.length-1]; + } + //function filter_product_risk(documents, product_order) { + // /* filter based on product risk variables */ + // var product_risk_variable_attrs = [ + // 'eligible_industry_discount', + // 'has_existing_insurance', + // 'employees', + // 'addon_psychiatric_treatment']; + + // /* which variables are set? */ + // var product_risk_variables = _.filter(product_risk_variable_attrs, function(attr) { + // return product_order[attr] !== undefined; + // }); + // //console.log("product risk variables: ", product_risk_variables); + + // /* filter based on vars in product_risk_variables and product_order + // * all must match */ + // documents = _.filter(documents, function(doc){ + // //console.log("looking at: ", doc.name, "(", doc.id, ")"); + // // filter when not specified + // if(!doc.product_risk_variables.length) { + // return false; + // } + + // /* Loop over the product_risks attached to this document */ + // var doc_matches = _.map(doc.product_risk_variables, function(variables, index, list) { + // /* Loop over each variable in the list of risks */ + // var var_matches = _.map(product_risk_variables, function(element) { + // //console.log("looping document risk vars: ", element, product_order[element], variables[element], variables); + // // num employees special case + // if(element == 'employees' && (product_order[element] > variables['employees_max'] || product_order[element] < variables['employees_min'])) { + // return false + // } + // else if(product_order[element] != variables[element] && element != 'employees') { + // return false; // drop document + // } + // return true; + // }); + // // All attributes in the product_order must match with variables + // return _.every(var_matches); + // }); + // // Need just one match to keep the document + // return _.some(doc_matches); + // }); + // return documents; + //} + //function filter_individual_risk(documents, product_order) { + // //console.log("individual risk variables: ", product_order.individual_term_employees); + // /* Filter based on age ranges */ + // var ages = _.map(product_order.individual_term_employees, function(employee) { + // return employee.age; + // }); + // /* Filter documents not referencing at least one individual risk variable matching the specified ages */ + // documents = _.filter(documents, function(doc) { + // // filter when not specified + // // Note: Unsure if this is correct + // if(!doc.employee_risk_variables.length) { + // return false; + // } + // var matches = _.map(doc.employee_risk_variables, function(variables, index, list) { + // var age_matches = _.map(ages, function(age) { + // return age >= variables.age_min && age <= variables.age_max; + // }); + // return _.some(age_matches); // matching at least one age + // }); + // return _.some(matches); //matching at least one risk variable + // }); + // return documents; + //} + //function filter_documents(documents, product_order) { + // /* Filter based on product selection + // * Note: only filters by product if below 100 employees */ + // if(product_order.employees < 100) { + // var documents = _.filter(documents, function(doc){ + // var product_ids = _.map(doc.products, function(product) { return product.id; }); + // return _.contains(product_ids, product_order.product.id); + // }); + + // if(product_order.employees >=1 && product_order.employees <= 4 && !product_order.eligible_industry_discount) { + // documents = filter_individual_risk(documents, product_order); + // } + // else { + // documents = filter_product_risk(documents, product_order); + // } + // } else { + // /* Filter based on dummy no-product */ + // documents = _.filter(documents, function(doc){ + // var product_slugs = _.map(doc.products, function(product) { return product.slug; }); + // return _.contains(product_slugs, 'no-product'); + // }); + // + // } + // return documents; + // + //} + //function update_document_list(documents) { + // if(documents.length == 0) { + // $(".product-calculator .documents-table").html("Fillern, det er ingen dokumenter knyttet til dette produktet og valgte variable :'("); + // return; + // } + // var html = ""; + // _.each(documents, function(doc) { + // html += ''; + // }); + // html += "
NavnType
'+ doc.name +''+ doc.category +'
"; + // $(".product-calculator .documents-table").html(html); + //} + function get_price_individual(product, product_order) { + /* Need a valid product */ + if(product === undefined || product.employee_risk_variables.length === 0) { + return -1; + } + /* Invidual risk */ + var has_existing_insurance = false; + if( product_order.has_existing_insurance !== undefined) { + has_existing_insurance = product_order.has_existing_insurance; + } + /* Get list of prices for each employee */ + var prices = _.map(product_order.individual_term_employees, function(employee) { + /* Filter by employee-age */ + var variation = _.find(product.employee_risk_variables, function(variation) { + if(employee.age >= variation.age_min && employee.age <= variation.age_max) { + return true; + } + return false; + }); + return variation.price; + }); + return prices; + } + + function get_price(product, product_order) { + /* Group risk */ + var price = 0; + var has_existing_insurance = false; + if( product_order.has_existing_insurance !== undefined) { + has_existing_insurance = product_order.has_existing_insurance; + } + + /* Filter by boolean values */ + var variations = _.where(product.product_risk_variables, { + eligible_industry_discount: product_order.eligible_industry_discount, + has_existing_insurance: has_existing_insurance, + }); + /* Filter by num employees */ + variation = _.filter(variations, function(variation) { + if(variation.employees_max == product_order.employees ) { + return true; + } + }); + if(variation.length >= 1) { + price = parseInt(variation[0].price); + } else { + /* Error: Missing product data in db */ + price = -1; + } + /* include price for psychiatric treatment addon */ + // FIXME price is static. + if(product_order.addon_psychiatric_treatment !== undefined && product_order.addon_psychiatric_treatment) { + price += 204; + } + + return price; + } + function product_recalc(products, product_order) { + var product = product_select( + products, + product_order.treatments, + product_order.counceling); + + /* calculate price based in product and current risk data */ + var price_formatted; + + if(product_order.employees <= 4 && ! product_order.eligible_industry_discount) { + var prices = get_price_individual(product, product_order); + var sum = _.reduce(prices, function(memo, num) { return memo + parseInt(num); }, 0); + if(sum === 0) { + price_formatted = "Prøv andre valg, ingen pris funnet."; + } else { + if(prices.length == 1) { + price_formatted = "NOK " + sum + ",- per måned"; + } else { + price_formatted = prices.join(" + ")+" = NOK " + sum + ",- per måned"; + } + } + } else { + price = get_price(product, product_order); + if(price == -1) { + price_formatted = "Prøv andre valg, ingen pris funnet."; + } else { + price_formatted = "NOK " + price + ",- per år"; + } + } + product_order.product = product; + $("[data-prodcalc-product]").text(product.name); + $("[data-prodcalc-product-price]").text(price_formatted); + } + //function update_relevant_documents(product_order) { + + // var url = $(".product-calculator[data-documents-url]").attr('data-documents-url'); + // $.ajax({ + // url: url, + // method: 'GET', + // dataType: 'json', + // headers: { + // 'X-CSRFToken': $("[name=csrfmiddlewaretoken]").val() + // }, + // success: function(documents) { + // /* Present only the right documents, ordered by category */ + // //console.log("fetched the following documents:", documents); + // //console.log("filtering based on product_order", product_order); + + // var less_documents = filter_documents(documents, product_order); + // //console.log("returned these documents:", less_documents); + // update_document_list(less_documents); + // } + // }); + //} + + if($(".product-calculator").length) { + /* product_order stores the state of the order */ + var product_order = {}; + var product_order_steps = {}; + var num_product_order_steps = 6; + + /* Is the industry discount disabled? */ + if ( $('.product-calculator[data-disable-industry-discount]').length ) { + product_order.eligible_industry_discount = false; + $("[data-key=treatments][data-value=5]").show(); + } + + /* General layout of steps when user interacts with page: + * - update product_order state + * - update progress based on state + * - update the dom with the correct display state (button state, step description) + * - find product based on selection + * - calculate price based on discounts, selection and product + */ + + $.getJSON('/products.json', function(products) { + /* Attach to buttons and fields */ + + /* On every answer change */ + $("[data-answer]").on('click', function(e) { + var key = $(this).attr('data-key'); + var value = $(this).attr('data-value'); + + /* to_javascript */ + if (value == "no") { + value = false; + } + else if(value == "yes") { + value = true; + } + if(key == "treatments" || key == "employees") { + value = parseInt(value); + } + + /* limit options and change display */ + /* based on employees */ + if(key == "employees") { + if( value >= 20) { + if(product_order.has_exisiting_insurance === undefined) { + $(".modal-has-existing-insurance").foundation('reveal', 'open'); + } + } else { + /* Reset answer */ + delete product_order.has_exisiting_insurance; + $(".modal-has-existing-insurance button").removeClass("selected disabled"); + } + + var min_value = $(this).attr('data-min'); + /* if between 1 and 4 then.. */ + if( value <= 4 && min_value >= 1 && !product_order.eligible_industry_discount) { + /* display individual employee risk container */ + $(".individual-pricing-container").fadeIn('fast'); + /* Note: Fetching employee ages before anyone have been selected */ + update_employee_ages(); + } else { + $(".individual-pricing-container").fadeOut('fast'); + $("[data-key=treatments][data-value=12]").show(); + } + /* Next button */ + $("[data-goto-part=part-two]").fadeIn('fast'); + } + /* based on industry deal */ + if(key == "eligible_industry_discount") { + if(value) { + /* limit num treatments*/ + $("[data-key=treatments][data-value=5]").hide(); + } else { + $("[data-key=treatments][data-value=5]").show(); + } + if( !value && product_order.employees <= 4 && product_order.employees >= 1) { + $(".individual-pricing-container").fadeIn('fast'); + } else { + $(".individual-pricing-container").fadeOut('fast'); + } + + $(".prod-num-staff").fadeIn('fast'); + $(".part-one-zero").fadeOut('fast'); + setTimeout(function() { + $(".part-one-one").fadeIn('fast'); + }, 400); + } + /* based on counceling */ + if(key == "counceling") { + $(".prod-num-treatments").fadeIn('fast'); + $(".about-num-treatments").fadeIn('fast'); + if(value) { + /* limit num treatments and auto-select 24 */ + $("[data-key=treatments][data-value=5], [data-key=treatments][data-value=0]").hide(); + product_order.treatments = 24; + product_order_steps.treatments = 24; + $("[data-key=treatments]").removeClass("selected disabled"); + $("[data-key=treatments][data-value=24]").addClass("selected"); + /* update coverage */ + $(".coverage-treatments").text(product_order.treatments); + $(".selected-coverage .topp, .selected-coverage .treatments").fadeIn('fast'); + } else { + /* show all treatments, except 0 if industry deal */ + if( !product_order.eligible_industry_discount ) { + $("[data-key=treatments][data-value=5]").show(); + } + // FIXME: missing pricing data, just hide this option for now + if(product_order.employees <= 4) { + $("[data-key=treatments][data-value=0]").hide(); + } else { + $("[data-key=treatments][data-value=0]").show(); + } + $(".selected-coverage .topp").fadeOut('fast'); + } + } + /* based on addon_psychiatric_treatment */ + if(key == "addon_psychiatric_treatment") { + $(".prod-num-treatments").fadeIn('fast'); + $(".about-num-treatments").fadeIn('fast'); + $(".selected-coverage .counceling").fadeOut('fast'); + if(value) { + /* limit num treatments and auto-select 24 */ + $("[data-key=treatments][data-value=0]").hide(); + product_order.treatments = 24; + product_order_steps.treatments = 24; + $("[data-key=treatments]").removeClass("selected disabled"); + $("[data-key=treatments][data-value=24]").addClass("selected"); + /* update coverage */ + $(".coverage-treatments").text(product_order.treatments); + $("[data-prodcalc-addon]").text("med psykologi"); + $(".selected-coverage .treatments").fadeIn('fast'); + $(".selected-coverage .topp, .selected-coverage .psychology").fadeIn('fast'); + } else { + $(".selected-coverage .topp").fadeOut('fast'); + $("[data-prodcalc-addon]").text(""); + $("[data-key=treatments][data-value=0]").show(); + } + } + /* based on num treatments */ + if(key == "treatments") { + /* update coverage */ + if(value > 0) { + $(".selected-coverage .treatments").fadeIn('fast'); + $(".coverage-treatments").text(value); + } else if(value === 0) { + $(".selected-coverage .topp").fadeOut('fast'); + $(".selected-coverage .treatments").fadeOut('fast'); + $(".coverage-treatments").text(value); + } else { + $(".selected-coverage .treatments:visible").fadeOut('fast'); + } + } + + /* Update current answers. + * ie. industry discount, number of treatments, counceling and addon_psychiatric_treatment + */ + product_order[key] = value; + product_order_steps[key] = value; + + $(this).addClass("selected").removeClass("disabled"); + $("[data-key="+ key +"]").not(this).removeClass("selected").addClass("disabled"); + product_recalc(products, product_order); + /* total questions by number by answered questions */ + var current_progress = _.size(product_order_steps) / parseFloat(num_product_order_steps) * 100; + set_progress(current_progress); + }); + + /* Go on to the section after this one */ + $("[data-goto-part]").on('click', function(e) { + product_recalc(products, product_order); + var part = $(this).attr('data-goto-part'); + + + /* Product tailoring */ + if(part == 'part-two' && product_order.employees < 100) { + //console.log(product_order); + $(".part-zero, .part-one-right-container").fadeOut('fast'); + setTimeout(function() { + if(product_order.eligible_industry_discount) { + /* Don't ask for counceling, and set it to false */ + product_order.counceling = false; + $(".addon_psychiatric_treatment").fadeIn('fast'); + $(".about-addon-psychiatric-treatment").fadeIn('fast'); + $(".about-counceling").hide(); + } else { + $(".part-two .counceling").fadeIn('fast'); + // FIXME remove this if business rules are valid + //if(product_order.employees >= 20 && product_order.employees <= 99) { + // $(".about-num-treatments").fadeIn('fast'); + // $(".prod-num-treatments").fadeIn('fast'); + //} else { + // $(".part-two .counceling").fadeIn('fast'); + //} + } + $(".part-two-and-a-half-container").fadeIn('fast'); + $(".part-two").fadeIn('fast'); + if(product_order.has_exisiting_insurance) { + $(".part-two-right .need-stats").show(); + } else { + $(".part-two-right .need-stats").hide(); + } + }, 500); + } + /* Skip product tailoring */ + if( part == 'part-two' && product_order.employees >= 100) { + set_progress(100); + /* Get relevant product documents */ + //update_relevant_documents(product_order); + /* Show documents tab */ + $(".part-zero, .part-one-right-container").fadeOut('fast'); + setTimeout(function() { + if(product_order.has_exisiting_insurance) { + $(".part-three-special .need-stats").show(); + } else { + $(".part-three-special .need-stats").hide(); + } + $(".part-three-special").fadeIn('fast'); + }, 500); + } + + + /* "We recommend the product..." */ + if(part == 'part-two-and-a-half') { + $(".part-two-right").fadeOut('fast'); + $(".select-product-btn").fadeIn('fast'); + setTimeout(function() { + $(".part-two-and-a-half").fadeIn('fast'); + }, 500); + } + + + + /* Document "checkout" - fancy schmancy */ + if( part == 'part-three') { + set_progress(100); + /* Get relevant product documents */ + //update_relevant_documents(product_order); + + /* Show documents tab */ + $(".part-two, .part-one").fadeOut('fast'); + setTimeout(function() { + $(".part-two-and-a-half").parent().removeClass("small-7").addClass("small-12"); + $(".eula-container").removeClass("small-7").addClass("small-4"); + $(".product-description-inner").removeClass("small-5").addClass("small-3"); + $(".part-three").fadeIn('fast'); + }, 300); + $('[data-goto-part="part-three"]').fadeOut('fast'); + } + }); + + /* Update the product_order with individual employee ages */ + function update_employee_ages() { + var employees = []; + var i = 1; + $(".individual-pricing-container select.age-select-dropdown:visible").each(function(j, el) { + age = parseInt($(el).val().split(" -")[0]); + employees.push({ id: i, age: age }); + i++; + }); + product_order.individual_term_employees = employees; + } + $(".individual-pricing-container select.age-select-dropdown").on('change', update_employee_ages); + + /* add html for individual employee risk */ + $(".individual-pricing-container").on('click', "[data-add-new-employee]", function(e) { + e.preventDefault(); + /* No more than set amount */ + if( $(".person:visible").length == 4) { + return; + } + $(this).parent().next().fadeIn({ complete: update_employee_ages }); + }); + /* remove html for individual employee risk */ + $(".individual-pricing-container").on('click', "[data-remove-employee]", function(e) { + e.preventDefault(); + /* At least 1 */ + if( $(".person:visible").length == 1) { + return; + } + $(this).parent().fadeOut({ complete: update_employee_ages }); + }); + + /* Close modal on answer */ + $('[data-key="has_exisiting_insurance"]').on('click', function() { + $("#modal-has-existing-insurance").foundation('reveal', 'close'); + }); + }); + } +}); diff --git a/static/app/scripts/slide_edit.js b/static/app/scripts/slide_edit.js new file mode 100644 index 0000000..de812fd --- /dev/null +++ b/static/app/scripts/slide_edit.js @@ -0,0 +1,276 @@ +$(function() { + /* Save part urls + * Ref: urls.py */ + var urls = { + slide_part_save: '/api/slide/part/', + slide_title_save: '/api/slide/{slide_id}/title/', + slide_part_update: '/api/slide/part/{part_id}/', + slide_part_remove: '/api/slide/part/{part_id}/', + image_save: '/api/image/' + }; + var slide_id = $("#slide").attr('data-slide-id'); + var csrf_token = $.cookie('csrftoken'); + + /* Editor fields */ + var elements = document.querySelectorAll('[data-type="text"], [data-type="html"], [data-type="wysihtml5"]'); + var mediumOptions = { + buttons: ['bold', 'italic', 'header1', 'header2', 'quote', 'anchor', 'unorderedlist', 'orderedlist', 'removeFormat'] + }; + var editor = new MediumEditor(elements, mediumOptions); + editor.subscribe('blur', function(event, el) { + var type = $(el).attr('data-type'); + var name = $(el).attr('data-name'); + var url = $(el).attr('data-url'); + var pk = $(el).attr('data-pk'); + var method = 'POST'; + + if (pk.length > 0 && name != 'slide-title') { + url = urls.slide_part_update.replace('{part_id}', pk); + method = 'PUT'; + } + + var value = el.innerHTML; + if(type == 'text') { + value = el.textContent; + } + var data = { + slide_id: slide_id, + pk: pk, + name: name, + value: value + }; + $.ajax({ + method: method, + headers: { + 'X-CSRFToken': csrf_token + }, + type: 'POST', + url: url, + data: JSON.stringify(data), + contentType : 'application/json' + }).done(function() { + // TODO set pk on part + // $('[data-name="part-' + response.part_created_name + '"]').attr('data-pk', response.part_created_pk); + }).fail(function() { + console.log("boo"); + }); + + }); + $('[data-type="dynamic"]').on('changed', function(e) { + /* Delete part */ + if($(this).attr('data-part-remove')) { + var that = this; + $.ajax({ + url: urls.slide_part_remove.replace('{part_id}', $(this).attr('data-pk')), + method: 'DELETE', + headers: { + 'X-CSRFToken': csrf_token + }, + success: function(response, newValue) { + $(that).removeAttr('data-part-remove'); + $(that).attr('data-pk', ''); + } + }); + return; + } + /* Create or update part */ + var value = ''; + var type = ''; + + if($(this).find('img').length) { + value = $($(this).find('img')[0]).attr('data-pk'); + type = 'image'; + } + else if($(this).find('[data-graph-pk]').length) { + value = $($(this).find('[data-graph-pk]')[0]).attr('data-graph-pk'); + type = 'graph'; + } + else { + console.log("Could not determine Part-type."); + return; + } + + var slide_pk = $(this).attr('data-pk'); + var url = urls.slide_part_save; + var method = 'POST'; + + if (slide_pk.length > 0) { + url = urls.slide_part_update.replace('{part_id}', slide_pk); + method = 'PUT'; + } + + $.ajax({ + url: url, + method: method, + dataType: 'json', + data: { + name: $(this).attr('data-name'), + value: value, + type: type, + slide_id: $("#slide").attr('data-slide-id'), + href: $(this).find('a').attr('href') + }, + headers: { + 'X-CSRFToken': csrf_token + }, + success: function(response, newValue) { + if(response !== undefined && response.part_name && response.part_pk) { + $('[data-name="part-' + response.part_name + '"]').attr('data-pk', response.part_pk); + } + } + }); + }); + + /* + * Gallery + */ + // Ref: https://github.com/blueimp/jQuery-File-Upload + // https://github.com/blueimp/jQuery-File-Upload/wiki/Options + $('#id_file').fileupload({ + dataType: 'json', + url: urls.image_save, + done: function(e, data) { + // add image in gallery + $(".gallery ul").prepend('
  • '+ data.result.name +'
  • '); + // click event + $(".gallery ul li:first-child").click(function (e) { + $(this).siblings().removeClass("selected"); + $(this).toggleClass("selected"); + }); + $("#progress .bar").fadeOut('slow'); + }, + fail: function(e, data) { + console.log("Failed uploading file: ",e, data); + }, + headers: { + 'X-CSRFToken': csrf_token, + 'cache-control': 'no-cache' + }, + send: function(e, data) { + $('#progress .bar').css('width', '0%'); + $("#progress .bar").show(); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .bar').css( + 'width', + progress + '%' + ); + } + }); + /* Green select */ + $(".image-select").not(".placeholder").click(function (e) { + $(this).siblings().removeClass("selected"); + $(this).toggleClass("selected"); + + }); + /* Insert image */ + $('[data-type="dynamic"]').each(function(i, el) { + /* Insert image-button */ + var button_area = '
    '; + var image_button = ''; + $(el).wrap('
    '); + $(el).after(button_area); + $('[data-buttons-for="'+ $(el).attr('data-name') +'"]').append(image_button); + }); + + $('[data-reveal-id="gallery-modal"]').click( function(e) { + /* Store where to but the image from the modal in the modal */ + var replacing = $(this).attr('data-replace'); + $(".image-insert-btn").attr('data-replacing', replacing); + }); + $(".image-insert-btn").click(function(e) { + var img = $(".gallery .selected img"); + if(!img.length) { + // nothing selected + return; + } + var replacing = $(this).attr('data-replacing'); + var part = $('[data-name="'+ replacing +'"]'); + part.html(''); + part.find('img').attr('data-pk', img.attr('data-pk')); + part.trigger('changed'); + $("#gallery-modal").foundation('reveal', 'close'); + $('.image-select').removeClass("selected"); + }); + /* DELETE image part */ + $("[data-remove-image]").click(function(e) { + var replacing = $('.image-insert-btn').attr('data-replacing'); + var part = $('[data-name="'+ replacing +'"]'); + part.attr('data-part-remove','1'); + part.html(''); + part.trigger('changed'); + $('.image-select').removeClass("selected"); + $("#gallery-modal").foundation('reveal', 'close'); + }); + + /* Link between slides */ + /* ...for "dynamic" areas */ + $('[data-type="dynamic"]').each(function(i, el) { + /* Insert link-button on images */ + var last_button = $(el).siblings().find("a:last-child"); + last_button.after(''); + }); + + /* Set element target on modal */ + $('[data-url-target]').click( function(e) { + var target = $(this).attr('data-url-target'); + if(!$('[data-name="' + target + '"]').find('img').length) { + /* if there is no image, dont link to nothing */ + e.stopPropagation(); + return; + } + $(".modal-links").attr('data-wrapping', target); + }); + + $("[data-is-slide-link]").click(function(e) { + e.preventDefault(); + if($(this).attr('data-get-value-from-id')) { + /* Insert own link via input-field */ + var input_id = $(this).attr('data-get-value-from-id'); + $(this).attr('href', $("#"+input_id).val()); + } + var link = $(this).attr('href'); + var wrapping = $(".modal-links").attr('data-wrapping'); + var el_target = $('[data-name="'+ wrapping +'"]'); + // replace href in targets children if it exists + var potential_link = el_target.children(); + if(potential_link.is('a')) { + potential_link.attr('href',link); + } else { + el_target.find('img').wrap(''); + } + el_target.trigger('changed'); + $(".modal-links").foundation('reveal', 'close'); + }); + + /* Graphs - sticks in divs with data-type=dynamic */ + $('[data-type="dynamic"]').each(function(i, el) { + /* Insert link-button on images */ + var last_button = $(el).siblings().find("a:last-child"); + last_button.after(''); + + /* Set element target on modal */ + $('[data-target="'+ $(el).attr('data-name') +'"]').click( function(e) { + var target = $(this).attr('data-target'); + $(".modal-graph").attr('data-graph-target', target); + }); + }); + + $("[data-is-graph] a").click(function(e) { + e.preventDefault(); + var part_name = $('[data-graph-target]').attr('data-graph-target'); + var graph = $(this).parent(); + var part = $('[data-name="'+ part_name +'"]'); + var html = graph.find('[data-graph-html-copy]')[0].outerHTML; + part.html(html); + part.find('[data-graph-slug]').graph('load'); + part.trigger('changed'); + $(".modal-graph").foundation('reveal', 'close'); + }); + + /* Load graphs initially */ + $('.template [data-graph-slug]').graph('load'); + $('.modal-graph [data-graph-slug]').graph('load', {width: 300, height: 200}); + +}); diff --git a/static/app/scripts/slides.js b/static/app/scripts/slides.js new file mode 100644 index 0000000..92a10dc --- /dev/null +++ b/static/app/scripts/slides.js @@ -0,0 +1,440 @@ +$(document).ready( function() { + var all_icons = $("[data-section-icon]").map(function() { + return $(this).attr('data-section-icon'); + }).get(); + all_icons = _.uniq(all_icons).join(" "); + + function update_title_bar( event ) { + if($(event.currentSlide).is('[data-section-title-hidden]') ) { + $(".title-bar").css('opacity', '0'); + } else { + $(".title-bar").css('opacity', '1'); + } + // event.previousSlide, event.currentSlide, event.indexh, event.indexv + var title = $(event.currentSlide).attr('data-section-title') || ""; + /* Only update when title has changed */ + if($(".title-bar .title span:first").text() !== title) { + $(""+title+"").hide().appendTo(".title-bar .title").fadeIn("normal"); + $(".title-bar .title span:not(:last)").fadeOut("normal", function() { + $(this).remove(); + }); + } + + var edit_url = $(event.currentSlide).attr('data-edit-url'); + $(".title-bar a.title").attr('href', edit_url); // Only update if a is found + + var icon = $(event.currentSlide).attr('data-section-icon') || ""; + if( !$(".title-bar .title i").hasClass(icon) ) { + $(".title-bar .title i") + .removeClass(all_icons) + .addClass(icon); +  } + } + /* Slides: with "wheel" */ + function wheel_toggle_slides(el) { + $("[data-wheel-order]").removeClass('active'); + $(el).addClass('active'); + var order = $(el).attr('data-wheel-order'); + var related = $('[data-wheel-order="' + order +'"]').not('.wheel-image'); + related.addClass('active'); + $('.wheel-text [data-type="wysihtml5"]').hide(); + related.show(); + } + $(".top-bar .links a").click(function() { + $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); + }); + + /* Presentation? */ + if( $('.page-presentation-play').length) { + /* Initialize reveal.js */ + Reveal.initialize({ + // Display controls in the bottom right corner + controls: true, + // Display a presentation progress bar + progress: true, + // Push each slide change to the browser history + history: true, + // Enable keyboard shortcuts for navigation + keyboard: true, + // Enable the slide overview mode + overview: false, + // Vertical centering of slides + center: false, + // Enables touch navigation on devices with touch input + touch: true, + // Loop the presentation + loop: false, + // Change the presentation direction to be RTL + rtl: false, + // Number of milliseconds between automatically proceeding to the + // next slide, disabled when set to 0, this value can be overwritten + // by using a data-autoslide attribute on your slides + autoSlide: 0, + // Enable slide navigation via mouse wheel + mouseWheel: false, + // Apply a 3D roll to links on hover + rollingLinks: false, + // Transition style + transition: 'linear', // default/cube/page/concave/zoom/linear/fade/none + // Factor of the display size that should remain empty around the content + margin: 0.15, + // The "normal" size of the presentation, aspect ratio will be preserved + // when the presentation is scaled to fit different resolutions. Can be + // specified using percentage units. + //width: 960, + //height: 700, + width: 768, // Note: Could set this to 100% and make presentation content responsive instead of using zoom; + height: 576, + minScale: 0.2, + maxScale: 1 + // FIXME: use user agent / device width ? + }); + + + Reveal.addEventListener( 'ready', function(event) { + /* On small screen? disable transitions */ + var small_screen = $(window).width() < 480; + if( small_screen ) { + Reveal.configure({ transition: 'none' }); + } + + update_title_bar(event); + + /* Load chart if one exists on current slide (animate) */ + if( $(event.currentSlide).find('[class^="graph-"]').length) { + $(event.currentSlide).find('[class^="graph-"]').graph('load'); + } + + }); + + Reveal.addEventListener( 'slidechanged', function( event ) { + + /* Update title bar */ + update_title_bar(event); + + /* Chart slide - Wait until it is current to load (animate) */ + if( $(event.currentSlide).find('[class^="graph-"]').length) { + $(event.currentSlide).find('[class^="graph-"]').graph('load'); + } + + /* Disable touch on specific slides*/ + if( $(event.currentSlide).find("[data-swipe-disable]").length ) { + Reveal.configure({ touch: false }); + } else { + Reveal.configure({ touch: true }); + } + + /* Search previous slide for video elements and pause them */ + $(event.previousSlide).find("video").each(function(i, el) { + el.pause(); + }); + + /* Setup/Reset wheel state on wheel-slide enter */ + if( $(event.currentSlide).find('.wheel').length) { + $('.wheel-text [data-wheel-order]').hide(); + $('[data-wheel-order]').removeClass('active'); + $('[data-wheel-order="1"]').addClass('active').show(); + } + } ); + + + $(".wheel-images .wheel-image .trigger, .wheel-head .trigger").on('mousedown', function(e) { + wheel_toggle_slides(this); + }); + /* Hover fix for touch: Only bind on hover for non-touch devices */ + $(".no-touch .wheel-images .wheel-image .trigger, .no-touch .wheel-head .trigger").on('mouseenter', function(e) { + wheel_toggle_slides(this); + }); + } + + /* Swipebox */ + $('a.fancybox').swipebox(); + + /* Video */ + $('video').mediaelementplayer({ + success: function (mediaElement, domObject) { + /* Track video plays */ + mediaElement.addEventListener( + 'play', + function(e) { + mixpanel.track("Played video."); + }, + false); + } + }); + + /* Skip home if you are on the play-slide */ + $("[data-goto-first-slide]").on('click', function(e) { + e.preventDefault(); + $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); + Reveal.slide(0, 0); + }); + + + /* Slide: Sick cost calculator */ + function get_salary() { + var industry_pk = parseInt($("#id_calc_industry").val(), 10); + /* Note: stb_industries is defined in the calculator.html-template */ + var industry = _.findWhere(stb_industries, {pk: industry_pk}); + + if(industry === undefined) { + return 0; + } + return industry.fields.yearly_salary; + } + function calc_cost(sick_rate, num_staff) { + var salary = get_salary(); + sick_rate = sick_rate / 100.0; // percent + return sick_rate * num_staff * salary; + } + /* Format norwegian */ + function format_number_norwegian(num) { + num = num.toString(); + var formatted_str = ""; + /* Add spaces backwards every third char */ + for(var i=0; i< num.length; i++){ + if(i % 3 === 0) { + formatted_str += " "; + } + formatted_str += num.charAt(num.length-i-1); + } + /* reverse the string */ + return formatted_str.split("").reverse().join(""); + } + function calc_savings(sick_rate, goal_sick_rate, num_staff) { + var current = calc_cost(sick_rate, num_staff); + var goal = calc_cost(goal_sick_rate, num_staff); + return current - goal; //total savings per year + } + function recalc() { + /* Get data */ + var num_staff = parseInt($(".num-staff").slider('value'), 10); + var sick_rate = $(".sick-rate").slider('value'); + var sick_rate_float = parseFloat(sick_rate); + var goal_sick_rate = $(".goal-sick-rate").slider('value'); + var goal_sick_rate_float = parseFloat(goal_sick_rate); + /* Calculate */ + var cost = calc_cost(sick_rate_float, num_staff); + cost = parseInt(Math.round( cost / 100), 10) * 100; + var savings = calc_savings(sick_rate_float, goal_sick_rate, num_staff); + savings = parseInt(Math.round( savings / 1000), 10) * 1000; + /* Output data */ + $("[data-calc-staff]").text(num_staff); + $("[data-calc-rate]").text(Math.round(sick_rate_float * 10) / 10); + $("[data-calc-goal-rate]").text(Math.round(goal_sick_rate_float * 10) / 10); + $("[data-calc-savings]").text(format_number_norwegian(savings)); + $("[data-calc-savings-employee]").text(format_number_norwegian(Math.round(savings / num_staff))); + /* cost */ + $("[data-calc-cost]").text(format_number_norwegian(cost)); + $("[data-calc-cost-employee]").text(format_number_norwegian(Math.round(cost / num_staff))); + + } + if($(".sick-cost-calculator").length) { + $( ".num-staff" ).slider({ + animate: "fast", + value: 600, + min: 1, + max: 2000, + step: 1, + stop: recalc, + slide: recalc + }); + $( ".sick-rate" ).slider({ + animate: "fast", + value: 10.2, + min: 1, + max: 15, + step: 0.2, + stop: recalc, + slide: recalc + }); + $( ".goal-sick-rate" ).slider({ + animate: "fast", + value: 5, + min: 1, + max: 15, + step: 0.2, + stop: recalc, + slide: recalc + }); + $(".sick-cost-industry-form").on('change', function(e) { + recalc(); + }); + + recalc(); // Initial calc + + /* Workaround for slider not working on touch devices + * Click/touch and change */ + $("[data-calc-staff], [data-calc-rate], [data-calc-goal-rate]").on('click', function(e) { + $(".set-value-modal").attr('data-updating', $(this).attr('data-updating')); + var old_value = $(this).text(); + $("input[name=set-value]").val(old_value); + $(".set-value-modal").foundation('reveal', 'open'); + }); + $(".set-value-button").on('click', function(e) { + var new_value = $("input[name=set-value]").val(); + var key = "#" + $(".set-value-modal").attr('data-updating'); + $( key ).slider({ value: parseFloat(new_value)}); + $(".set-value-modal").foundation('reveal', 'close'); + recalc(); + }); + } + + /* Slide: Public treatment comparison */ + if($(".public-treatment-comparison").length) { +        var options = { +     valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] +        }; + +        var featureList = new List('treatment-list', options); + featureList.sort('waittime', { asc: false }); + +        $('.filter-region, .filter-diagnose').change(function() { +            featureList.filter(function(item) { + var diagnose = $('.filter-diagnose').val(); + var region = $(".filter-region").val(); +                return (item.values().region == region || region == "Alle") && item.values().diagnose == diagnose; +            }); +            return false; +        }); +        $('.filter-none').click(function() { +            featureList.filter(); +            return false; +        }); + $(".filter-diagnose").trigger('change'); + } + + function init_treatment_map() { + // mapbox.com: nikolaik.map-hyrf1sef + var tile_url = 'http://{s}.tiles.mapbox.com/v3/nikolaik.map-hyrf1sef/{z}/{x}/{y}.png'; + var tiles = L.tileLayer(tile_url, {maxZoom: 17, minZoom: 4}); + var latlng = L.latLng(65.57, 12.56); + + var map = L.map('treament-network-map', {center: latlng, zoom: 4, layers: [tiles]}); + + var markers = L.markerClusterGroup({ showCoverageOnHover: false}); + /* Marker icon style */ + var static_url = $('meta[name="x-django-static-url"]').attr('content'); + var icon = L.icon({ + iconUrl: static_url + 'dist/images/storebrand_map_marker.png', + iconSize: new L.Point(35, 35), + iconAnchor: new L.Point(35, 35), + popupAnchor: new L.Point(-17.5, -35), + shadowUrl: '', + shadowSize: new L.Point(0, 0), + }); + + /* Add specialist markers */ + var _url = 'http://zeppelin.brill.no/blifrisk/data/no.json'; + $.getJSON(_url, function(data) { + _.each(data.specialists, function(s, i) { + if(s.position) { + var marker = L.marker(new L.LatLng(s.position.lat, s.position.lng), { title: s.name, icon: icon }); + marker.bindPopup("

    "+ s.name +"

    "+ s.address +"
    "+ s.postalCode +" "+ s.city +"

    "); + markers.addLayer(marker); + } + }); + map.addLayer(markers); + }); + } + /* Slide: Treatment locations map */ + if($(".treament-network-map").length) { + + /* Load the treatment map when the slide comes in to view when in presentation mode */ + if (window.Reveal && !$(".page-slide-edit").length) { + var handler = function(event) { + if($(event.currentSlide).find(".treament-network-map").length) { + init_treatment_map(); + Reveal.removeEventListener( 'slidechanged', handler, false); // run only once + } + }; + Reveal.addEventListener( 'slidechanged', handler); + Reveal.addEventListener( 'ready', function(event) { + if($(event.currentSlide).find(".treament-network-map").length) { + /* Load map */ + init_treatment_map(); + } + }); + } else { + init_treatment_map(); + } + + } + /* Placeholder polyfill for IE9 */ + placeholderSupport = ("placeholder" in document.createElement("input")); + if(!placeholderSupport){ + //This browser does not support the placeholder attribute + //use javascript instead + $('[placeholder]').focus(function() { + var input = $(this); + if (input.val() === input.attr('placeholder')) { + input.val(''); + input.removeClass('placeholder'); + } + }).blur(function() { + var input = $(this); + if (input.val() === '' || input.val() === input.attr('placeholder')) { + input.addClass('placeholder'); + input.val(input.attr('placeholder')); + } + }).blur().parents('form').submit(function() { + $(this).find('[placeholder]').each(function() { + var input = $(this); + if (input.val() === input.attr('placeholder')) { + input.val(''); + } + }); + }); + } + /* Highcarts graph theme */ + Highcharts.theme = { + colors: ['#da291c', '#425563', '#ed786f'], + chart: { + backgroundColor: null + }, + credits: { + enabled: false + }, + title: { + style: { + color: '#1e394d', + font: 'bold 16px "SignaColumn", Helvetica, Arial, sans-serif' + } + }, + subtitle: { + style: { + color: '#425563', + font: 'bold 12px "SignaColumn", Helvetica, Arial, sans-serif' + } + }, + yAxis: { + title: { + style: { + color: 'gray' + } + } + }, + xAxis: { + title: { + style: { + color: 'gray' + } + } + }, + legend: { + itemStyle: { + font: '9pt "SignaColumn", Helvetica, Arial, sans-serif', + color: 'black' + }, + itemHoverStyle:{ + color: 'gray' + } + }, + exporting: { + enabled: false + } + }; + + // Apply the theme + Highcharts.setOptions(Highcharts.theme); +}); diff --git a/static/app/styles/_header.scss b/static/app/styles/_header.scss new file mode 100644 index 0000000..e69de29 diff --git a/static/app/styles/_settings.scss b/static/app/styles/_settings.scss new file mode 100644 index 0000000..108b396 --- /dev/null +++ b/static/app/styles/_settings.scss @@ -0,0 +1,1457 @@ +// Foundation by ZURB +// foundation.zurb.com +// Licensed under MIT Open Source + +// a. Base +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// This is the default html and body font-size for the base rem value. +// $rem-base: 16px; + +// Allows the use of rem-calc() or lower-bound() in your settings +@import 'foundation/functions'; + +// The default font-size is set to 100% of the browser style sheet (usually 16px) +// for compatibility with browser-based text zoom or user-set defaults. + +// Since the typical default browser font-size is 16px, that makes the calculation for grid size. +// If you want your base font-size to be different and not have it affect the grid breakpoints, +// set $rem-base to $base-font-size and make sure $base-font-size is a px value. +// $base-font-size: 100%; + +// The $base-font-size is 100% while $base-line-height is 150% +// $base-line-height: 150%; + +// We use this to control whether or not CSS classes come through in the gem files. +$include-html-classes: true; +// $include-print-styles: true; +$include-html-global-classes: $include-html-classes; + + +// $input-font-family: inherit; +// $input-font-color: rgba(0,0,0,0.75); +// $input-font-size: rem-calc(14); +// $input-bg-color: $white; +// $input-focus-bg-color: scale-color($white, $lightness: -2%); +// $input-border-color: $charcoal-color; +// $input-focus-border-color: scale-color($white, $lightness: -40%); +// $input-border-style: solid; +// $input-border-width: 2px; +// $input-border-radius: $global-radius; +// $input-disabled-bg: $gainsboro; +// $input-disabled-cursor: $cursor-default-value; +// $input-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); +// $input-include-glowing-effect: false; + + +// b. Grid +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-grid-classes: $include-html-classes; +// $include-xl-html-grid-classes: false; + +// $row-width: rem-calc(1000); +// $total-columns: 12; +// $column-gutter: rem-calc(30); + +// c. Global +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// We use these to define default font stacks +// $font-family-sans-serif: "Helvetica Neue", Helvetica, Roboto, Arial, sans-serif; +// $font-family-serif: Georgia, Cambria, "Times New Roman", Times, serif; +// $font-family-monospace: Consolas, "Liberation Mono", Courier, monospace; + +// We use these to define default font weights +// $font-weight-normal: normal; +// $font-weight-bold: bold; + +// $white : #FFFFFF; +// $ghost : #FAFAFA; +// $snow : #F9F9F9; +// $vapor : #F6F6F6; +// $white-smoke : #F5F5F5; +// $silver : #EFEFEF; +// $smoke : #EEEEEE; +// $gainsboro : #DDDDDD; +// $iron : #CCCCCC; +// $base : #AAAAAA; +// $aluminum : #999999; +// $jumbo : #888888; +// $monsoon : #777777; +// $steel : #666666; +// $charcoal : #555555; +// $tuatara : #444444; +// $oil : #333333; +// $jet : #222222; +// $black : #000000; + +// We use these as default colors throughout +// $primary-color: #008CBA; +// $secondary-color: #e7e7e7; +// $alert-color: #f04124; +// $success-color: #43AC6A; +// $warning-color: #f08a24; +// $info-color: #a0d3e8; + +// We use these to control various global styles +// $body-bg: $white; +// $body-font-color: $jet; +// $body-font-family: $font-family-sans-serif; +// $body-font-weight: $font-weight-normal; +// $body-font-style: normal; + +// We use this to control font-smoothing +// $font-smoothing: antialiased; + +// We use these to control text direction settings +// $text-direction: ltr; +// $opposite-direction: right; +// $default-float: left; +// $last-child-float: $opposite-direction; + +// We use these to make sure border radius matches unless we want it different. +// $global-radius: 3px; +// $global-rounded: 1000px; + +// We use these to control inset shadow shiny edges and depressions. +// $shiny-edge-size: 0 1px 0; +// $shiny-edge-color: rgba($white, .5); +// $shiny-edge-active-color: rgba($black, .2); + +// d. Media Query Ranges +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $small-breakpoint: em-calc(640); +// $medium-breakpoint: em-calc(1024); +// $large-breakpoint: em-calc(1440); +// $xlarge-breakpoint: em-calc(1920); + +// $small-range: (0, $small-breakpoint); +// $medium-range: ($small-breakpoint + em-calc(1), $medium-breakpoint); +// $large-range: ($medium-breakpoint + em-calc(1), $large-breakpoint); +// $xlarge-range: ($large-breakpoint + em-calc(1), $xlarge-breakpoint); +// $xxlarge-range: ($xlarge-breakpoint + em-calc(1), em-calc(99999999)); + +// $screen: "only screen"; + +// $landscape: "#{$screen} and (orientation: landscape)"; +// $portrait: "#{$screen} and (orientation: portrait)"; + +// $small-up: $screen; +// $small-only: "#{$screen} and (max-width: #{upper-bound($small-range)})"; + +// $medium-up: "#{$screen} and (min-width:#{lower-bound($medium-range)})"; +// $medium-only: "#{$screen} and (min-width:#{lower-bound($medium-range)}) and (max-width:#{upper-bound($medium-range)})"; + +// $large-up: "#{$screen} and (min-width:#{lower-bound($large-range)})"; +// $large-only: "#{$screen} and (min-width:#{lower-bound($large-range)}) and (max-width:#{upper-bound($large-range)})"; + +// $xlarge-up: "#{$screen} and (min-width:#{lower-bound($xlarge-range)})"; +// $xlarge-only: "#{$screen} and (min-width:#{lower-bound($xlarge-range)}) and (max-width:#{upper-bound($xlarge-range)})"; + +// $xxlarge-up: "#{$screen} and (min-width:#{lower-bound($xxlarge-range)})"; +// $xxlarge-only: "#{$screen} and (min-width:#{lower-bound($xxlarge-range)}) and (max-width:#{upper-bound($xxlarge-range)})"; + +// $retina: ( +// "#{$screen} and (-webkit-min-device-pixel-ratio: 2)", +// "#{$screen} and (min--moz-device-pixel-ratio: 2)", +// "#{$screen} and (-o-min-device-pixel-ratio: 2/1)", +// "#{$screen} and (min-device-pixel-ratio: 2)", +// "#{$screen} and (min-resolution: 192dpi)", +// "#{$screen} and (min-resolution: 2dppx)" +// ); + +// Legacy +// $small: $medium-up; +// $medium: $medium-up; +// $large: $large-up; + +// We use this as cursors values for enabling the option of having custom cursors in the whole site's stylesheet +// $cursor-crosshair-value: crosshair; +// $cursor-default-value: default; +// $cursor-disabled-value: not-allowed; +// $cursor-pointer-value: pointer; +// $cursor-help-value: help; +// $cursor-text-value: text; + +// e. Typography +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-type-classes: $include-html-classes; + +// We use these to control header font styles +// $header-font-family: $body-font-family; +// $header-font-weight: $font-weight-normal; +// $header-font-style: normal; +// $header-font-color: $jet; +// $header-line-height: 1.4; +// $header-top-margin: .2rem; +// $header-bottom-margin: .5rem; +// $header-text-rendering: optimizeLegibility; + +// We use these to control header font sizes +// $h1-font-size: rem-calc(44); +// $h2-font-size: rem-calc(37); +// $h3-font-size: rem-calc(27); +// $h4-font-size: rem-calc(23); +// $h5-font-size: rem-calc(18); +// $h6-font-size: 1rem; + +// We use these to control header size reduction on small screens +// $h1-font-reduction: rem-calc(10); +// $h2-font-reduction: rem-calc(10); +// $h3-font-reduction: rem-calc(5); +// $h4-font-reduction: rem-calc(5); +// $h5-font-reduction: 0; +// $h6-font-reduction: 0; + +// These control how subheaders are styled. +// $subheader-line-height: 1.4; +// $subheader-font-color: scale-color($header-font-color, $lightness: 35%); +// $subheader-font-weight: $font-weight-normal; +// $subheader-top-margin: .2rem; +// $subheader-bottom-margin: .5rem; + +// A general styling +// $small-font-size: 60%; +// $small-font-color: scale-color($header-font-color, $lightness: 35%); + +// We use these to style paragraphs +// $paragraph-font-family: inherit; +// $paragraph-font-weight: $font-weight-normal; +// $paragraph-font-size: 1rem; +// $paragraph-line-height: 1.6; +// $paragraph-margin-bottom: rem-calc(20); +// $paragraph-aside-font-size: rem-calc(14); +// $paragraph-aside-line-height: 1.35; +// $paragraph-aside-font-style: italic; +// $paragraph-text-rendering: optimizeLegibility; + +// We use these to style tags +// $code-color: $oil; +// $code-font-family: $font-family-monospace; +// $code-font-weight: $font-weight-normal; +// $code-background-color: scale-color($secondary-color, $lightness: 70%); +// $code-border-size: 1px; +// $code-border-style: solid; +// $code-border-color: scale-color($code-background-color, $lightness: -10%); +// $code-padding: rem-calc(2) rem-calc(5) rem-calc(1); + +// We use these to style anchors +// $anchor-text-decoration: none; +// $anchor-text-decoration-hover: none; +// $anchor-font-color: $primary-color; +// $anchor-font-color-hover: scale-color($anchor-font-color, $lightness: -14%); + +// We use these to style the
    element +// $hr-border-width: 1px; +// $hr-border-style: solid; +// $hr-border-color: $gainsboro; +// $hr-margin: rem-calc(20); + +// We use these to style lists +// $list-font-family: $paragraph-font-family; +// $list-font-size: $paragraph-font-size; +// $list-line-height: $paragraph-line-height; +// $list-margin-bottom: $paragraph-margin-bottom; +// $list-style-position: outside; +// $list-side-margin: 1.1rem; +// $list-ordered-side-margin: 1.4rem; +// $list-side-margin-no-bullet: 0; +// $list-nested-margin: rem-calc(20); +// $definition-list-header-weight: $font-weight-bold; +// $definition-list-header-margin-bottom: .3rem; +// $definition-list-margin-bottom: rem-calc(12); + +// We use these to style blockquotes +// $blockquote-font-color: scale-color($header-font-color, $lightness: 35%); +// $blockquote-padding: rem-calc(9 20 0 19); +// $blockquote-border: 1px solid $gainsboro; +// $blockquote-cite-font-size: rem-calc(13); +// $blockquote-cite-font-color: scale-color($header-font-color, $lightness: 23%); +// $blockquote-cite-link-color: $blockquote-cite-font-color; + +// Acronym styles +// $acronym-underline: 1px dotted $gainsboro; + +// We use these to control padding and margin +// $microformat-padding: rem-calc(10 12); +// $microformat-margin: rem-calc(0 0 20 0); + +// We use these to control the border styles +// $microformat-border-width: 1px; +// $microformat-border-style: solid; +// $microformat-border-color: $gainsboro; + +// We use these to control full name font styles +// $microformat-fullname-font-weight: $font-weight-bold; +// $microformat-fullname-font-size: rem-calc(15); + +// We use this to control the summary font styles +// $microformat-summary-font-weight: $font-weight-bold; + +// We use this to control abbr padding +// $microformat-abbr-padding: rem-calc(0 1); + +// We use this to control abbr font styles +// $microformat-abbr-font-weight: $font-weight-bold; +// $microformat-abbr-font-decoration: none; + +// 01. Accordion +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-accordion-classes: $include-html-classes; + +// $accordion-navigation-padding: rem-calc(16); +// $accordion-navigation-bg-color: $silver; +// $accordion-navigation-hover-bg-color: scale-color($accordion-navigation-bg-color, $lightness: -5%); +// $accordion-navigation-active-bg-color: scale-color($accordion-navigation-bg-color, $lightness: -3%); +// $accordion-navigation-font-color: $jet; +// $accordion-navigation-font-size: rem-calc(16); +// $accordion-navigation-font-family: $body-font-family; + +// $accordion-content-padding: ($column-gutter/2); +// $accordion-content-active-bg-color: $white; + +// 02. Alert Boxes +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-alert-classes: $include-html-classes; + +// We use this to control alert padding. +// $alert-padding-top: rem-calc(14); +// $alert-padding-default-float: $alert-padding-top; +// $alert-padding-opposite-direction: $alert-padding-top + rem-calc(10); +// $alert-padding-bottom: $alert-padding-top; + +// We use these to control text style. +// $alert-font-weight: $font-weight-normal; +// $alert-font-size: rem-calc(13); +// $alert-font-color: $white; +// $alert-font-color-alt: scale-color($secondary-color, $lightness: -66%); + +// We use this for close hover effect. +// $alert-function-factor: -14%; + +// We use these to control border styles. +// $alert-border-style: solid; +// $alert-border-width: 1px; +// $alert-border-color: scale-color($primary-color, $lightness: $alert-function-factor); +// $alert-bottom-margin: rem-calc(20); + +// We use these to style the close buttons +// $alert-close-color: $oil; +// $alert-close-top: 50%; +// $alert-close-position: rem-calc(4); +// $alert-close-font-size: rem-calc(22); +// $alert-close-opacity: .3; +// $alert-close-opacity-hover: .5; +// $alert-close-padding: 9px 6px 4px; +// $alert-close-background: inherit; + +// We use this to control border radius +// $alert-radius: $global-radius; + +// $alert-transition-speed: 300ms; +// $alert-transition-ease: ease-out; + +// 03. Block Grid +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-block-grid-classes: $include-html-classes; +// $include-xl-html-block-grid-classes: false; + +// We use this to control the maximum number of block grid elements per row +// $block-grid-elements: 12; +// $block-grid-default-spacing: rem-calc(20); + +// $align-block-grid-to-grid: false; +// @if $align-block-grid-to-grid {$block-grid-default-spacing: $column-gutter;} + +// Enables media queries for block-grid classes. Set to false if writing semantic HTML. +// $block-grid-media-queries: true; + +// 04. Breadcrumbs +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-nav-classes: $include-html-classes; + +// We use this to set the background color for the breadcrumb container. +// $crumb-bg: scale-color($secondary-color, $lightness: 55%); + +// We use these to set the padding around the breadcrumbs. +// $crumb-padding: rem-calc(9 14 9); +// $crumb-side-padding: rem-calc(12); + +// We use these to control border styles. +// $crumb-function-factor: -10%; +// $crumb-border-size: 1px; +// $crumb-border-style: solid; +// $crumb-border-color: scale-color($crumb-bg, $lightness: $crumb-function-factor); +// $crumb-radius: $global-radius; + +// We use these to set various text styles for breadcrumbs. +// $crumb-font-size: rem-calc(11); +// $crumb-font-color: $primary-color; +// $crumb-font-color-current: $oil; +// $crumb-font-color-unavailable: $aluminum; +// $crumb-font-transform: uppercase; +// $crumb-link-decor: underline; + +// We use these to control the slash between breadcrumbs +// $crumb-slash-color: $base; +// $crumb-slash: "/"; + +// 05. Buttons +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-button-classes: $include-html-classes; + +// We use these to build padding for buttons. +// $button-tny: rem-calc(10); +// $button-sml: rem-calc(14); +// $button-med: rem-calc(16); +// $button-lrg: rem-calc(18); + +// We use this to control the display property. +// $button-display: inline-block; +// $button-margin-bottom: rem-calc(20); + +// We use these to control button text styles. +// $button-font-family: $body-font-family; +// $button-font-color: $white; +// $button-font-color-alt: $oil; +// $button-font-tny: rem-calc(11); +// $button-font-sml: rem-calc(13); +// $button-font-med: rem-calc(16); +// $button-font-lrg: rem-calc(20); +// $button-font-weight: $font-weight-normal; +// $button-font-align: center; + +// We use these to control various hover effects. +// $button-function-factor: -20%; + +// We use these to control button border styles. +// $button-border-width: 0; +// $button-border-style: solid; +// $button-bg-color: $primary-color; +// $button-bg-hover: scale-color($button-bg-color, $lightness: $button-function-factor); +// $button-border-color: $button-bg-hover; +// $secondary-button-bg-hover: scale-color($secondary-color, $lightness: $button-function-factor); +// $secondary-button-border-color: $secondary-button-bg-hover; +// $success-button-bg-hover: scale-color($success-color, $lightness: $button-function-factor); +// $success-button-border-color: $success-button-bg-hover; +// $alert-button-bg-hover: scale-color($alert-color, $lightness: $button-function-factor); +// $alert-button-border-color: $alert-button-bg-hover; +// $warning-button-bg-hover: scale-color($warning-color, $lightness: $button-function-factor); +// $warning-button-border-color: $warning-button-bg-hover; +// $info-button-bg-hover: scale-color($info-color, $lightness: $button-function-factor); +// $info-button-border-color: $info-button-bg-hover; + +// We use this to set the default radius used throughout the core. +// $button-radius: $global-radius; +// $button-round: $global-rounded; + +// We use this to set default opacity and cursor for disabled buttons. +// $button-disabled-opacity: .7; +// $button-disabled-cursor: $cursor-default-value; + +// 06. Button Groups +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-button-classes: $include-html-classes; + +// Sets the margin for the right side by default, and the left margin if right-to-left direction is used +// $button-bar-margin-opposite: rem-calc(10); +// $button-group-border-width: 1px; + +// 07. Clearing +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-clearing-classes: $include-html-classes; + +// We use these to set the background colors for parts of Clearing. +// $clearing-bg: $oil; +// $clearing-caption-bg: $clearing-bg; +// $clearing-carousel-bg: rgba(51,51,51,0.8); +// $clearing-img-bg: $clearing-bg; + +// We use these to style the close button +// $clearing-close-color: $iron; +// $clearing-close-size: 30px; + +// We use these to style the arrows +// $clearing-arrow-size: 12px; +// $clearing-arrow-color: $clearing-close-color; + +// We use these to style captions +// $clearing-caption-font-color: $iron; +// $clearing-caption-font-size: .875em; +// $clearing-caption-padding: 10px 30px 20px; + +// We use these to make the image and carousel height and style +// $clearing-active-img-height: 85%; +// $clearing-carousel-height: 120px; +// $clearing-carousel-thumb-width: 120px; +// $clearing-carousel-thumb-active-border: 1px solid rgb(255,255,255); + +// 08. Dropdown +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-dropdown-classes: $include-html-classes; + +// We use these to controls height and width styles. +// $f-dropdown-max-width: 200px; +// $f-dropdown-height: auto; +// $f-dropdown-max-height: none; + +// Used for bottom position +// $f-dropdown-margin-top: 2px; + +// Used for right position +// $f-dropdown-margin-left: $f-dropdown-margin-top; + +// Used for left position +// $f-dropdown-margin-right: $f-dropdown-margin-top; + +// Used for top position +// $f-dropdown-margin-bottom: $f-dropdown-margin-top; + +// We use this to control the background color +// $f-dropdown-bg: $white; + +// We use this to set the border styles for dropdowns. +// $f-dropdown-border-style: solid; +// $f-dropdown-border-width: 1px; +// $f-dropdown-border-color: scale-color($white, $lightness: -20%); + +// We use these to style the triangle pip. +// $f-dropdown-triangle-size: 6px; +// $f-dropdown-triangle-color: $white; +// $f-dropdown-triangle-side-offset: 10px; + +// We use these to control styles for the list elements. +// $f-dropdown-list-style: none; +// $f-dropdown-font-color: $charcoal; +// $f-dropdown-font-size: rem-calc(14); +// $f-dropdown-list-padding: rem-calc(5, 10); +// $f-dropdown-line-height: rem-calc(18); +// $f-dropdown-list-hover-bg: $smoke; +// $dropdown-mobile-default-float: 0; + +// We use this to control the styles for when the dropdown has custom content. +// $f-dropdown-content-padding: rem-calc(20); + +// Default radius for dropdown. +// $f-dropdown-radius: $global-radius; + + +// 09. Dropdown Buttons +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-button-classes: $include-html-classes; + +// We use these to set the color of the pip in dropdown buttons +// $dropdown-button-pip-color: $white; +// $dropdown-button-pip-color-alt: $oil; + +// We use these to set the size of the pip in dropdown buttons +// $button-pip-tny: rem-calc(6); +// $button-pip-sml: rem-calc(7); +// $button-pip-med: rem-calc(9); +// $button-pip-lrg: rem-calc(11); + +// We use these to style tiny dropdown buttons +// $dropdown-button-padding-tny: $button-pip-tny * 7; +// $dropdown-button-pip-size-tny: $button-pip-tny; +// $dropdown-button-pip-opposite-tny: $button-pip-tny * 3; +// $dropdown-button-pip-top-tny: (-$button-pip-tny / 2) + rem-calc(1); + +// We use these to style small dropdown buttons +// $dropdown-button-padding-sml: $button-pip-sml * 7; +// $dropdown-button-pip-size-sml: $button-pip-sml; +// $dropdown-button-pip-opposite-sml: $button-pip-sml * 3; +// $dropdown-button-pip-top-sml: (-$button-pip-sml / 2) + rem-calc(1); + +// We use these to style medium dropdown buttons +// $dropdown-button-padding-med: $button-pip-med * 6 + rem-calc(3); +// $dropdown-button-pip-size-med: $button-pip-med - rem-calc(3); +// $dropdown-button-pip-opposite-med: $button-pip-med * 2.5; +// $dropdown-button-pip-top-med: (-$button-pip-med / 2) + rem-calc(2); + +// We use these to style large dropdown buttons +// $dropdown-button-padding-lrg: $button-pip-lrg * 5 + rem-calc(3); +// $dropdown-button-pip-size-lrg: $button-pip-lrg - rem-calc(6); +// $dropdown-button-pip-opposite-lrg: $button-pip-lrg * 2.5; +// $dropdown-button-pip-top-lrg: (-$button-pip-lrg / 2) + rem-calc(3); + +// 10. Flex Video +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-media-classes: $include-html-classes; + +// We use these to control video container padding and margins +// $flex-video-padding-top: rem-calc(25); +// $flex-video-padding-bottom: 67.5%; +// $flex-video-margin-bottom: rem-calc(16); + +// We use this to control widescreen bottom padding +// $flex-video-widescreen-padding-bottom: 56.34%; + +// 11. Forms +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-form-classes: $include-html-classes; + +// We use this to set the base for lots of form spacing and positioning styles +// $form-spacing: rem-calc(16); + +// We use these to style the labels in different ways +// $form-label-pointer: pointer; +// $form-label-font-size: rem-calc(14); +// $form-label-font-weight: $font-weight-normal; +// $form-label-line-height: 1.5; +// $form-label-font-color: scale-color($black, $lightness: 30%); +// $form-label-small-transform: capitalize; +// $form-label-bottom-margin: 0; +// $input-font-family: inherit; +// $input-font-color: rgba(0,0,0,0.75); +// $input-font-size: rem-calc(14); +// $input-bg-color: $white; +// $input-focus-bg-color: scale-color($white, $lightness: -2%); +// $input-border-color: scale-color($white, $lightness: -20%); +// $input-focus-border-color: scale-color($white, $lightness: -40%); +// $input-border-style: solid; +// $input-border-width: 1px; +// $input-border-radius: $global-radius; +// $input-disabled-bg: $gainsboro; +// $input-disabled-cursor: $cursor-default-value; +// $input-box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); +// $input-include-glowing-effect: false; + +// We use these to style the fieldset border and spacing. +// $fieldset-border-style: solid; +// $fieldset-border-width: 1px; +// $fieldset-border-color: $gainsboro; +// $fieldset-padding: rem-calc(20); +// $fieldset-margin: rem-calc(18 0); + +// We use these to style the legends when you use them +// $legend-bg: $white; +// $legend-font-weight: $font-weight-bold; +// $legend-padding: rem-calc(0 3); + +// We use these to style the prefix and postfix input elements +// $input-prefix-bg: scale-color($white, $lightness: -5%); +// $input-prefix-border-color: scale-color($white, $lightness: -20%); +// $input-prefix-border-size: 1px; +// $input-prefix-border-type: solid; +// $input-prefix-overflow: hidden; +// $input-prefix-font-color: $oil; +// $input-prefix-font-color-alt: $white; + +// We use this setting to turn on/off HTML5 number spinners (the up/down arrows) +// $input-number-spinners: true; + +// We use these to style the error states for inputs and labels +// $input-error-message-padding: rem-calc(6 9 9); +// $input-error-message-top: -1px; +// $input-error-message-font-size: rem-calc(12); +// $input-error-message-font-weight: $font-weight-normal; +// $input-error-message-font-style: italic; +// $input-error-message-font-color: $white; +// $input-error-message-bg-color: $alert-color; +// $input-error-message-font-color-alt: $oil; + +// We use this to style the glowing effect of inputs when focused +// $glowing-effect-fade-time: .45s; +// $glowing-effect-color: $input-focus-border-color; + +// We use this to style the transition when inputs are focused and when the glowing effect is disabled. +// $input-transition-fade-time: 0.15s; +// $input-transition-fade-timing-function: linear; + +// Select variables +// $select-bg-color: $ghost; +// $select-hover-bg-color: scale-color($select-bg-color, $lightness: -3%); + + +// 12. Icon Bar +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// We use these to style the icon-bar and items +// $icon-bar-bg: $oil; +// $icon-bar-font-color: $white; +// $icon-bar-font-color-hover: $icon-bar-font-color; +// $icon-bar-font-size: 1rem; +// $icon-bar-hover-color: $primary-color; +// $icon-bar-icon-color: $white; +// $icon-bar-icon-color-hover: $icon-bar-icon-color; +// $icon-bar-icon-size: 1.875rem; +// $icon-bar-image-width: 1.875rem; +// $icon-bar-image-height: 1.875rem; +// $icon-bar-active-color: $primary-color; +// $icon-bar-item-padding: 1.25rem; + +// We use this to set default opacity and cursor for disabled icons. +// $icon-bar-disabled-opacity: .7; + +// 13. Inline Lists +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-inline-list-classes: $include-html-classes; + +// We use this to control the margins and padding of the inline list. +// $inline-list-top-margin: 0; +// $inline-list-opposite-margin: 0; +// $inline-list-bottom-margin: rem-calc(17); +// $inline-list-default-float-margin: rem-calc(-22); +// $inline-list-default-float-list-margin: rem-calc(22); + +// $inline-list-padding: 0; + +// We use this to control the overflow of the inline list. +// $inline-list-overflow: hidden; + +// We use this to control the list items +// $inline-list-display: block; + +// We use this to control any elements within list items +// $inline-list-children-display: block; + +// 14. Joyride +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-joyride-classes: $include-html-classes; + +// Controlling default Joyride styles +// $joyride-tip-bg: $oil; +// $joyride-tip-default-width: 300px; +// $joyride-tip-padding: rem-calc(18 20 24); +// $joyride-tip-border: solid 1px $charcoal; +// $joyride-tip-radius: 4px; +// $joyride-tip-position-offset: 22px; + +// Here, we're setting the tip font styles +// $joyride-tip-font-color: $white; +// $joyride-tip-font-size: rem-calc(14); +// $joyride-tip-header-weight: $font-weight-bold; + +// This changes the nub size +// $joyride-tip-nub-size: 10px; + +// This adjusts the styles for the timer when its enabled +// $joyride-tip-timer-width: 50px; +// $joyride-tip-timer-height: 3px; +// $joyride-tip-timer-color: $steel; + +// This changes up the styles for the close button +// $joyride-tip-close-color: $monsoon; +// $joyride-tip-close-size: 24px; +// $joyride-tip-close-weight: $font-weight-normal; + +// When Joyride is filling the screen, we use this style for the bg +// $joyride-screenfill: rgba(0,0,0,0.5); + +// 15. Keystrokes +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-keystroke-classes: $include-html-classes; + +// We use these to control text styles. +// $keystroke-font: "Consolas", "Menlo", "Courier", monospace; +// $keystroke-font-size: inherit; +// $keystroke-font-color: $jet; +// $keystroke-font-color-alt: $white; +// $keystroke-function-factor: -7%; + +// We use this to control keystroke padding. +// $keystroke-padding: rem-calc(2 4 0); + +// We use these to control background and border styles. +// $keystroke-bg: scale-color($white, $lightness: $keystroke-function-factor); +// $keystroke-border-style: solid; +// $keystroke-border-width: 1px; +// $keystroke-border-color: scale-color($keystroke-bg, $lightness: $keystroke-function-factor); +// $keystroke-radius: $global-radius; + +// 16. Labels +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-label-classes: $include-html-classes; + +// We use these to style the labels +// $label-padding: rem-calc(4 8 4); +// $label-radius: $global-radius; + +// We use these to style the label text +// $label-font-sizing: rem-calc(11); +// $label-font-weight: $font-weight-normal; +// $label-font-color: $oil; +// $label-font-color-alt: $white; +// $label-font-family: $body-font-family; + +// 17. Magellan +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-magellan-classes: $include-html-classes; + +// $magellan-bg: $white; +// $magellan-padding: 10px; + +// 18. Off-canvas +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// Off Canvas Tab Bar Variables +// $include-html-off-canvas-classes: $include-html-classes; + +// $tabbar-bg: $oil; +// $tabbar-height: rem-calc(45); +// $tabbar-icon-width: $tabbar-height; +// $tabbar-line-height: $tabbar-height; +// $tabbar-color: $white; +// $tabbar-middle-padding: 0 rem-calc(10); + +// Off Canvas Divider Styles +// $tabbar-left-section-border: solid 1px scale-color($tabbar-bg, $lightness: -50%); +// $tabbar-right-section-border: $tabbar-left-section-border; + + +// Off Canvas Tab Bar Headers +// $tabbar-header-color: $white; +// $tabbar-header-weight: $font-weight-bold; +// $tabbar-header-line-height: $tabbar-height; +// $tabbar-header-margin: 0; + +// Off Canvas Menu Variables +// $off-canvas-width: rem-calc(250); +// $off-canvas-bg: $oil; +// $off-canvas-bg-hover: scale-color($tabbar-bg, $lightness: -30%); +// $off-canvas-bg-active: scale-color($tabbar-bg, $lightness: -30%); + +// Off Canvas Menu List Variables +// $off-canvas-label-padding: .3rem rem-calc(15); +// $off-canvas-label-color: $aluminum; +// $off-canvas-label-text-transform: uppercase; +// $off-canvas-label-font-size: rem-calc(12); +// $off-canvas-label-font-weight: $font-weight-bold; +// $off-canvas-label-bg: $tuatara; +// $off-canvas-label-border-top: 1px solid scale-color($off-canvas-label-bg, $lightness: 14%); +// $off-canvas-label-border-bottom: none; +// $off-canvas-label-margin:0; +// $off-canvas-link-padding: rem-calc(10, 15); +// $off-canvas-link-color: rgba($white, .7); +// $off-canvas-link-border-bottom: 1px solid scale-color($off-canvas-bg, $lightness: -25%); +// $off-canvas-back-bg: #444; +// $off-canvas-back-border-top: $off-canvas-label-border-top; +// $off-canvas-back-border-bottom: $off-canvas-label-border-bottom; +// $off-canvas-back-hover-bg: scale-color($off-canvas-back-bg, $lightness: -30%); +// $off-canvas-back-hover-border-top: 1px solid scale-color($off-canvas-label-bg, $lightness: 14%); +// $off-canvas-back-hover-border-bottom: none; + +// Off Canvas Menu Icon Variables +// $tabbar-menu-icon-color: $white; +// $tabbar-menu-icon-hover: scale-color($tabbar-menu-icon-color, $lightness: -30%); + +// $tabbar-menu-icon-text-indent: rem-calc(35); +// $tabbar-menu-icon-width: $tabbar-icon-width; +// $tabbar-menu-icon-height: $tabbar-height; +// $tabbar-menu-icon-padding: 0; + +// $tabbar-hamburger-icon-width: rem-calc(16); +// $tabbar-hamburger-icon-left: false; +// $tabbar-hamburger-icon-top: false; +// $tabbar-hamburger-icon-thickness: 1px; +// $tabbar-hamburger-icon-gap: 6px; + +// Off Canvas Back-Link Overlay +// $off-canvas-overlay-transition: background 300ms ease; +// $off-canvas-overlay-cursor: pointer; +// $off-canvas-overlay-box-shadow: -4px 0 4px rgba($black, .5), 4px 0 4px rgba($black, .5); +// $off-canvas-overlay-background: rgba($white, .2); +// $off-canvas-overlay-background-hover: rgba($white, .05); + +// Transition Variables +// $menu-slide: "transform 500ms ease"; + +// 19. Orbit +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-orbit-classes: $include-html-classes; + +// We use these to control the caption styles +// $orbit-container-bg: none; +// $orbit-caption-bg: rgba(51,51,51, .8); +// $orbit-caption-font-color: $white; +// $orbit-caption-font-size: rem-calc(14); +// $orbit-caption-position: "bottom"; // Supported values: "bottom", "under" +// $orbit-caption-padding: rem-calc(10 14); +// $orbit-caption-height: auto; + +// We use these to control the left/right nav styles +// $orbit-nav-bg: transparent; +// $orbit-nav-bg-hover: rgba(0,0,0,0.3); +// $orbit-nav-arrow-color: $white; +// $orbit-nav-arrow-color-hover: $white; + +// We use these to control the timer styles +// $orbit-timer-bg: rgba(255,255,255,0.3); +// $orbit-timer-show-progress-bar: true; + +// We use these to control the bullet nav styles +// $orbit-bullet-nav-color: $iron; +// $orbit-bullet-nav-color-active: $aluminum; +// $orbit-bullet-radius: rem-calc(9); + +// We use these to controls the style of slide numbers +// $orbit-slide-number-bg: rgba(0,0,0,0); +// $orbit-slide-number-font-color: $white; +// $orbit-slide-number-padding: rem-calc(5); + +// Graceful Loading Wrapper and preloader +// $wrapper-class: "slideshow-wrapper"; +// $preloader-class: "preloader"; + +// Hide controls on small +// $orbit-nav-hide-for-small: true; +// $orbit-bullet-hide-for-small: true; +// $orbit-timer-hide-for-small: true; + +// 20. Pagination +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-pagination-classes: $include-html-classes; + +// We use these to control the pagination container +// $pagination-height: rem-calc(24); +// $pagination-margin: rem-calc(-5); + +// We use these to set the list-item properties +// $pagination-li-float: $default-float; +// $pagination-li-height: rem-calc(24); +// $pagination-li-font-color: $jet; +// $pagination-li-font-size: rem-calc(14); +// $pagination-li-margin: rem-calc(5); + +// We use these for the pagination anchor links +// $pagination-link-pad: rem-calc(1 10 1); +// $pagination-link-font-color: $aluminum; +// $pagination-link-active-bg: scale-color($white, $lightness: -10%); + +// We use these for disabled anchor links +// $pagination-link-unavailable-cursor: default; +// $pagination-link-unavailable-font-color: $aluminum; +// $pagination-link-unavailable-bg-active: transparent; + +// We use these for currently selected anchor links +// $pagination-link-current-background: $primary-color; +// $pagination-link-current-font-color: $white; +// $pagination-link-current-font-weight: $font-weight-bold; +// $pagination-link-current-cursor: default; +// $pagination-link-current-active-bg: $primary-color; + +// 21. Panels +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-panel-classes: $include-html-classes; + +// We use these to control the background and border styles +// $panel-bg: scale-color($white, $lightness: -5%); +// $panel-border-style: solid; +// $panel-border-size: 1px; +// $callout-panel-bg: scale-color($primary-color, $lightness: 94%); + +// We use this % to control how much we darken things on hover +// $panel-border-color: scale-color($panel-bg, $lightness: -11%); + +// We use these to set default inner padding and bottom margin +// $panel-margin-bottom: rem-calc(20); +// $panel-padding: rem-calc(20); + +// We use these to set default font colors +// $panel-font-color: $oil; +// $panel-font-color-alt: $white; + +// $panel-header-adjust: true; +// $callout-panel-link-color: $primary-color; +// $callout-panel-link-color-hover: scale-color($callout-panel-link-color, $lightness: -14%); + +// 22. Pricing Tables +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-pricing-classes: $include-html-classes; + +// We use this to control the border color +// $price-table-border: solid 1px $gainsboro; + +// We use this to control the bottom margin of the pricing table +// $price-table-margin-bottom: rem-calc(20); + +// We use these to control the title styles +// $price-title-bg: $oil; +// $price-title-padding: rem-calc(15 20); +// $price-title-align: center; +// $price-title-color: $smoke; +// $price-title-weight: $font-weight-normal; +// $price-title-size: rem-calc(16); +// $price-title-font-family: $body-font-family; + +// We use these to control the price styles +// $price-money-bg: $vapor; +// $price-money-padding: rem-calc(15 20); +// $price-money-align: center; +// $price-money-color: $oil; +// $price-money-weight: $font-weight-normal; +// $price-money-size: rem-calc(32); +// $price-money-font-family: $body-font-family; + + +// We use these to control the description styles +// $price-bg: $white; +// $price-desc-color: $monsoon; +// $price-desc-padding: rem-calc(15); +// $price-desc-align: center; +// $price-desc-font-size: rem-calc(12); +// $price-desc-weight: $font-weight-normal; +// $price-desc-line-height: 1.4; +// $price-desc-bottom-border: dotted 1px $gainsboro; + +// We use these to control the list item styles +// $price-item-color: $oil; +// $price-item-padding: rem-calc(15); +// $price-item-align: center; +// $price-item-font-size: rem-calc(14); +// $price-item-weight: $font-weight-normal; +// $price-item-bottom-border: dotted 1px $gainsboro; + +// We use these to control the CTA area styles +// $price-cta-bg: $white; +// $price-cta-align: center; +// $price-cta-padding: rem-calc(20 20 0); + +// 23. Progress Bar +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-media-classes: $include-html-classes; + +// We use this to set the progress bar height +// $progress-bar-height: rem-calc(25); +// $progress-bar-color: $vapor; + +// We use these to control the border styles +// $progress-bar-border-color: scale-color($white, $lightness: 20%); +// $progress-bar-border-size: 1px; +// $progress-bar-border-style: solid; +// $progress-bar-border-radius: $global-radius; + +// We use these to control the margin & padding +// $progress-bar-margin-bottom: rem-calc(10); + +// We use these to set the meter colors +// $progress-meter-color: $primary-color; +// $progress-meter-secondary-color: $secondary-color; +// $progress-meter-success-color: $success-color; +// $progress-meter-alert-color: $alert-color; + +// 24. Range Slider +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-range-slider-classes: $include-html-classes; + +// These variables define the slider bar styles +// $range-slider-bar-width: 100%; +// $range-slider-bar-height: rem-calc(16); + +// $range-slider-bar-border-width: 1px; +// $range-slider-bar-border-style: solid; +// $range-slider-bar-border-color: $gainsboro; +// $range-slider-radius: $global-radius; +// $range-slider-round: $global-rounded; +// $range-slider-bar-bg-color: $ghost; +// $range-slider-active-segment-bg-color: scale-color($secondary-color, $lightness: -1%); + +// Vertical bar styles +// $range-slider-vertical-bar-width: rem-calc(16); +// $range-slider-vertical-bar-height: rem-calc(200); + +// These variabels define the slider handle styles +// $range-slider-handle-width: rem-calc(32); +// $range-slider-handle-height: rem-calc(22); +// $range-slider-handle-position-top: rem-calc(-5); +// $range-slider-handle-bg-color: $primary-color; +// $range-slider-handle-border-width: 1px; +// $range-slider-handle-border-style: solid; +// $range-slider-handle-border-color: none; +// $range-slider-handle-radius: $global-radius; +// $range-slider-handle-round: $global-rounded; +// $range-slider-handle-bg-hover-color: scale-color($primary-color, $lightness: -12%); +// $range-slider-handle-cursor: pointer; + +// $range-slider-disabled-opacity: .7; +// $range-slider-disabled-cursor: $cursor-disabled-value; + +// 25. Reveal +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-reveal-classes: $include-html-classes; + +// We use these to control the style of the reveal overlay. +// $reveal-overlay-bg: rgba($black, .45); +// $reveal-overlay-bg-old: $black; + +// We use these to control the style of the modal itself. +// $reveal-modal-bg: $white; +// $reveal-position-top: rem-calc(100); +// $reveal-default-width: 80%; +// $reveal-max-width: $row-width; +// $reveal-modal-padding: rem-calc(20); +// $reveal-box-shadow: 0 0 10px rgba($black,.4); + +// We use these to style the reveal close button +// $reveal-close-font-size: rem-calc(40); +// $reveal-close-top: rem-calc(10); +// $reveal-close-side: rem-calc(22); +// $reveal-close-color: $base; +// $reveal-close-weight: $font-weight-bold; + +// We use this to set the default radius used throughout the core. +// $reveal-radius: $global-radius; +// $reveal-round: $global-rounded; + +// We use these to control the modal border +// $reveal-border-style: solid; +// $reveal-border-width: 1px; +// $reveal-border-color: $steel; + +// $reveal-modal-class: "reveal-modal"; +// $close-reveal-modal-class: "close-reveal-modal"; + +// 26. Side Nav +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-nav-classes: $include-html-classes; + +// We use this to control padding. +// $side-nav-padding: rem-calc(14 0); + +// We use these to control list styles. +// $side-nav-list-type: none; +// $side-nav-list-position: outside; +// $side-nav-list-margin: rem-calc(0 0 7 0); + +// We use these to control link styles. +// $side-nav-link-color: $primary-color; +// $side-nav-link-color-active: scale-color($side-nav-link-color, $lightness: 30%); +// $side-nav-link-color-hover: scale-color($side-nav-link-color, $lightness: 30%); +// $side-nav-link-bg-hover: hsla(0, 0, 0, .025); +// $side-nav-link-margin: 0; +// $side-nav-link-padding: rem-calc(7 14); +// $side-nav-font-size: rem-calc(14); +// $side-nav-font-weight: $font-weight-normal; +// $side-nav-font-weight-active: $side-nav-font-weight; +// $side-nav-font-family: $body-font-family; +// $side-nav-font-family-active: $side-nav-font-family; + +// We use these to control heading styles. +// $side-nav-heading-color: $side-nav-link-color; +// $side-nav-heading-font-size: $side-nav-font-size; +// $side-nav-heading-font-weight: bold; +// $side-nav-heading-text-transform: uppercase; + +// We use these to control border styles +// $side-nav-divider-size: 1px; +// $side-nav-divider-style: solid; +// $side-nav-divider-color: scale-color($white, $lightness: 10%); + +// 27. Split Buttons +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-button-classes: $include-html-classes; + +// We use these to control different shared styles for Split Buttons +// $split-button-function-factor: 10%; +// $split-button-pip-color: $white; +// $split-button-span-border-color: rgba(255,255,255,0.5); +// $split-button-pip-color-alt: $oil; +// $split-button-active-bg-tint: rgba(0,0,0,0.1); + +// We use these to control tiny split buttons +// $split-button-padding-tny: $button-pip-tny * 10; +// $split-button-span-width-tny: $button-pip-tny * 6; +// $split-button-pip-size-tny: $button-pip-tny; +// $split-button-pip-top-tny: $button-pip-tny * 2; +// $split-button-pip-default-float-tny: rem-calc(-6); + +// We use these to control small split buttons +// $split-button-padding-sml: $button-pip-sml * 10; +// $split-button-span-width-sml: $button-pip-sml * 6; +// $split-button-pip-size-sml: $button-pip-sml; +// $split-button-pip-top-sml: $button-pip-sml * 1.5; +// $split-button-pip-default-float-sml: rem-calc(-6); + +// We use these to control medium split buttons +// $split-button-padding-med: $button-pip-med * 9; +// $split-button-span-width-med: $button-pip-med * 5.5; +// $split-button-pip-size-med: $button-pip-med - rem-calc(3); +// $split-button-pip-top-med: $button-pip-med * 1.5; +// $split-button-pip-default-float-med: rem-calc(-6); + +// We use these to control large split buttons +// $split-button-padding-lrg: $button-pip-lrg * 8; +// $split-button-span-width-lrg: $button-pip-lrg * 5; +// $split-button-pip-size-lrg: $button-pip-lrg - rem-calc(6); +// $split-button-pip-top-lrg: $button-pip-lrg + rem-calc(5); +// $split-button-pip-default-float-lrg: rem-calc(-6); + +// 28. Sub Nav +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-nav-classes: $include-html-classes; + +// We use these to control margin and padding +// $sub-nav-list-margin: rem-calc(-4 0 18); +// $sub-nav-list-padding-top: rem-calc(4); + +// We use this to control the definition +// $sub-nav-font-family: $body-font-family; +// $sub-nav-font-size: rem-calc(14); +// $sub-nav-font-color: $aluminum; +// $sub-nav-font-weight: $font-weight-normal; +// $sub-nav-text-decoration: none; +// $sub-nav-padding: rem-calc(3 16); +// $sub-nav-border-radius: 3px; +// $sub-nav-font-color-hover: scale-color($sub-nav-font-color, $lightness: -25%); + + +// We use these to control the active item styles + +// $sub-nav-active-font-weight: $font-weight-normal; +// $sub-nav-active-bg: $primary-color; +// $sub-nav-active-bg-hover: scale-color($sub-nav-active-bg, $lightness: -14%); +// $sub-nav-active-color: $white; +// $sub-nav-active-padding: $sub-nav-padding; +// $sub-nav-active-cursor: default; + +// $sub-nav-item-divider: ""; +// $sub-nav-item-divider-margin: rem-calc(12); + +// 29. Switch +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-form-classes: $include-html-classes; + +// Controlling background color for the switch container +// $switch-bg: $gainsboro; + +// We use these to control the switch heights for our default classes +// $switch-height-tny: 1.5rem; +// $switch-height-sml: 1.75rem; +// $switch-height-med: 2rem; +// $switch-height-lrg: 2.5rem; +// $switch-bottom-margin: 1.5rem; + +// We use these to style the switch-paddle +// $switch-paddle-bg: $white; +// $switch-paddle-transition-speed: .15s; +// $switch-paddle-transition-ease: ease-out; +// $switch-active-color: $primary-color; + +// 30. Tables +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-table-classes: $include-html-classes; + +// These control the background color for the table and even rows +// $table-bg: $white; +// $table-even-row-bg: $snow; + +// These control the table cell border style +// $table-border-style: solid; +// $table-border-size: 1px; +// $table-border-color: $gainsboro; + +// These control the table head styles +// $table-head-bg: $white-smoke; +// $table-head-font-size: rem-calc(14); +// $table-head-font-color: $jet; +// $table-head-font-weight: $font-weight-bold; +// $table-head-padding: rem-calc(8 10 10); + +// These control the table foot styles +// $table-foot-bg: $table-head-bg; +// $table-foot-font-size: $table-head-font-size; +// $table-foot-font-color: $table-head-font-color; +// $table-foot-font-weight: $table-head-font-weight; +// $table-foot-padding: $table-head-padding; + +// These control the caption +// table-caption-bg: transparent; +// $table-caption-font-color: $table-head-font-color; +// $table-caption-font-size: rem-calc(16); +// $table-caption-font-weight: bold; + +// These control the row padding and font styles +// $table-row-padding: rem-calc(9 10); +// $table-row-font-size: rem-calc(14); +// $table-row-font-color: $jet; +// $table-line-height: rem-calc(18); + +// These are for controlling the layout, display and margin of tables +// $table-layout: auto; +// $table-display: table-cell; +// $table-margin-bottom: rem-calc(20); + + +// 31. Tabs +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-tabs-classes: $include-html-classes; + +// $tabs-navigation-padding: rem-calc(16); +// $tabs-navigation-bg-color: $silver; +// $tabs-navigation-active-bg-color: $white; +// $tabs-navigation-hover-bg-color: scale-color($tabs-navigation-bg-color, $lightness: -6%); +// $tabs-navigation-font-color: $jet; +// $tabs-navigation-active-font-color: $tabs-navigation-font-color; +// $tabs-navigation-font-size: rem-calc(16); +// $tabs-navigation-font-family: $body-font-family; + +// $tabs-content-margin-bottom: rem-calc(24); +// $tabs-content-padding: ($column-gutter/2); + +// $tabs-vertical-navigation-margin-bottom: 1.25rem; + +// 32. Thumbnails +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-media-classes: $include-html-classes; + +// We use these to control border styles +// $thumb-border-style: solid; +// $thumb-border-width: 4px; +// $thumb-border-color: $white; +// $thumb-box-shadow: 0 0 0 1px rgba($black,.2); +// $thumb-box-shadow-hover: 0 0 6px 1px rgba($primary-color,0.5); + +// Radius and transition speed for thumbs +// $thumb-radius: $global-radius; +// $thumb-transition-speed: 200ms; + +// 33. Tooltips +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-tooltip-classes: $include-html-classes; + +// $has-tip-border-bottom: dotted 1px $iron; +// $has-tip-font-weight: $font-weight-bold; +// $has-tip-font-color: $oil; +// $has-tip-border-bottom-hover: dotted 1px scale-color($primary-color, $lightness: -55%); +// $has-tip-font-color-hover: $primary-color; +// $has-tip-cursor-type: help; + +// $tooltip-padding: rem-calc(12); +// $tooltip-bg: $oil; +// $tooltip-font-size: rem-calc(14); +// $tooltip-font-weight: $font-weight-normal; +// $tooltip-font-color: $white; +// $tooltip-line-height: 1.3; +// $tooltip-close-font-size: rem-calc(10); +// $tooltip-close-font-weight: $font-weight-normal; +// $tooltip-close-font-color: $monsoon; +// $tooltip-font-size-sml: rem-calc(14); +// $tooltip-radius: $global-radius; +// $tooltip-rounded: $global-rounded; +// $tooltip-pip-size: 5px; +// $tooltip-max-width: 300px; + +// 34. Top Bar +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-top-bar-classes: $include-html-classes; + +// Background color for the top bar +// $topbar-bg-color: $oil; +// $topbar-bg: $topbar-bg-color; + +// Height and margin +// $topbar-height: rem-calc(45); +// $topbar-margin-bottom: 0; + +// Controlling the styles for the title in the top bar +// $topbar-title-weight: $font-weight-normal; +// $topbar-title-font-size: rem-calc(17); + +// Set the link colors and styles for top-level nav +// $topbar-link-color: $white; +// $topbar-link-color-hover: $white; +// $topbar-link-color-active: $white; +// $topbar-link-color-active-hover: $white; +// $topbar-link-weight: $font-weight-normal; +// $topbar-link-font-size: rem-calc(13); +// $topbar-link-hover-lightness: -10%; // Darken by 10% +// $topbar-link-bg: $topbar-bg; +// $topbar-link-bg-hover: $jet; +// $topbar-link-bg-color-hover: $charcoal; +// $topbar-link-bg-active: $primary-color; +// $topbar-link-bg-active-hover: scale-color($primary-color, $lightness: -14%); +// $topbar-link-font-family: $body-font-family; +// $topbar-link-text-transform: none; +// $topbar-link-padding: ($topbar-height / 3); +// $topbar-back-link-size: rem-calc(18); +// $topbar-link-dropdown-padding: rem-calc(20); +// $topbar-button-font-size: .75rem; +// $topbar-button-top: 7px; + +// Style the top bar dropdown elements +// $topbar-dropdown-bg: $oil; +// $topbar-dropdown-link-color: $white; +// $topbar-dropdown-link-color-hover: $topbar-link-color-hover; +// $topbar-dropdown-link-bg: $oil; +// $topbar-dropdown-link-bg-hover: $jet; +// $topbar-dropdown-link-weight: $font-weight-normal; +// $topbar-dropdown-toggle-size: 5px; +// $topbar-dropdown-toggle-color: $white; +// $topbar-dropdown-toggle-alpha: .4; + +// $topbar-dropdown-label-color: $monsoon; +// $topbar-dropdown-label-text-transform: uppercase; +// $topbar-dropdown-label-font-weight: $font-weight-bold; +// $topbar-dropdown-label-font-size: rem-calc(10); +// $topbar-dropdown-label-bg: $oil; + +// Top menu icon styles +// $topbar-menu-link-transform: uppercase; +// $topbar-menu-link-font-size: rem-calc(13); +// $topbar-menu-link-weight: $font-weight-bold; +// $topbar-menu-link-color: $white; +// $topbar-menu-icon-color: $white; +// $topbar-menu-link-color-toggled: $jumbo; +// $topbar-menu-icon-color-toggled: $jumbo; +// $topbar-menu-icon-position: $opposite-direction; // Change to $default-float for a left menu icon + +// Transitions and breakpoint styles +// $topbar-transition-speed: 300ms; +// Using rem-calc for the below breakpoint causes issues with top bar +// $topbar-breakpoint: #{lower-bound($medium-range)}; // Change to 9999px for always mobile layout +// $topbar-media-query: "#{$screen} and (min-width:#{lower-bound($topbar-breakpoint)})"; + +// Top-bar input styles +// $topbar-input-height: rem-calc(28); + +// Divider Styles +// $topbar-divider-border-bottom: solid 1px scale-color($topbar-bg-color, $lightness: 13%); +// $topbar-divider-border-top: solid 1px scale-color($topbar-bg-color, $lightness: -50%); + +// Sticky Class +// $topbar-sticky-class: ".sticky"; +// $topbar-arrows: true; //Set false to remove the triangle icon from the menu item +// $topbar-dropdown-arrows: true; //Set false to remove the \00bb >> text from dropdown subnavigation li// + +// 36. Visibility Classes +// - - - - - - - - - - - - - - - - - - - - - - - - - + +// $include-html-visibility-classes: $include-html-classes; +// $include-accessibility-classes: true; +// $include-table-visibility-classes: true; +// $include-legacy-visibility-classes: true; diff --git a/static/app/styles/app.scss b/static/app/styles/app.scss new file mode 100644 index 0000000..e20fba9 --- /dev/null +++ b/static/app/styles/app.scss @@ -0,0 +1,30 @@ +@import "settings"; // Global settings + +@import "../../bower_components/foundation/scss/normalize"; +@import + "../../bower_components/foundation/scss/foundation/components/block-grid", + "../../bower_components/foundation/scss/foundation/components/buttons", + "../../bower_components/foundation/scss/foundation/components/dropdown", + "../../bower_components/foundation/scss/foundation/components/dropdown-buttons", + "../../bower_components/foundation/scss/foundation/components/forms", + "../../bower_components/foundation/scss/foundation/components/grid", + "../../bower_components/foundation/scss/foundation/components/inline-lists", + "../../bower_components/foundation/scss/foundation/components/labels", + "../../bower_components/foundation/scss/foundation/components/progress-bars", + "../../bower_components/foundation/scss/foundation/components/reveal", + "../../bower_components/foundation/scss/foundation/components/sub-nav", + "../../bower_components/foundation/scss/foundation/components/tables", + "../../bower_components/foundation/scss/foundation/components/tooltips", + "../../bower_components/foundation/scss/foundation/components/top-bar", + "../../bower_components/foundation/scss/foundation/components/type", + "../../bower_components/foundation/scss/foundation/components/visibility"; + +/* Vendor styles */ +@import "../../bower_components/components-font-awesome/scss/font-awesome"; + +/* Global styles */ +body { + background-color: $body-bg; +} + +@import "header"; \ No newline at end of file diff --git a/static/bower.json b/static/bower.json new file mode 100644 index 0000000..5f8af20 --- /dev/null +++ b/static/bower.json @@ -0,0 +1,28 @@ +{ + "name": "sis-slides", + "private": true, + "dependencies": { + "jquery": "latest", + "foundation": "latest", + "underscore": "~1.8.3", + "list.js": "~1.1.1", + "components-font-awesome": "~4.3.0" + }, + "devDependencies": {}, + "resolutions": { + "jquery": "2.1.4" + }, + "overrides": { + "components-font-awesome": { + "main": [ + "css/font-awesome.css", + "scss/font-awesome.scss", + "fonts/fontawesome-webfont.eot", + "fonts/fontawesome-webfont.woff", + "fonts/fontawesome-webfont.woff2", + "fonts/fontawesome-webfont.ttf", + "fonts/fontawesome-webfont.svg" + ] + } + } +} diff --git a/static/dist/fonts/fontawesome-webfont.eot b/static/dist/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000000000000000000000000000000000000..33b2bb80055cc480e797de704925acaba4ba7d7d GIT binary patch literal 60767 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%0DKehr}RFC`2XTB_?==0w^)u1m5PYii@6f)6_5Ydu zv+NIZ_(Rt}Q++LT5!n8!J4x!>sE&v_3*cXat{Zq5;17w;B6$epw}$Rg`0nFJg5D-L zYvw@(goc5TeJjM($AJAZxZHZN}RzBcP0=_>ZI6WVGU zO#Nk-YqZTa3{!84P0K~GsI#32<+_AsXU43wILwZS(8n%S9)lP!Dg$$e2$$9$E?^Nj zql4do#+a8qEP(bD2)DpP|$dp<`TZ#bY6^~7Xv_Lle)77^OsVhMOm(@ z??8O8kA%}ZWpR&2v!7qFSw@TF6d*=9YT^Rtk(n8p=CQWvt1Om=n&5uP;GiT6 zMRvbm39kbp*KB`qoVg12w52Z)T}`X41P>D|q_%K#zuhwb+BpEogY0E)KnSy#@+(m5 z20@LG@LUEvk`I|OIUV^^0_YtG9AElBS!Dsh%k^P9r0moJ25Lkm-gh#igwBDhAOj0!EF&8MxV^-m1U1MEd?H7} zL;r;tfFIT|ei3-Z@gyM=!%Ba7Pa626JRAA`V<2D<{RLRT@0o=bE)XF)nFtUL67`2L z{?_Qz_`Yy2t+I)?9&z#z__Q%L3pnhN}U z_rN#WU)kD59D4whbSYERHY01jM7id50EuI1ctl?<_IT=Y5vP>(sNNkB&U5&F&^kBhm5y{o!y!F+4wdxXoy;!4$W`?_nL(+bK_QDAMUV1O0AwZ| z6j)s}9YEZbY-C^Y)9Ej`aS&~{sXCG2SS3ce$EY;Yv-c8TlrD$C85ATlLZpGP_YWfi z`RQ?z1@zIfa{yqfsUDMEPpwuX%XHdO+ASb3EPi1fBPocvfgsC0xa^CG2SWBPWQ&GS zpCXPti8b>WkYbf#Vg%A?&_UwUsUQE_t4GX?7QqUpKJ2Iw#%)Q4Ft(`9Ja&Yk{C@38 z@%T`)#wWy(kKfEH;ZBQ(m*Iq&L=<)4D7tNO{SsA4Fp4D?(Ex6nQS&f3TK|atgj`fE z2|OX0(&(ZqxJd~IANX&dvX?U14_<~h2(lP6k^H8ep;2HW6oPo?U%v{M>|{sU~;p zLTv$OTx3H^4zNUn4wUfo>j{CEvTC@C+cw+cW*ABH6u@!M2EdBL?1GbL_#e;7YDBas zic?MTazk(khXSyPeDom_I~wkLv?Wr8<%egEfM!*M9^kl$>zsVzaP}S!gcD3;Czy#58RTm?`p)RTS8I<-sC3+*n{A)P*rU!@Npj`e{x9xsif2v zTW`{q3p^?A!Mk60Q{(FLt(&TVe9z z0-!PiOV02JcNeq?AbJaI+B9xC;LB=}Ho0vH(@;Qe0zq~-8ckOa!(u@Wou`p_TR|QT z38H`lJE$G{q1egUX@&v$x7wNLWD#j*!D58GLv^bT+jpdKBrK#SsQsWK(+RO40VA^w z0nA7MN1Y1Fc#5JkwD5TtHG1t;lo=i)U+kFG?1Jh11h9382!marrRE2eZh;JGh`wNO zQA_~n?%97HOKLA^#oG(5*bgSllS%rOc(S%Yj00cYR;!D9G_90{pfq7D4I*$k?byOV zR|epi%oIJ{ou`5zS!-_dnxOa{uNv)(luMo^5TCOItq}2}sxCztLEzBGS)Mf6dzaw< z!GweAgvFYJu&mH(Vl9HJBV%=Jz~~i%nDGIF9ncTET-AQ=fv{L11&K_;ei!iht(!De;ym|y7ksL|^5Ko~B-vSh80++s?unD}bZaYa@ zPH4M$&fw;xEGN3_H1vHW><%-+dg7dfW)F8$bB+h7sThoOtteO(v{&-+iK}r$%G))# z*Nhx^!ZMj1VeG?EkWg+0CYQSX1t96fV9^3c+9C393LU&CHsFCa1q99$`zTMsEWwLc zxsw1|A?k8-m8HCrk6;K7dhNDJN3R9iws%6vTq_}PtR2CZ8TG;ltZ4I}sU+^s8`P3F5QxrypG1-{ zGlr^7$Wsy(lo=xfC~BpKfg<2z4OEeEF@~x{Pi7O#CvqMJy+f+}=CB_$&IuEslB@s# J000000038FvZ??8 literal 0 HcmV?d00001 diff --git a/static/dist/fonts/fontawesome-webfont.svg b/static/dist/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..1ee89d4 --- /dev/null +++ b/static/dist/fonts/fontawesome-webfont.svg @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/static/dist/fonts/fontawesome-webfont.ttf b/static/dist/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ed9372f8ea0fbaa04f42630a48887e4b38945345 GIT binary patch literal 122092 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 +|+&Vdls@0SAya!5R?! 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
    6YuX1v{q9=vI}{pN+P4FW!CI?#11< z!e^rg&DeJG*#!$zIlg7-?u#E=qIS=ivSWdEooPVGbLzEA7O}Mrjp1bF?RnQ}J~6E} z3%gUJy6~mx{3DB&T&r%oy)qeYY+xJ3O#(kz@(kUrZGoL;93B^!U=)aD0V`YuE)P@N zB$K(Z2=oEUrEn8eVc}YP(Zog$w@IcqyNPGgcor!NaUlHlA!i|exSFX?M_+~sX_Xwa z`}K}GcX`B7EytrrD(dT^_eS&6qer53>B@Vf(U&Xg$Ci?BJnPURjs68fEJ0j)ox(?lMM;f-SKdOlAkMchv5v|xCO`}jn_2@$R*N-mSzwE3Z zE!%PJ+2@>tnn!18U0|)|fLkjtMuPK)%0L*40*xxvH>8( zX&o=nps<}+Ssd}hp(hEdf9sgF@kDOptPb`!tRK_v0|I{IE#oNv594Scch0#t-gvHD z&h9dCv~k5uV;TE=b&}m>T#*!A8G0Y`d>QymmljE@rH#@KX}7cww@8W$OBuvZCmAEH zZme+-=b%9;Bfi*x-jZc3s8+f}=cY(lhn)tx9njL0a{-UQ zoEZ^IPzlwHKRlI&mXZj3SRb%_k*nt8z|{*Ogy%nMDCjyl&a9du}^> zrCndQbl3i6Gp){@JDt{<%l7YDx=vT?8_(Kv&#q z%0QyllLg6lOSi%%PFQ$HX8EG!*Y@0*Szhh5&YNd-Rxi)o*)!$R^qI?B?_4-xB2&8A zEfziNsZ9j-HtcGdlAuF=O3SW>ggEfN$@WCRGCm@EKo+t8j`3{PSaL1<9YD9EM!ZHM3W+1Wp@aAbEXnZaMI%f-|KX&Ft8~69f zmT60~%cteP5vi$6m9qz7RPC@C7frhol6pSt!UwiJe4%W)>XVQB=8F7dHiu`bji0~p zz{X2@2LCo~d3NbEKC3KM8LKcZ!o4mVdk_-+D^b}x+QSRBIx^PoL}`}!jSL1`I0P*P z2RJ+@_`*#=eGL1!qA0=i<0LQoVI>;oD@;^cPL|*klFJ2b#vg1G+@@A8hvAknO$Y)x z95R`{VqW;RXCFSD!OEg_L9y)dBret zYL3v{adD({zev%6y?Lr6Esmjn(3)Av)Ul=E2?~m)=mq90?9h;lk7`{}3pe)q$&s1K zF{1FN9xc_j9XHjAqc4^gcv(Eg?iQzfAB^J6xs-o5_6i$`PK{|npWL+W)xW_atW)X% z*1lA_4(LFv8XDbvzQ z)TXAVVd**c{z-#y{pKYbyC+SYRM~h*#4<7A_e}R}WDC!4>Ey-%ZG3n4_{#F8+Ox{e zpFHovnM-G}8`VFV7CNiTE2L7_c>=&MzfX<+l+c2 z*V`A z?~!cTNq~F*_y0kBmd<$R^FH(U^phXp7u*|=J(KGjd--Kds@^$qv(aRg&GW6*b&D_B z*3mw3;#-q?nxcPWx9P_C#zv=hb$0FEHs_jgHa*FWYi;>9IZ|HQ*4&wxKC`@XPN4u8 zGS$P->P$q+&sq9-@)DQ1DAu*R#TkT5c~j%k=BCA+?d@&uid_FmO}uXNnue-K#aO4u zS8O-yt(Hw=^JCF6p>SGEKQ3D2@dg7etsV0_^T4NM=)x+pI=P_nBD$;Ask%Yu^Pt)~ zkY=yP=gO+BT4VCNL6ZS^ub~DSG#*sLn~LuD5(aOkbDrEMOsH)T|YLe z7cIe-+5?3P=kCaF%x6MNq6N8tm{nUIX)+{5?o+||B6rI?Y=^MDhlRu1x`*EnWl8^vaXefW?b(*7~oTKXQ7Y+c|;p_ z?a-kzd?*gV4mz{0W*wgXhOC#dS=kvni4F%(-j>F6a6ul3K#x&FsI+lb#Qmm8@FAzp z0v7cVrGSy(414K2EV>a$WhKrNCtx>t-szOJv_J9U%9Z)~_+uA8`)o@K{>0y>ucW?} zJ`jJvpM9&Ip2ef}^sMvw>-lr}E0sb1T+6em<>@Oze)<5zPDvy7@oQ!dYl|3s zvB)~)84A_|n2;2U(2@y{YTAMUQw2XTGHvh?rg)XKS|S}Vt-QpN-?A89; z;*gQQ1pPrhX0ZA&n^{6%@2w0L;w6DT@C2wIj&bys_D3D0gpYz3@MKcKz|%^-o-~ zw6tqxz8=^IT1U<6_uqW~RU2EUS@luG54J7LS>=#kQ8HQ0=WvTo=eD0J zUfA2zz31}wo^OTBA>CN$^;^%n`R%*+fA`}>t&yEe3aTe=ThLjhET6n_DZBVD+y^YX zZa}*j;`=kTbE?U;(v_pDupxX&<+y1Ubys6>Q>6=hhBD9kmdF1*dG`|=dLG|%R_W}S z7LR0k%H<-B!Otqc4s{f;Mz|I5VbUbMLIp?D*U|8f2u7j};8-hJ7` zwYP_4qqWT8bG0o#^449K-uJgfErmN56;w^wI&W%~vU2sUL&3Zx*Ce@Z%Ll1u9;by| z)`k_He2PiH)QQwVWR^j1zitXs=mdb;m;P=ms~4*2>4A=Gm@k38h?%QSReOqnb`hAk@KZMmg2u zWEfLN3)Wt0HkaCLTHtf<-dg|Wo9l)5iYB#pC1;&A@1pJVx?85qIao2*S&|r2R3-iR#<{oF zPfRQxf6ZA_w@+zKw1tD?);3+fXKp;)yryE^y1BK3HwS8$x8;mQV#5maSV6EBHJ;r( zd1G^)xM|aGf4k{zlF_*CMuRMdx$uo8X_==-g-VJ7nu_4OjUk2+h7rXOCPY+@LWGbU ztA6yVM^XC8Z8y#=v5@YyWai!@duNuYJE3I5k%1)9CMkL3L#Uxa%VGf?wk+Ar`mXAV zx|RO-uQ_z_tXUTyQg=!T@;BoFg>S{gK$0GzyhI>kpkXY5>{v-ewZK16jcHTCDS)n| zB;WynO)P+bc6B47$cs8LvI}}C4Q5S>+FEgAs@HB<`WC{VwBVzA0`nn-bP4AoU$!dwyv?1hASSK`J-FGbeMbr*x zLu7|m%lH+2hkjSvGt+mRM~954(F6$fWSH1_eTYvMng#A35UnSOG7VgL5UC3lZ;X6n ziKIgLpo86jj0t7q*oG^{O*y}Yv6}OzjQcK|I<9nOr*h>oC1}n<@8ASRpnIzE5nK7^sT*fn{SFiidYUw)V$vF$hFYuU@Cm|ZKPFMq{tQ-HpYvOf-Vet>Fx^v~q&S~eIGx)pI z3xad~u1PidHK|{*>)5Ab#~uoeZ7ldxy6w|z5IkDJH&EDj5!9Qc$0p4rEi62FB}~>M zO(6s%D0#J-i(XOQyZu4s=jZB}{wkx*uIqerSI-X*&Y5%YhdnDFn|xK4)nngA=DOi_ zmivmB3%K0(Ub*P{1I8TvL4#mi(SzGx!&6fx9?Y_CT)Jj6Kysl(gPrfM@~;WoDxATP z1$if(DF8u0%3&=|Ytj&aBa3 zrj#^!8>4m6P0=VL>tQLwx2!Oo;C*&u4DU914F*z07F+ODQxM;WO;+*<_zb>v>a8f% zX>Q$nQd5e$#EH`df5GPl>4YdlELnfx6qsRjGkfN$uYffO@uTDugGDlyv7~11$aoDh zJKB$8xEz`6@{IhGr*B{;b@%Tz+F*5sZcWQ_ySwYwgKm47u#*3hdXevh^nF)Gm6<1~Q(7ndM|`@ink(0xv%Ft@C3*7R>O;~jUTzD4*9$G-x_L2mk5=ndCO$(~2n z&b_6valYGCV6^r;^3o$8T=loFfOHu6{HxI%c3<#1Y}JD&HR2U=lB`LTdmB?6^u57F zk@qm*xQGel<|;7?+92+9no{ps@+8E-NzW-8B)!w(lz%4q?QAMij6A@ufe(ZDbGLtB zca9+E+Qs5E%w+S6? zr?hI2V;A!v9v4e6fO32=qxMNDnSRM~kfArLY{Kw=)JQ zU_PUtJT_Vjz?h+SGc>DceyLZTgr2CDy5d@ z@^wqDfAT+{yncy@MsQgws`0kajM}Le&n_>Yeeu*avrT2DZ(e`>H?f<&=C-X>GqzXf z)<=WEXlg_YCw%)etfvpoJY<+;!|6Y!98{n}zT=mbD z9o*gq)&O%9-tE<1I|&+S8Qx{8)rL4j6*kRsqSs|Ho0T6UC1rxAr0hm|Nfq$&L@yOv z?p84_SvP8de@5JgB$n91%Ha~i8Bj`Y^MJk%NR`w_AR$~vOCmZ4I1`9NMqEe6N`?u; z?R}Jpkmgvp@btEK8Jfm^{^EX0df81$FIO0aj79#M^T{HAI}@9ytbj#+-@QUNa*=dX zsTEWUnKpY-trg}sxt)IBI}Q03*y+D_2zL4zZ3SefA5}&)oth#Ma5zK0$}m!5e0@n7 z=`(1BJB?X|{gN{FqVc*7xZi9B&~-1BmUX+7kIqm?6p_nOJg!%#Sq#0vkkw0VI~uNH z161lk-lQ+qBvc<{oG zy+^h$wbgdK=w96l?6R)b)$SMD3VM19+7d@LEXgaOSzeO2gb+H0&pLJ$8YdLgmbh$7 zw;$OH+w@P~eHUnJXba+dlIga9jx)o*0f0y6a07(86*gMF-c z24e5rO_#<^LF*9mH~uBsR(h13N8f$-=mGby4{`X8{37suPUSqV;XLfbNm0H4$0^OB zU%LiLb`Zm3WLUyW2i*!4}J4^UzY zxi6K(v>5!1CV^cftX7fzhn|)C_+= zEZ8Xxfg5MwZIB|VpKLj)1Z{_}!d!d+{wM=U8irbo)8gC?<;pxW8)rV@l)xvj-V+)T zv^;J3>>aj%p2X|<+pwXC^K_q`&ffNr=0}=WHGj~20uIUs52SL22;hdgeE5jCy#y^| z*uYVC=vd4;&c1%8FR;n8Z;es}G0Fx4VA+hbxRLu2XLq|gu%(|8u z{`t#~{3$_q6Tk}k|844p@AeHS7M*)cGlg^ z8SXyX^5gR1=|k9As9JvvOh+P(H=)|6TQsXiTByl4RhMDsT)g|zeTd#v9Y&flPBOg- zrkpR&DsRHKDtCt-Rqfa5t`$`Mo$?~=*H-;Ah!oO*1)IL%MR4of&7hywnV~~OjtBZO zHti&lfq?6IS0d1>T53$fc*#R1x+SjiOPKocodb2Ksu3xy2AJGV;JU zO>I8@QYI1{8pEGPmz0v+QlYglT|{NUOT{{v<#draSsm-*bq!>_t%KVTuGYbX0T1O; z#%g>rAU50Lx}bEhx$T#f6}kVzMu7ma2339s0o=#h}TW~=xCwu0G}5Ig{UDu%GjfNp9;V z{tG$jGxUe79odwKxGr@R(*Pz;Hp84j`k*LNMcwgZn((+Z5?-he_CZviQf<(lOm-9| zqV!=e{>QMj8mMMzd1<&@s!C_5NJE}j=^~+U>ckpdE~QT`8+`-cQcH!;k1UyxKv~pM zjebCA8d)#_eD+N7zoZ&)abrlL#q=LCOCmhMturv`bQgu~#%e$$Diw&ydjkj6Mx(Ne zUBwQb_VO`)1HTa)^_E@AF7>%nF7x)Xpj^MmluNZIa{nLXoZ$%`eJB^1Zbw}d=24l{ z&s~Kt@NcmV40HS(fV z^HsG@7n&NAy@7;xC`V(8T(T0l9?5J6oT zxTl%IyrFk~?Lly+-sbO|$t+ThNd1a(@>%fpI*^@vraobsnXDY|q&}g#r)SpJXne8! z49%(1Hy&eU<8f^uA)pbQzk=-{ZOeC)ABsxT5M|8)chak{PUEtC!C3@tg4^~}{h<&k zK?1Q*DAi9!W-V;gLP*5VNH;>aiZjVgFFL2yLPW>f(iK}iQNm4#YRkmhC9#B(?8p7} zAjV}#DVKXeU%gZ|T;ydX7LXSX%%EId3!?0^Dy+9=8pC7>I7qE*Exm0R>W#cE#>t1-EN(UN`YM-B_ilY*=Pcz$ElIIz#}$P?@nd(yDN3s|^=B z9gD)glWqYEwFVp^hH?7VaxGK8s!<-K!iq1CaAxGbF`|a+O?;}y{+Yfm@Fr+xBROL5 z!LM=bD9uTzQ8m;X0=9kB1ifr5bUd)XkWHp`#tIHG^(pE2)B1jKW+)UI@ zXbX)dWM%ez7DB>nZk!Ai0rL?SKJiB7*ObeaXS6*fW3SYkl^pknr+_FxcavVzDdvsq zZqn;ln?OQ6X*XyICSVLM$^Db%yIyZasMUgtia*CIcca2|bSHUvoMhgV-o2#WIl>nLX*yN&Q;w z&0HD1SMT7q39n$CjsyhLHwdkq<4#@8cT$R{B-k*0ux0sy<;xF9pQ^vU2nFnxUSZ#X zWt3fV*@0(}j{&(0l>fuIb3rwvr>>T!u6cwX4`Br=IMx5k4qxCrPsb6V%O=Fmp?=Fs8O2hSgK>y!tl+){e} z!NkhLm(RU#?&XJ9Ci+`rSKRR9Bg%_shH%@J!J18XZ@l5I8xO3%dt*)TO4idg zzoTRR$j!wU+~+ZwJojC&c>nZrtF?Ukex`r*;+b1oA_lE%Oxx-SyI=e0=-kCS*3OnuHNyF`ALE7q})_D3DyGsZ0NwU-l~cawJQcwdS1BU zcZqzTBuk;N1k?zp8gi#X#oC~E&P?qL_@TyLA%v`gJzoIjA4-i&{wL=}f3EyIs`m$S zD)l*6+;>Heer&a0G4gpWKupI!Hht{_A1Q+$J+KygCVlk4`=jtN*vl8*c;kh50bbL! zYE@Uj53jOU`Sj*5n4VJTF?u}x8j$Pd%F$P{=I!b0=H+mQSUTW_Odc0Bb^aT5)BCH( zrfXH16Y%S)u1dpyuWmItmG(@v^!myiR8=tiPwQrag@8~RVC6?OXpnLJ*VnI7G8RZd z#zTa1GN8o%do@vwg6#4CR^d561D%2$ZX>~%^k##5}(nBu2Q{H^D@9;Z^``%PwIet@2zRCJdd4?We$19cg@Oo2Oth@;< zhB9^^1N{MqivPG?glKUD{4=eUYlH>p8c)tV^{=+o(02^Ij*BJxyWKP%sg?Y9+tFs+wm`H@3-S$ z`V98uK`@MBw>>rVJHKuC_7SI<%Zf&Q8$h_!-!=5wE%g2`k~(N)z5tpYl5%0ow(vVX z&Dy52Pt;>2`%?NOy<_T6cK!mp(o41Y)J`$FgGu_M4~ev;?jyWW6ae(xi#&V_(N|3~f+U*MPu;9*9X4b#@aOavjJ4{{GpEUJ`TgWO&-F@zxQ$@{OGJAUL;#(ZU zyD(m1Ky#3H7(ydG-kNIsh(-cF_Wze=5fhKU`0}F2CJ$bNcgtxLIj@YDalLfV6V8eq>EH zNs{>craFW6xI@tWaH;;;687=`tRW#sk(|Qy2SpTLc8U_o>&8?}%c!blLg?gLlF>RD zsT?UQFeaQ<5d=&aLpqSrN+V-HDd)G)MjgZDC$H1Zll~69KoMoz;kitQV%xaR&Fcnm z6CtVtu%QiB(|q8+oTiwK1-#BdruA&;LDyOsthU;9U z@QKgxutV}$WRrT3>N$Po(y}Gy)x&=@M<~51@z$Lq?_swczn?unnGk4*MaPC5 z!6zx(D2iid)6IMKG@2buA7F>>nKIilFzP<#MDCA|QJ)AWzc_hJdxhMO=+R=-p&V^5 zI()K-9J4Nta~mZuPdIrp@K{k7Ic~Y+d?ww+m~#8X{G-jRt;NhfQ*K%)dwmX{GF};v zomXC{+!%6}vwywo&dc?@i`3vwq5VXyv4u?>Y%REtt(wT{ly52KaMb*_znP<9_D{Al z)S&BRKOHkh8P};J4uPFa!PjO#SR*eVt(@LLMGPT=_*V+wV)BKlq@!3idV{GxZ^YD-^xpi{Yz4x)A~VBpfkezXOg14SVj+f%OLb zFz0?zYb{lne7<%9xirCM7cloWb4^mJ4y-zc5M-hJW|NFHD15 ze}lj7zTtbsZY zE~p3>_ZrA+gvdWGV1LLh@?k-YyK z;0EdiQdmq4H^to3k+TVb!q8v=f_v60xE!2*wM-hyp^vgBPil-7vkAU?8tT4YHLp{D zR>ZI@s6au=BOcEu%n_U$1i+B;u`}XfUGq~nf1-Sn1|4EfTvHxS;|j4^9^u-o*QEZT zzM9>9Qe*NDeUKSWYWP?{z$%7BO;%8JKTk2$djVk!vDu!8Q~5Z^R0tyG`ox1zEfkhJ znKKPbqM(DFV5KL`ewoMB6y=b|QnbAoTgc(fIj>wG_msl*Pw1;LPUPH>bl<)f|MtC^`bW3YR;~TZADF{Y)33^yGSAXxX@~jS_p~09S|6 z+xoc7fepiDew^xyNo)H^5}^&1;T&uVPzKTm6DK|5BQC^#P?_RljF*HAYs0V4&t-8s zjk8=9CF^XIh5G5;w2`za4IPWLhzmQWxgH5H{b88^MDsqCV#u z#`Zk*lJH?l5vAH$XU(c@9#d0c^{x*@=dC~Q%Bty$XEcZ(+e_VPm6KMjo+f=omEL|OSk6wZ(Zu!bO&xKnkZ^Jk z@)lehvD!fA93{VXFR5Pm2*5H5a)f~=CRrB{^d8oJW;5jsCSy%0O>Dd!$0CkJ9485O zN2)8Fo;#>18&inAggpiq*06UtUO*2{Fwi)vID8Xy9zbD%#Rth74mhV|LY(E`skq{W zbq>M~A>0rO)m7DbC^8M>M4MbPdrW6}NA$c9^O_1T>8WU)9~l$b zG-v+#`O*A}XxEA(hN!^;#7&_fDjr$U6|KPa^A~h&!d>%Q6CYGEfXMnIW#!&+Rb8cX zm$E13&`%e~Z;8ubHH>xRq8;U(V`eW|I=8f|YMi&cEaDd=V2CnFGwRWFNygQIw2b%~ zrvWFE60Iq5vVUX#X>=6np-w}Z{&g`8(E+ZG*M!o?voaB@)?*P+p~3VBKe;?R-~V?lV`QMk0%qmP(v4TWV$ z>y?|2A84rWK4%lstl+{a_1SYCFt?3!kuHl^-?>KRqSOt?53IdMn7wA*X0-x!LcVfy z^1yLdcMZVh)N9#QwR9*(JQ<)@&>nA~8lF$%p7e7v$*5Y)WbWGlT7xiKK)+&vMWkTb z8Yd-`#IEIk?Q36k)sDS&c5|-TUblD0Rjb-nCl?`sOgGn!pZ1jaa7wfA{{0uv?F{Gu zn;Ynyd-4AJ7pjC1-ywYKD&~8OVtwS)pJXgF%p~J6wUDsE>t6EK~>eJJjG6$1}pNP6HjG%mq!h%$xdXtOa zF#{J@R1zlZNzLZ#)x~bls!;QmDXnhFQEa#P9A??oIAMKb4(t+ER$(=o}XwWUE_Jxm1??Lb>VDu5RTryRly~B*1^WS5xthr2k!gg2Eoxp0pAa)Dudxq zvZ1#++q@%wV=cn2UuHEf*IJU|nh+NMysK8Ye3ZT!w;|-c2KUwCM!JvREc|MeQhD_E z@oBKb1jRyGZ3(S^UA0;qO)}$woH-Q(ItkVcF;gI87g9njhXYYD0`FgIIn_z0^(^t@Qth zHv-yeM288xPSXbo9xvh`DV8;0WD$f<#3k3%MP1=I@-WF!X@h<6no41{_qk^+4|&-J ziLI+nU2IbtS4Zf3_JcW(PW8Y!#cMMEzlAewYOa*y+QTdFS*y*?b}MO^FFOBUnVyOga;t+I93*?=O~yFoF#y?VWEb^B*G^%0fnYnlva$jMFW z$xWZNueRy+Ue;}OO7HWfcd%FK_38z~+1K5B?{#MbY@7e+cG*`i-QyOn;N1GR3wKT? z56HgTAixp-G{0z#7SEf-2W@ZY5*?(AZ-kt=$`fjUfGZ zCbN|a?aRFBcqev_!j=A9<^SNYo$0jZD&a#F%J&>ZG|}_Ie6km))`HaDue4Ng9SW2u zNl}$`fXSFG3(^ug+N*!`IZHMc!%)aK6qk9rV=KtT1=UTMeb=Hq^?}vxu-y8Ni8(DviyOFyYrp>&<=tDY2BXvR z5?l7Vj{jgZv4U*0pclDKsPF?e)xz9((8)~i+-h;SEw{3QzkGkK%#aP2uIgS_?taPQ zG#bR0NBc--#;S>9n`CDO;iMdb0%hBQEFp}}9`OjdRTYGhN#5?Tosv-?b+dDtlORIJk zwqDo(f=oGCQb(|YA?uBJ_2ACv#^~P0ExnCumIECv5cSP|}?-ty*F)AL6;vt;uiEhM@8(vpcS)U|p*w)Ft2XftMvU_HnWXW;% zG#;y}N@1jjDj(Z?-B4qTPSq%Ug)bK=B`K*iH1yzpMmTX1rc@tCSp~9`(2t*0-d2HG zlGr!y?j`OUzUO{Svy%fD>}L5ASl)qb&fQ2*X#%4JS;qnZ`c58~%qyO77WYxml}E2P z_ZsXh(O2wrK&#+rkO3T!1F#sUWWgWb8T1dfrS+XD&6_Tbt zs~gPTaKDlL0djeU6&p&x6eu?KId?QUfMVWCH?7J4L=5JC)dQ|TAFm*I(9 za&wn;XO}d)opQ)G8ml0UZ=Dt>+G);>1ALrHv&e&7330If)Q4(A2;M`^pxF{1HSD`t zKQQ>m9&yyb8oK=y@_?2-)kSCnG7iFL+6AktZA#gd{bG2#NWkMOLdv(cR=e#E*# z4|;)kv+F1O&uI)B?={*09WIt_sJQQ%VzW6Q#6~pNqqrZGpqor7z47rYx-VMO^7tRj zNO8he?y9Zqg%w5U%Pyj-r|0xv0ORC@29j(j3}$NhoIw2J-i9O6b5ZaH1==VYF_h(2 zc#6{@Ed5C~JN3tt8c5{7uNr2QHq z5?@^=M{z1y>~Q+9N=$UIgm34W%f!ANiA0dMJQ!3G1lD} zmdSP6%<7REfV8`~hfJh0{N;3Nk_BAQLIWO4a}=m6J; z%3b4EP~T1z#C9sw%64{6|Jr5993z&BUW+8z+&RGl>)sct*_(EQQS{3}#gDWxFWSH% z_@M((_Kbb;5@%6Ct_NvnEEe;hkD5J{z6L3okdKGSzjIl(T3qACI<4ER&NrCGhwodC zl1Ub6nvjtuxdq4r+XB%Jv)Q)AWZQWaQqRbE0g^;v=<@a$M0<=U%A+#lBQ^P4XTyzu zkYsgQq_*PmS)h<4Z4eZFT9YFVqRBe|+-x~#1=V!Lzkl@f5r_!ukaNf=mvome=wVgV z6w0gYTTbg;P!e3HTu*l%!LYx?W!Z0a{^5b&@6qQNFEKH}AmpYbcFb-%@>T=qB~ zL|K_83T&J=ATzDR2~2H6EGKy`q6d)iWGwX=$C?K;T7@2^YZ%fs0X+!a$*TcxM{<7z zteRGQqjPrWN4sk4?9Irv)sV-}aw`mnYzTw>Qc-G^<+gC#m6dA@}m zfwFio;&Qrum9e%7i_?9!4}I2#HsB2aq$@8ad;s?y2N$e%AhgSAvka1fX83Yi*;Faf z>w~~3?sHo2^S$}qds&gysP{Z$Hz=?40qSGRfjhm*0_q!f$GBfyPemiX#%cXarQ-oe zgC%RN&O?v6A5m_#JDp~>`6Ywp5{ql$T&ER3Y;{>KqkD1KIu9}*>E|UK$_s8iOzLt9 zN2fAEOFU#aQdtgIyS+Y$uP)LJB07u$%G6<|;t25p=hg~KAH<;Or@;hZAin>l@*}<8 z==_Px_$yb`I7as)z2`>`qd~9y^jCb${hk%7dsKx@b6VF~Tnn7m9*awuXt&#)%A(jJ z|6&Kb+hw;pQa^NAdaTX`F3UP#c06Hm5idi+BMu5=6qoB^w%yL)3)u zkkZqM+r%W-K1il8XRytw7nBFt7t~IQ&SkkbW0vlxEB%O{556F-d*Naw!R}P{{`36N z&TF`E6Ux35aq*Z8q(VU1^gzh8!$Uhya~?*9E8>Dl7Z8|;a0}POBXj|Px#|T~Milvo z5hHvbi;F|09j1pOX9dwO(A80&WcFSic{8a)Nrxjrm~(VGaQk*dly^ex&Z{Gn+0j{d z&B2w;VdYna0{G*%?$-H_`gPxV{a)-%4x#ros_R4HYiW1x667Dmej$o&8wt!~rO36=(&v}vX5oHy;< zVbRsh+HuL;Tf0hbbxw7?P_Vfg$?}Yr8Jpisgm0Z&eCzCsdRkx4FPqY`xO%o;-xTYp znov=d@0yZR)KcA9IzcBl7fvi|jukn@L57`76)MyN7>b`;s&ZlD#VHl-j zB+0JtlS#VD($3U`B@O&zZ?Rfa_aT5ZGz1F~f;jkVt5xZ-dPBvH1O23EAe0A87qS;* z-dl`$GZmxK3!8x#VEZFpjnEy60nQfdM#GnnK9`T~Lu*aY~8?k1Ct7A=n9L)*S1^Z6S}|MbfLs+_L8JNf;) z-j{lQQ)!pntk67=p81c%cATyAmupO>UQ);mow_U#fc-LT=% zp$!{^BdHBUUPjitmg*fHt~WWclb$jyHfGhEB5kv4CVpu`A!M6K!wH^l5XaB$hd@MOne@J~kTz}he{YTgG z%~ngoY}(?Q~7SwhjG$#s=VHUVbG# z*W1YpI0_m?>9N6Go_Wki;jlvrnm8P!=+1@+76Nh-s3(StCIpn-$kIYiB$TH`p18QV zwym?HdUEPpXQ=eYfyS<#liDi$&bZAUjm=+U7d&&yHe7z_+}(HQE2Z}`B;$0p&F$O$ zhw&SxZJSZQ@N{)+qSWXb$;1ywm6#>KAqY& zG~b8n-oQPehwJ|3bZ%7jTwm54U!(4?W!LYSFKGxVUHO6Up04(TqpK;`oVGoOf=rBr;tR(Q zFcbo$NG~Bz1f$VlAl3^l4%9OUv=0ShQg4GztZ+DNaYIw$vZ5J|iMKDBxjPbw73KJQ zsyf2XfWe?M<+@#giq6Wg4PK)zCsL2g`F+Yl6YB*+vO>!E^f*9$7YljYW;329|xpY(4Z~IkAk-a z_kT%`<a&mRQ33CieiDt?wN~jpXiuTbXlUw5VtuT6{47FiPWD} zXf56z54A3ywax1GYoo<8WB&Y>;_3pA%iU5IFNwA|!;2Ez1RIddD5 zpvM!esmk*_-rmk3tlPCFyq*0!TTS?vJE{>C@<3rt%?Fc}CG6hGdzI^p%X959R;c{L zFW3s0fAis5Psx}f_R*ciC7ve?c~-BpI2LTav^f}yB* zw`4l64x^)v##4Q?F2V;4LfKF0Sm=c@+#rZm^UT0HZHNyML~#=J36U|(%W6b)I^y=? zHLlFqBSwX&k`Dm=r;bqZ#kkMw^~KrTv(6f9+Niv+el-g%S(1-r$!v+s>7Kh3WUb=SV7$E}o|_k+G!=r1km_ByP4h*e2z|Du1+f`E#9t#`?EY>&G@U1m{_5j75_ct(zUKsfo@$hFx7S zXb^w$#-vGaOinHOa7S~O*5lE3HE;Qtj&*Lg4#$!ehVj2M+q8r0<||)JerOJ!j&(iM zMK77FSQ^@*{u*{rxjrm-OW7Xi?70uov{HB-K0wOWeAIp#7Epm2OFQ*I9m#!Qc9L?LMM6-_~5IBd5eL>>xz!Dh2>nDYC2q;k`h4j$2TQn}&R8lLb0XJ$;z-}7dnRF zXk8b)N`vHOY>+(66W7&2?#I6dkHHL~`(x$1idQaEypXAVH?W0Jcq~fIVG9+f@;$kN z%~gEL{cI8Yi}F3iDYh!FDt}_*mG?F&zr~GMh&Oe!T=-rJ%6rnUl|L!3F{|;M8&)FtB&u3$(+9(5rL zeQ&B&e2fj;7-1KRy@S7oB`-C8uJAxSwczK%IWtp7+2icmi!c9O?WyJI)iX9N)3`t&5qhuVZ}bfXQ_d6Wmn(Hj-SQs6$OcCFe~E{c zSNerVQ!{%RQc0Z}$2?oURDJ>a2#Qo}*Q~>LywK8gdB6{ zI-KTa$Hr}Cxff1an$+uW5iSZw4Eo9{ov|>G8!_nea`pPipfj+hz0*CmQgrCug>{kc zXYGa?Z`2kxicj6E`15OX9eZQJE#|y2!CFK03%ehj8Ys`tx0x!O(M1(A+-)S}r)_$A zPSKkn>#rwD3i~Jc)cOV<8qUMsU1&kHuRxhP>%r-|YLO!ugvtih7XGJ(g;QfZh9nGX zTjz_oE|Co2JcZ%vnp;%LO5^jV=@%c^APNoTldpTi-5xKy?f$Y@yT?*dnE(76;iBqB zlWeAA}+2W*vheDP>uzU>Nwqjbx!6`)(hN^2y&w@AzMTBl|GqfC68WyRSv zTDY~e!s}k|MAnyy=b4waS1ooI%wHiR zR;+SO*dYA0&f5?kA2b)*++*`QuK9V9TdiA478xtCrU2s8@5c*YM(b=09mCHJ1@nGsier+8RNM_s5)r_@qsMz3X54#jO zO6V}k!D!L9+F&Rix#CG%+RB=XYIBT?!P#8TH8_uXh1Ae{ zJa!9PPH$(cERxGL5TZ9p{V_Yk%ax=ZuS6duGy}ktm-#!nb_N?L@j$xCl*xf8bQ&tb zs6q+-(4O=Ue`BSU*MPrMqZ!clrQb=qGO|VuX@Q^v0biu;qautdm9QU80m#PeDxiVz zPINK+wYQ=@V?2T|Ehdq46DbrCQlWCO#3yq}3co{E2Q!QV{0}+^!sc^(<*o7gmnN&0 zE}YOhXHLy6H{Gyx%Y#$b_Y{_|Tsvjg^4i+jkqHNtck}Yc*Vjke#p%-?W=K}ZChXbs zY$y~i#EJZm_YNP*&o3;TP?Tt|S-$n+=cS8Ur%xYW?=)#|+O%dj}Y2cf50B^IwAE*J?a7%H$n!K~LZYjM7mNR)%s_Yy>`N5E)J4qi2F%m5mt0SXM zor8iF$!i_X0rdssLj)>@K}s`2eHL0O_PdbJ7xJ>>A+I;&8yqNUXePj6Y+ zagV{+%!dJw&b6`L}!0ew}}ejR(4avb31oF*RbEB)0z*IlpHW?b(YjknWsvdo3V~E zB_*HGGT6F+6Ap(^H!EUQYzq4X0~(Bn7Q><1r;X`QDHbETqXP#FrGwZ49PHY78<5*U zyCFn_R@09-Qdhbd$T*$Q!iitJa15%$0*IWB5o8mJD``SvG&-#UCyDqBU1_L?Ng9u-|Fl@2J@r^%K(Fvh zd`&GVw~N-(5>(R$KAy_s@%pNDT8NZXBLEGcO7(H%#-u9afA@HX6X*e~5JT`uFR{>Y zn9CQaFjQ(<;fXf`k>quU4IS^NCcv$TGUNrs+ww)2H}FO(BWbhftyB|~y$$E6bpy_+ zX!Udx|32=;qRHQk*P?}}QPVF@w{yNM+-x!+(XYHrvKbKai%;b4nbs!f?=Q5d^K)q_c>*v+KQ{60gYe^DIu^Y-DlP>OCO|iN<89s6sB5-1iym zVnM#X#99%TELtYIjTIMMR^~IA1$IuHmQqk!)UO2X++$4eUIrDYM5*l-#XEjSgZC89k-G-uZlYm!MxT;}^4XlRA7!1}I zI)hGwRq)1~cDKvecvf+9YiHe9Q#=$7i&kc}1?)j-4RbLqs={od$)Z)}GCg3g^hSZ% zjmQXw?iQ3=oqk(R(4J>3)RoF(&vU!S-?gJykjgKrh_@8Lzo2byev#KRp-?X(!((+V z6DQ`l5Obc8^NT$OQNPz_5GCC>sHw&k*vbk7(PUtGE^j_7DUxhfvyWK=vfgKdQ;CC_ z4Gx1o1Lsn5+Ry!f?_|MvDg$BRfn@5?$*VcEqudChi{8_t8JuEL+au=n9WyJQ>hX-0cA?0Vv5w^Ii`i6tMV^PVu?t+UC z_Jvr5_|6+YT{LF%je~#3f-cN{`tupH_ivwc(Ucb3d*WecaJNt2GbzUfQ)gIyT1EoU{ZaHM=AW^5oXRwjO)y;E7AHeyucdjWZ{ME*T3>ghR@-?jcpVW z4%#ik>kNU!upGeGg5pOZSRdDV7aoP@*b`%$t1uDmFd9b@9xw$X!Fvvp}p)LP`Vx{KpAq4M%jOZl?>(aAdx9euaUzWIktzOHj-&p!1;8K4uifv71v zxkq{zEKdX;X&q<iHx{LsP1vHhsl2%Uo}rJUj=3MGkJPp&f=ZD$f-9aT6N&ma|WE9lS}3`i%E zWc!h^?UOXb>krbFT`MH%gxg3(>+nr6DiiV5P;|-tzzYOA47cpS1<2!~fyF(}ha?OP zCRZK2gor~V;Q(44@bQ^A8UT9~*W~@F{NDyd5KXM;t(XY=i{anpf6A*VZUm5O=Q@^L z*9nX#rF;K>?BD+%489hnY{3C#jm-%F>`yBuPOJbxXuxS>w;fO(C~Yjx^Rwi}jY`rl zcGCm<)v^MgqaRsv$m2H6=t9H98Q#%*m|9_C%aji}M!Fgk6PHcoe>es}CqOTieqI_e zL8(lDuirhmg_q%m{?>(KDqv)h7LOt@AF{W-)4B@+;8u!@a|>CZpnID4+SAa8 zIAn{r5x{RF^mvV$_zVOAd10dzbdcbSG(o&&&|Bglk$({OX25Tg|;TTMr2LPDIhXlMtOEup548^h_lH& zdpLXsaRSVokLw$sP=5Yc&(BUGL~Gw6ESRz7%4PkxQ>xbO&oSpW%N)+|!lj2#+<5+Z zV+yRgzo0htPxRf>qI~aH`v4%g`!Md!?(N@XzL)lBg)w6aX1%)o#uJBYoCVfm z%xP6etlEi7sWZ=W=&_a)%K)2*AEzC$IqMksX+b5TtF^8 zCeAnp+)~%E{(v$$mHYuS{y;!#;|F%V4*!0a>p9szCWJiKgUMh#Zn3@!$JaXdpSJZP zG?B&B2i4aozY#Q-{on_f;3rR>9Ms(?b!slh2_y$qj`P(N2;c?;2zs(MhSd=oOv&el zBLy;^Lg_TF<%rZL)90}qXzEKUKL|+0(0)N8o&hHvG!7m#9E*o@Jk~6Y>%8{*S`*Vzu zO+DXe(Tb9-ggMP#S+?ulwKjWReQ9y7MbJ78Mp>}xv^gynr^8eCA9L&6LGbtB>9r24 z-dR}E7Hz3SJPw2jw~>Y7)mriM#QUMT)dgdUJ*_Cj{=LCh6WaZLWAU}UO#2PHSJt|~Z%U%cQ@t@auVrynuFUjBO+B5(6D{UKgWz?U z0s=G3j)HJg?UIIr&|kU0wqnGf}-tM60fc zLFj^rFb=Z64&rfe53-SSQXKQZvz^!aF)mG?3lAdk0gb8I!C@W|MBua zZr(Vjvhwu}n^!{U)4{)6&ctD%>%!+&5=7MphH$4W|hU-{=-`>syj&z4M^P%de$ zHm&yRUsjZt3$oQ{9=EJx$NU_ZzSM_;xfhT3mq>EJ-@+Cws)-w_>jV1SqPDgN7v+vM z7v%2#$6(=Pn>7$FoD>S)W(mpwGAppkrsZq9iwd7!arUxc-s3IZH%_+tK02)KuI;#P ze@|Qct|vEbXHxS1%cmu-x0*2wgyz=q+bvcA&^epd3oDlIZp7D7hVk7NeBD1rw#@EM zZ4U;V)xo)sbxf*rY6}`GwE=)z4D%P;pdoR=|5rod{c#BKVBH-E{-*@TMaXsxV(CB> zq;&2B&prFV!Dk91&nUO0UV0qv-%{PTb1CTa?Yw>G5-(P zq+g~=ln;KjiX9zff6o71Tl*U?XtfuqamLgf}h8+_! zlC`pa@rp}3gm~+$1@mV#I~=}ht$%vgt{vC1?|1EJ4T;wL9Ha3)JoTb+7K z*|fd$D&3J;Gs^b&GEop6d5zPyPtJ9?#x#!~UuCmj)Twn(nzm)@H#%}UyUtoXZ*o2S z2bKnOzVUTU1%hwZC39QzotQu34Oi-X%@r}B3OYd#e2f1Idnb8lyLsFa=dz#`Bt{l0 zIS2hk;U1$@ z=9>2Q`MY*y@tQf{maua2xEoOXk&0MI2F!bgpeZStP70bySg9rjz5mMssDx`zlNhVx}YahO#7#<^d#4EZ}yi;amYUh-ua{OPE5mK`&9DipuUmut@kU+&S= zg9`XKO9n2@*?@Hbs6Y@)S=7g=k%*B_-Vul&gsK{r23OdF$OMEGh$q)JDX;zDcIE%l z_TGU}Rq6ZqoO|!|$@H3OnM_SDlgXrKQbEgJ$m(ai8JT)aaqXnp^?q^(KSxXc5Yl}_x?VZ*!3{)y@L`f!wYB)e z?H~l&@_y>lIC2ra@3FE#9n%ZFN#{UX~*}%i@$PSy=w^ z?4=FGw}rF@m8q^kr^INX^Z87fm06?Gx2~Ff`T3qYcI)W88Y64SjE*jl=C%|~7;Z|- zwT`Tr1v{NTCW9ok$03#Z7#I?r`iy8w?#|ueX{jocskLVZ2s{FPh%&xwRlg?=V>BER z)E7Z@X(PiWRXRakq53lr>4Vpk$ZaRo0~*;O6`KZDbj37fFSKtn7k`pJ{`(%a{x7UV zAy2V1tU zQeJuoq+8e^-4~7C{zZM^O#dsIJLwaO%iK!BXK z#o{+Dyo<_GO1PtXbOUTkLb?@5$%i4rJyd zmo~6M6Yw2Dn~}M z56(H5YOZLHX5Sb|?f?+0ST>qgj@)80SB$R6zH!cBYhNEJp2NSy{4}z1il_VzQ)>B` z;+)&&9=2NO%B>N3TP02!A*IE#k@WPDLsm=0=;EB7IX$#WH2dbLWJGz+P)#xaT#1Z7 zJ%^N2>ViRYF~!hBW2bL{P8(>n0_+OB(sY=ScuNtwhd~Gb`cX3j1|k?rX?u_qR*9qj zDl!<1!h-T4{rSk$+S;kPzt2-;DoR3ZEL0NB=<5xYRQmHC4zdol!(cTTO;!WeSfcb+ zpO0BNbCMkO8qFJhLx!ZSNs|R+d<%>o%#4h(l8}FdEp2HkV}Qk6Ar>p}V_@#LjG)hj zkJ=v_Ax3L%6paKQ;}Wn4V8RYC0%IjBIFSOHqc!C4^~NwV7hd{vm{2? zAC*`MzAYm)z}6{BgV9n8ze*a6nOc3ZD9u-l?Eta}NU&|*R7Vy)_aCuLtdZHd7XGu` zOoQ5Bcy-t&l}>`}8f~lZDU!P$zSq`Ik zu)@)q0?&LID`q@SqJWo5r8lUFjDL)mu|NSNOM9M}+dVR>vKs6fm&zxecOtPyBF;|Z z+V6k%P5#hK=JvbhWimzQUARTKnNyEm_A#lv;2!Y)sqHQ<#HQ#edjrvl13ubad{L8x zGZ{IHju`y#$wfE|SH*wz5r5^|eDM`4it>yXt0QdWEJ9jT;Xqc3=79 z;naHrC$Bp2iA&rDR^hcvI~tt#de-;1VUdsvN(B#mK4k_ldHb6%*c6bX8lLU5{{?AH z7|Mj?!h$%<_OiY44997OBO^{kM1)21U%4aW6n2zLu<{dDBqBZzu?GwtKZ_FRJm>x= z=|X$42mAYNr560Xph0*b!@uZSAL`nhL` z^O+t_#U++!l}M_~${2-Q)2opyn6k1O;bSgj$I|YVu%U$k4#+>t@SxWk_B~ z_#Qm}0^k{tv6W(Dh#>%HhXG8Z)HeckO%Jz7l&%)2F&45DQmV2tVksg1=LfpV3bX2~ zcRrozzov6_UU8(P%n|brSL|l$5|v6N^Xw4vJPGa4Xcm2eJFEQk+E>S_)xl|Hm*{?? z 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 literal 0 HcmV?d00001 diff --git a/static/dist/fonts/fontawesome-webfont.woff b/static/dist/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000000000000000000000000000000000000..8b280b98fa2fa261aa4b0f8fd061f772073ef83e GIT binary patch literal 71508 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 literal 0 HcmV?d00001 diff --git a/static/dist/scripts/app.js b/static/dist/scripts/app.js new file mode 100644 index 0000000..e69de29 diff --git a/static/dist/scripts/documents_edit.js b/static/dist/scripts/documents_edit.js new file mode 100644 index 0000000..eca4572 --- /dev/null +++ b/static/dist/scripts/documents_edit.js @@ -0,0 +1,95 @@ + +$(function(){ + var urls = { + save_document: '/api/document/', + update_document: '/api/document/{pk}/' + }; + var _dom = { + document_table: $('.document-table'), + progress_bar: $("#progress .bar"), + }; + var csrf_token = $.cookie('csrftoken'); + + /* inplace edit */ + _dom.document_table.on('click', "[data-model-field]", function() { + var input_field = $(this).siblings("input"); + if($(this).siblings("input").length) { + input_field.val($(this).text()).css('display', 'inline-block'); + } else { + $(this).after(''); + input_field = $(this).siblings("input"); + } + input_field.css('width', $(this).width() + 30); + $(this).hide(); + $("[data-editable-field]").focus(); + }); + + /* save on blur and */ + _dom.document_table.on('blur keyup', 'input[type=text]', function(e) { + if(e.type == 'keyup' && e.keyCode != 13) { + return; + } + /* anything changed ? */ + if( $(this).siblings("[data-model-field]").text() !== $(this).val() ) { + /* update text */ + $(this).siblings("[data-model-field]").text($(this).val()); + + var document_pk = $(this).siblings("[data-model-field]").attr('data-pk'); + var model_field = $(this).siblings("[data-model-field]").attr('data-model-field'); + var field_value = $(this).val(); + + var data = {}; + data[model_field] = field_value; + + $.ajax({ + url: urls.update_document.replace('{pk}', document_pk), + method: 'PATCH', + dataType: 'json', + data: data, + headers: { + 'X-CSRFToken': csrf_token + }, + success: function(response, newValue) { + console.log('Field '+model_field+' updated with value "'+field_value+'".'); + } + }); + } + /* Back to original view */ + $("[data-model-field]").show(); + $(this).hide(); + }); + + /* Document file upload */ + $('.upload-document').fileupload({ + dataType: 'json', // TODO: why no JSON? + url: urls.save_document, + done: function(e, data) { + _dom.progress_bar.fadeOut('slow'); + var result = data.result; + /* insert document row */ + + var filename = result.filename.slice(0, 40); + console.log(result); + + $('.document-table').prepend(''+ result.name +' '+ filename +''+ result.updated +''); + }, + fail: function(e, data) { + console.log("Failed uploading file: ",e, data); + }, + headers: { + 'X-CSRFToken': csrf_token, + 'cache-control': 'no-cache' + }, + send: function(e, data) { + _dom.progress_bar.css('width', '0%'); + _dom.progress_bar.show(); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + _dom.progress_bar.css( + 'width', + progress + '%' + ); + } + }); +}); diff --git a/static/dist/scripts/fd-slider.js b/static/dist/scripts/fd-slider.js new file mode 100644 index 0000000..940ee49 --- /dev/null +++ b/static/dist/scripts/fd-slider.js @@ -0,0 +1,1341 @@ +/*! Unobtrusive Slider Control / HTML5 Input Range polyfill - MIT/GPL2 @freqdec */ +/*jshint sub:true, evil:true, boss:true */ +var fdSlider = (function() { + var sliders = {}, + uniqueid = 0, + mouseWheelEnabled = true, + fullARIA = true, + describedBy = "fd-slider-describedby", + varSetRules = { + onfocus:true, + onvalue:true + }, + noRangeBar = false, + html5Animation = "jump", + useDOMAttrModEvt = false, + isOpera = Object.prototype.toString.call(window.opera) === "[object Opera]", + fpRegExp = /^([\-]{0,1}[0-9]+(\.[0-9]+){0,1})$/, + stepRegExp = /^([0-9]+(\.[0-9]+){0,1})$/; + + var parseJSON = function(str) { + if(typeof str !== "string" || str === "") { + return {}; + } + try { + // Does a JSON (native or not) Object exist + if(typeof JSON === "object" && typeof(JSON.parse) === "function") { + return JSON.parse(str); + // Genious code taken from: http://kentbrewster.com/badges/ + } else if(/mousewheelenabled|fullaria|describedby|norangebar|html5animation|varsetrules/.test(str.toLowerCase())) { + var f = Function(['var document,top,self,window,parent,Number,Date,Object,Function,', + 'Array,String,Math,RegExp,Image,ActiveXObject;', + 'return (' , str.replace(/<\!--.+-->/gim,'').replace(/\bfunction\b/g,'function-') , ');'].join('')); + return f(); + } + } catch (e) { } + + return {"err":"Could not parse the JSON object"}; + }; + + var affectJSON = function(json) { + if(typeof json !== "object") { + return; + } + for(var key in json) { + value = json[key]; + switch(key.toLowerCase()) { + case "mousewheelenabled": + mouseWheelEnabled = !!value; + break; + case "fullaria": + fullARIA = !!value; + break; + case "describedby": + describedBy = String(value); + break; + case "norangebar": + noRangeBar = !!value; + break; + case "html5animation": + html5Animation = String(value).search(/^(jump|tween|timed)$/i) != -1 ? String(value).toLowerCase() : "jump"; + break; + case "watchattributes": + useDOMAttrModEvt = !!value; + break; + case "varsetrules": + if("onfocus" in value) { + varSetRules.onfocus = !!value.onfocus; + } + if("onvalue" in value) { + varSetRules.onvalue = !!value.onvalue; + } + break; + } + } + }; + var addEvent = function(obj, type, fn) { + if(obj.addEventListener) { + obj.addEventListener(type, fn, true); + } else if(obj.attachEvent) { + obj.attachEvent("on"+type, fn); + } + }; + var removeEvent = function(obj, type, fn) { + try { + if(obj.removeEventListener) { + obj.removeEventListener(type, fn, true); + } else if(obj.detachEvent) { + obj.detachEvent("on"+type, fn); + } + } catch(err) {} + }; + var stopEvent = function(e) { + e = e || window.event; + if(e.stopPropagation) { + e.stopPropagation(); + e.preventDefault(); + } + + /*@cc_on@*/ + /*@if(@_win32) + e.cancelBubble = true; + e.returnValue = false; + /*@end@*/ + + return false; + }; + var preventDefault = function(e) { + e = e || window.event; + if(e.preventDefault) { + e.preventDefault(); + return; + } + e.returnValue = false; + }; + // Add/Remove classname utility functions + var addClass = function(e,c) { + if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) { + return; + } + e.className += ( e.className ? " " : "" ) + c; + }; + var removeClass = function(e,c) { + e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + }; + // Returns an Object of key value pairs indicating which sliders have values + // that have been "set" by the user. Normally used within form validation code + var getValueSet = function() { + var obj = {}; + for(var id in sliders) { + obj[id] = sliders[id].getValueSet(); + } + return obj; + }; + // Sets the valueSet variable for a specific slider + var setValueSet = function(sliderId, tf) { + sliders[sliderId].setValueSet(!!tf); + }; + // Does the slider exist in memory + var sliderExists = function(slider) { + return !!(slider in sliders && sliders.hasOwnProperty(slider)); + }; + // Javascript instantiation of a slider (input type="text|range" or select list) + var createSlider = function(options) { + if(!options || !options.inp || !options.inp.tagName || options.inp.tagName.search(/^input|select/i) == -1) { return false; } + + options.html5Shim = false; + + if(options.inp.tagName.toLowerCase() == "select") { + if(options.inp.options.length < 2) { + return false; + } + options.min = 0; + options.max = options.inp.options.length - 1; + options.step = 1; + options.precision = 0; + options.scale = false; + options.forceValue = true; + } else { + if(String(options.inp.type).search(/^(text|range)$/i) == -1) { + return false; + } + options.min = options.min && String(options.min).search(fpRegExp) != -1 ? +options.min : 0; + options.max = options.max && String(options.max).search(fpRegExp) != -1 ? +options.max : 100; + options.step = options.step && String(options.step).search(stepRegExp) != -1 ? options.step : 1; + options.precision = options.precision && String(options.precision).search(/^[0-9]+$/) != -1 ? options.precision : (String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0); + options.scale = options.scale || false; + options.forceValue = ("forceValue" in options) ? !!options.forceValue : false; + options.userSnap = ("userSnap" in options) ? !!options.userSnap : false; + } + options.ariaFormat = ("ariaFormat" in options) && typeof options.ariaFormat == "function" ? options.ariaFormat : false; + options.maxStep = options.maxStep && String(options.maxStep).search(stepRegExp) != -1 ? +options.maxStep : +options.step * 2; + options.classNames = options.classNames || ""; + options.callbacks = options.callbacks || false; + + destroySingleSlider(options.inp.id); + sliders[options.inp.id] = new fdRange(options); + return true; + }; + var getAttribute = function(elem, att) { + return elem.getAttribute(att) || ""; + }; + // HTML5 input type="range" shim - called onload or onDomReady + var init = function() { + var inputs = document.getElementsByTagName("input"), + options, + defs; + + for(var i = 0, inp; inp = inputs[i]; i++) { + + if(inp.tagName.toLowerCase() == "input" && + (getAttribute(inp,"type") && getAttribute(inp,"type").toLowerCase() == "range") && + (getAttribute(inp, "min") && getAttribute(inp, "min").search(fpRegExp) != -1 || + getAttribute(inp, "max") && getAttribute(inp, "max").search(fpRegExp) != -1 || + getAttribute(inp, "step") && getAttribute(inp, "step").search(/^(any|([0-9]+(\.[0-9]+){0,1}))$/i) != -1 + )) { + + // Skip elements that have already been created are are resident in the DOM + if(inp.id && document.getElementById("fd-slider-"+inp.id)) { + continue; + // Destroy elements that have already been created but not resident in the DOM + } else if(inp.id && !document.getElementById("fd-slider-"+inp.id)) { + destroySingleSlider(inp.id); + } + + // Create an id for the form element if necessary + if(!inp.id) { + inp.id = "fd-slider-form-elem-" + uniqueid++; + } + + // Basic option Object + options = { + inp: inp, + callbacks: [], + animation: html5Animation, + vertical: getAttribute(inp, "data-fd-slider-vertical") ? true : (inp.offsetHeight > inp.offsetWidth), + classNames: getAttribute(inp, "data-fd-slider-vertical"), + html5Shim: true + }; + + if(options.vertical && !getAttribute(inp, "data-fd-slider-vertical")) { + options.inpHeight = inp.offsetHeight; + } + + defs = getInputAttributes(inp); + + options.min = defs.min; + options.max = defs.max; + options.step = defs.step; + options.precision = String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0; + options.maxStep = options.step * 2; + + destroySingleSlider(options.inp.id); + sliders[options.inp.id] = new fdRange(options); + } + } + + return true; + }; + var getInputAttributes = function(inp) { + return { + "min":+(getAttribute(inp, "min") || 0), + "max":+(getAttribute(inp, "max") || 100), + "step":+(getAttribute(inp, "step").search(stepRegExp) != -1 ? inp.getAttribute("step") : 1) + }; + }; + var destroySingleSlider = function(id) { + if(id in sliders && sliders.hasOwnProperty(id)) { + sliders[id].destroy(); + delete sliders[id]; + return true; + } + return false; + }; + var destroyAllsliders = function(e) { + for(var slider in sliders) { + if(sliders.hasOwnProperty(slider)) { + sliders[slider].destroy(); + } + } + sliders = []; + }; + var unload = function(e) { + destroyAllsliders(); + sliders = null; + }; + var resize = function(e) { + for(var slider in sliders) { + if(sliders.hasOwnProperty(slider)) { + sliders[slider].onResize(); + } + } + }; + var rescanAttributes = function() { + for(var slider in sliders) { + if(sliders.hasOwnProperty(slider)) { + sliders[slider].rescan(); + } + } + }; + var onDomReady = function() { + removeOnLoadEvent(); + init(); + }; + var removeOnLoadEvent = function() { + removeEvent(window, "load", init); + }; + function fdRange(options) { + var inp = options.inp, + disabled = false, + tagName = inp.tagName.toLowerCase(), + min = +options.min, + max = +options.max, + rMin = +options.min, + rMax = +options.max, + range = Math.abs(max - min), + step = tagName == "select" ? 1 : +options.step, + maxStep = options.maxStep ? +options.maxStep : step * 2, + precision = options.precision || 0, + steps = Math.ceil(range / step), + scale = options.scale || false, + hideInput = !!options.hideInput, + animation = options.animation || "", + vertical = !!options.vertical, + callbacks = options.callbacks || {}, + classNames = options.classNames || "", + html5Shim = !!options.html5Shim, + defaultVal = max < min ? min : min + ((max - min) / 2), + resetDef = tagName == "select" ? inp.selectedIndex : inp.defaultValue || defaultVal, + forceValue = html5Shim || !!options.forceValue, + inpHeight = html5Shim && vertical && ("inpHeight" in options) ? options.inpHeight : false, + ariaFormat = !html5Shim && options.ariaFormat ? options.ariaFormat : false, + userSnap = !html5Shim && (tagName != "select") && ("userSnap" in options) ? !!options.userSnap : false, + userInput = false, + timer = null, + kbEnabled = true, + initialVal = tagName == "select" ? inp.selectedIndex : inp.value, + sliderH = 0, + sliderW = 0, + tweenX = 0, + tweenB = 0, + tweenC = 0, + tweenD = 0, + frame = 0, + x = 0, + y = 0, + rMaxPx = 0, + rMinPx = 0, + handlePos = 0, + destPos = 0, + mousePos = 0, + stepPx = 0, + userSet = false, + touchEvents = false, + outerWrapper, + innerWrapper, + ieBlur, + handle, + rangeBar, + bar; + + // For the reset event to work we have to set a defaultValue + if(tagName == "input" && forceValue && !inp.defaultValue) { + inp.defaultValue = getWorkingValueFromInput(); + } + + // Make sure we have a negative step if the max < min + if(max < min) { + step = -Math.abs(step); + maxStep = -Math.abs(maxStep); + } + + // Add the 100% scale mark if needs be. This is hacky. + if(scale) { + scale[100] = max; + } + + // Set the "userSet" variable programmatically for this slider + function valueSet(tf) { + tf = !!tf; + if(tf != userSet) { + userSet = tf; + valueToPixels(getWorkingValueFromInput()); + } + } + + function rescanAttrs() { + if(!useDOMAttrModEvt || tagName == "select") { + return; + } + + var defs = getInputAttributes(inp); + + if(defs.min == min && defs.max == max && defs.step == step) { + return; + } + + min = +defs.min; + max = +defs.max; + rMin = min; + rMax = max; + step = +defs.step; + range = Math.abs(max - min); + maxStep = step * 2; + steps = Math.ceil(range / step); + userSet = false; + setSliderRange(min, max); + } + + function disableSlider(noCallback) { + if(disabled && !noCallback) { + return; + } + + try { + setTabIndex(handle, -1); + removeEvent(handle, "focus", onFocus); + removeEvent(handle, "blur", onBlur); + + if(!isOpera) { + removeEvent(handle, "keydown", onKeyDown); + removeEvent(handle, "keypress", onKeyPress); + } else { + removeEvent(handle, "keypress", onKeyDown); + } + + removeEvent(outerWrapper, "mouseover", onMouseOver); + removeEvent(outerWrapper, "mouseout", onMouseOut); + removeEvent(outerWrapper, "mousedown", onMouseDown); + removeEvent(outerWrapper, "touchstart", onMouseDown); + + if(mouseWheelEnabled) { + if (window.addEventListener && !window.devicePixelRatio) window.removeEventListener('DOMMouseScroll', trackMouseWheel, false); + else { + removeEvent(document, "mousewheel", trackMouseWheel); + removeEvent(window, "mousewheel", trackMouseWheel); + } + } + } catch(err) {} + + removeClass(innerWrapper, "fd-slider-focused"); + removeClass(innerWrapper, "fd-slider-active"); + + addClass(innerWrapper, "fd-slider-disabled"); + outerWrapper.setAttribute("aria-disabled", true); + inp.disabled = disabled = true; + clearTimeout(timer); + + if(!noCallback) { + callback("disable"); + } + } + + function enableSlider(noCallback) { + if(!disabled && !noCallback) { + return; + } + + setTabIndex(handle, 0); + addEvent(handle, "focus", onFocus); + addEvent(handle, "blur", onBlur); + + if(!isOpera) { + addEvent(handle, "keydown", onKeyDown); + addEvent(handle, "keypress", onKeyPress); + } else { + addEvent(handle, "keypress", onKeyDown); + } + + addEvent(outerWrapper, "touchstart", onMouseDown); + addEvent(outerWrapper, "mousedown", onMouseDown); + addEvent(outerWrapper, "mouseover", onMouseOver); + addEvent(outerWrapper, "mouseout", onMouseOut); + + removeClass(innerWrapper, "fd-slider-disabled"); + outerWrapper.setAttribute("aria-disabled", false); + inp.disabled = disabled = touchEvents = false; + + if(!noCallback) { + callback("enable"); + } + } + + // Destroys a slider + function destroySlider() { + clearTimeout(timer); + ieBlur = bar = handle = outerWrapper = innerWrapper = timer = null; + callback("destroy"); + callbacks = null; + } + + // Calculates the pixel increment etc + function redraw() { + locate(); + // Internet Explorer requires the try catch as hidden + // elements throw errors + try { + var sW = outerWrapper.offsetWidth, + sH = outerWrapper.offsetHeight, + hW = handle.offsetWidth, + hH = handle.offsetHeight, + bH = bar.offsetHeight, + bW = bar.offsetWidth, + mPx = vertical ? sH - hH : sW - hW; + + stepPx = mPx / steps; + rMinPx = Math.max(scale ? percentToPixels(valueToPercent(rMin)) : Math.abs((rMin - min) / step) * stepPx, 0); + rMaxPx = Math.min(scale ? percentToPixels(valueToPercent(rMax)) : Math.abs((rMax - min) / step) * stepPx, Math.floor(vertical ? sH - hH : sW - hW)); + + sliderW = sW; + sliderH = sH; + + valueToPixels(forceValue ? getWorkingValueFromInput() : (tagName == "select" ? inp.selectedIndex : parseFloat(inp.value)), false); + + } catch(err) {} + callback("redraw"); + } + + // Calls a callback function + function callback(type) { + if(!html5Shim) { + if(callbacks.hasOwnProperty(type)) { + var cbObj = {"userSet":userSet, "disabled":disabled, "elem":inp, "value":tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value}; + + // Call all functions in sequence + for(var i = 0, func; func = callbacks[type][i]; i++) { + func.call(inp, cbObj); + } + } + } else if(type.match(/^(blur|focus|change)$/i)) { + var e; + if(typeof(document.createEvent) != 'undefined') { + e = document.createEvent('HTMLEvents'); + e.initEvent(type, true, true); + inp.dispatchEvent(e); + } else if(typeof(document.createEventObject) != 'undefined') { + try { + e = document.createEventObject(); + inp.fireEvent('on' + type.toLowerCase(), e); + } catch(err){ } + } + } + } + + // FOCUS & BLUR events + function onFocus(e) { + addClass(innerWrapper, 'fd-slider-focused'); + + // Is the value said to have been set by the user onfocus + if(varSetRules.onfocus) { + userSet = true; + valueToPixels(getWorkingValueFromInput()); + } + + // If mousewheel events required then add them + if(mouseWheelEnabled) { + addEvent(window, 'DOMMouseScroll', trackMouseWheel); + addEvent(document, 'mousewheel', trackMouseWheel); + if(!isOpera) { + addEvent(window, 'mousewheel', trackMouseWheel); + } + } + + callback("focus"); + return true; + } + + function onBlur(e) { + removeClass(innerWrapper, 'fd-slider-focused'); + + // Remove mousewheel events if necessary + if(mouseWheelEnabled) { + removeEvent(document, 'mousewheel', trackMouseWheel); + removeEvent(window, 'DOMMouseScroll', trackMouseWheel); + if(!isOpera) { + removeEvent(window, 'mousewheel', trackMouseWheel); + } + } + + kbEnabled = true; + callback("blur"); + } + + // MOUSEWHEEL events + function trackMouseWheel(e) { + if(!kbEnabled) { + return; + } + + e = e || window.event; + var delta = 0, + value; + + if (e.wheelDelta) { + delta = e.wheelDelta/120; + // Older versions of Opera require a small hack to inverse the delta + if (isOpera && window.opera.version() < 9.2) { + delta = -delta; + } + } else if(e.detail) { + delta = -e.detail/3; + } + + if(vertical) { + delta = -delta; + } + + if(delta) { + value = getWorkingValueFromInput(); + value += (delta < 0) ? -step : step; + userSet = true; + valueToPixels(getValidValue(value)); + } + + preventDefault(e); + } + + // KEYBOARD events + function onKeyPress(e) { + e = e || window.event; + // Let all non-hijacked keyboard events pass + if((e.keyCode >= 33 && e.keyCode <= 40) || !kbEnabled || e.keyCode == 45 || e.keyCode == 46) { + return stopEvent(e); + } + return true; + } + + function onKeyDown(e) { + if(!kbEnabled) { + return true; + } + + e = e || window.event; + var kc = e.keyCode !== null ? e.keyCode : e.charCode, + value; + + if(kc < 33 || (kc > 40 && (kc != 45 && kc != 46))) { + return true; + } + + value = getWorkingValueFromInput(); + + if( kc == 37 || kc == 40 || kc == 46 || kc == 34) { + // left, down, ins, page down + value -= (e.ctrlKey || kc == 34 ? +maxStep : +step); + } else if( kc == 39 || kc == 38 || kc == 45 || kc == 33) { + // right, up, del, page up + value += (e.ctrlKey || kc == 33 ? +maxStep : +step); + } else if( kc == 35 ) { + // max + value = rMax; + } else if( kc == 36 ) { + // min + value = rMin; + } + + userSet = true; + valueToPixels(getValidValue(value)); + + callback("update"); + + // Opera doesn't let us cancel key events so the up/down arrows and home/end buttons will scroll the screen - which sucks + preventDefault(e); + } + + // MOUSE & TOUCH events + + function onMouseOver(e) { + addClass(innerWrapper, 'fd-slider-hover'); + } + + function onMouseOut(e) { + // Should really check we are not still in the slider + removeClass(innerWrapper, 'fd-slider-hover'); + } + + // Mousedown on the slider + function onMouseDown(e) { + e = e || window.event; + + // Stop page scrolling + preventDefault(e); + + // Grab the event target + var targ; + if (e.target) { + targ = e.target; + } else if (e.srcElement) { + targ = e.srcElement; + } + if(targ && targ.nodeType == 3) { + targ = targ.parentNode; + } + + // Are we using touchEvents + if(e.touches) { + // Skip gestures + if(e.targetTouches && e.targetTouches.length != 1) { + return false; + } + + e = e.touches[0]; + touchEvents = true; + } + + // Stop any animation timers + clearTimeout(timer); + timer = null; + + // Not keyboard enabled + kbEnabled = false; + + // User has set a value + userSet = true; + + // Handle mousedown - initiate drag + if(targ.className.search("fd-slider-handle") != -1) { + mousePos = vertical ? e.clientY : e.clientX; + handlePos = parseInt(vertical ? handle.offsetTop : handle.offsetLeft)||0; + + // Set a value on first click even if no movement + trackMouse(e); + + if(!touchEvents) { + addEvent(document, 'mousemove', trackMouse); + addEvent(document, 'mouseup', stopDrag); + } else { + addEvent(document, 'touchmove', trackMouse); + addEvent(document, 'touchend', stopDrag); + // Remove mouseEvents to stop them firing after the touch event + removeEvent(outerWrapper, "mousedown", onMouseDown); + } + + addClass(innerWrapper, 'fd-slider-active'); + addClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); + + callback("dragstart"); + + // Wrapper mousedown - initiate animation to click point + } else { + locate(); + + var posx = 0; + + if(e.pageX || e.pageY) { + posx = vertical ? e.pageY : e.pageX; + } else if (e.clientX || e.clientY) { + posx = vertical ? e.clientY + document.body.scrollTop + document.documentElement.scrollTop : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + } + + posx -= vertical ? y + Math.round(handle.offsetHeight / 2) : x + Math.round(handle.offsetWidth / 2); + posx = snapToPxValue(posx); + + // Tween animation to click point + if(animation == "tween") { + addClass(innerWrapper, 'fd-slider-active'); + tweenTo(posx); + // Progressive increment to click point + } else if(animation == "timed") { + addClass(innerWrapper, 'fd-slider-active'); + addEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); + destPos = posx; + onTimer(); + // Immediate jump to click point + } else { + pixelsToValue(posx); + //addEvent(document, touchEvents ? 'touchend' : 'mouseup', onMouseUp); + } + } + + return false; + } + + // Progressive increment to click point - clear the animation timer and remove the mouseup/touchend event + function onDocMouseUp( e ) { + e = e || window.event; + + preventDefault(e); + removeEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); + removeClass(innerWrapper, "fd-slider-active"); + + clearTimeout(timer); + timer = null; + kbEnabled = true; + + return false; + } + + // Mouseup or touchend event on the document to stop drag + function stopDrag(e) { + e = e || window.event; + + preventDefault(e); + + if(touchEvents) { + removeEvent(document, 'touchmove', trackMouse); + removeEvent(document, 'touchend', stopDrag); + } else { + removeEvent(document, 'mousemove', trackMouse); + removeEvent(document, 'mouseup', stopDrag); + } + + kbEnabled = true; + removeClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); + removeClass(innerWrapper, "fd-slider-active"); + + callback("dragend"); + + return false; + } + + // Mousemove or touchmove event on the drag handle + function trackMouse(e) { + e = e || window.event; + + preventDefault(e); + + if(e.touches) { + // Skip gestures + if(e.targetTouches && e.targetTouches.length != 1) { + return false; + } + e = e.touches[0]; + } + + pixelsToValue(snapToPxValue(handlePos + (vertical ? e.clientY - mousePos : e.clientX - mousePos))); + + return false; + } + + // Increments the slider by "inc" steps + function increment(inc) { + var value = getWorkingValueFromInput(); + userSet = true; + value += inc * step; + valueToPixels(getValidValue(value)); + } + + // Attempts to locate the on-screen position of the slider + function locate(){ + var curleft = 0, + curtop = 0, + obj = outerWrapper; + + // Try catch for IE's benefit + try { + do { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + } while(obj = obj.offsetParent); + } catch(err) {} + x = curleft; + y = curtop; + } + + // Used during the progressive animation to click point + function onTimer() { + var xtmp = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); + xtmp = Math.round((destPos < xtmp) ? Math.max(destPos, Math.floor(xtmp - stepPx)) : Math.min(destPos, Math.ceil(xtmp + stepPx))); + + pixelsToValue(snapToPxValue(xtmp)); + if(xtmp != destPos) { + timer = setTimeout(onTimer, steps > 20 ? 50 : 100); + } else { + kbEnabled = true; + removeClass(innerWrapper, "fd-slider-active"); + callback("finalise"); + } + } + + var tween = function(){ + frame++; + var c = tweenC, + d = 20, + t = frame, + b = tweenB, + x = Math.ceil((t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b); + + pixelsToValue(t == d ? tweenX : x); + + if(t!=d) { + // Call the "move" callback on each animation increment + callback("move"); + timer = setTimeout(tween, 20); + } else { + clearTimeout(timer); + timer = null; + kbEnabled = true; + + removeClass(innerWrapper, "fd-slider-focused"); + removeClass(innerWrapper, "fd-slider-active"); + + // Call the "finalise" callback whenever the animation is complete + callback("finalise"); + } + }; + + function tweenTo(tx){ + kbEnabled = false; + tweenX = parseInt(tx, 10); + tweenB = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); + tweenC = tweenX - tweenB; + tweenD = 20; + frame = 0; + + if(!timer) { + timer = setTimeout(tween, 20); + } + } + + // Returns a value within the range & sets the userSet var + // i.e. has the user entered a valid value + function checkValue(value) { + if(isNaN(value) || value === "" || typeof value == "undefined") { + userSet = false; + return defaultVal; + } else if(value < Math.min(rMin,rMax)) { + userSet = false; + return Math.min(rMin,rMax); + } else if(value > Math.max(rMin,rMax)) { + userSet = false; + return Math.max(rMin,rMax); + } + userSet = true; + return value; + } + + // Returns a value within a range - uses the form element value as base + function getWorkingValueFromInput() { + return getValidValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + } + + // Returns a value within the range + function getValidValue(value) { + return (isNaN(value) || value === "" || typeof value == "undefined") ? defaultVal : Math.min(Math.max(value, Math.min(rMin,rMax)), Math.max(rMin,rMax)); + } + + // Calculates value according to pixel position of slider handle + function pixelsToValue(px) { + var val = getValidValue(scale ? percentToValue(pixelsToPercent(px)) : vertical ? max - (Math.round(px / stepPx) * step) : min + (Math.round(px / stepPx) * step)); + + handle.style[vertical ? "top" : "left"] = (px || 0) + "px"; + redrawRange(); + setInputValue((tagName == "select" || step == 1) ? Math.round(val) : val); + } + + // Calculates pixel position according to form element value + function valueToPixels(val, updateInputValue) { + var clearVal = false, + value; + + // Allow empty values for non-polyfill sliders + if((typeof val === "undefined" || isNaN(val) || val === "") && tagName == "input" && !forceValue) { + value = defaultVal; + clearVal = true; + userSet = false; + } else { + value = checkValue(val); + } + + handle.style[vertical ? "top" : "left"] = (scale ? percentToPixels(valueToPercent(value)) : vertical ? Math.round(((max - value) / step) * stepPx) : Math.round(((value - min) / step) * stepPx)) + "px"; + redrawRange(); + if(typeof updateInputValue !== false) { + setInputValue(clearVal ? "" : value); + } + } + + // Rounds a pixel value to the nearest "snap" point on the slider scale + function snapToPxValue(px) { + if(scale) { + return Math.max(Math.min(rMaxPx, px), rMinPx); + } else { + var rem = px % stepPx; + if(rem && rem >= (stepPx / 2)) { + px += (stepPx - rem); + } else { + px -= rem; + } + + if(px < Math.min(Math.abs(rMinPx), Math.abs(rMaxPx))) { + px = Math.min(Math.abs(rMinPx), Math.abs(rMaxPx)); + } else if(px > Math.max(Math.abs(rMinPx), Math.abs(rMaxPx))) { + px = Math.max(Math.abs(rMinPx), Math.abs(rMaxPx)); + } + + return Math.min(Math.max(px, 0), rMaxPx); + } + } + + // Calculates a value according to percentage of distance handle has travelled + function percentToValue(pct) { + var st = 0, + fr = min, + value; + + for(var s in scale) { + if(!scale.hasOwnProperty(s)) { + continue; + } + + if(pct >= st && pct <= +s ) { + value = fr + ((pct - st) * (+scale[s] - fr) ) / (+s - st); + } + + st = +s; + fr = +scale[s]; + } + + return value; + } + + // Calculates the percentage handle position according to form element value + function valueToPercent(value) { + var st = 0, + fr = min, + pct = 0; + + for(var s in scale) { + if(!scale.hasOwnProperty(s)) { + continue; + } + + if(value >= fr && value <= +scale[s]){ + pct = st + (value - fr) * (+s - st) / (+scale[s] - fr); + } + + st = +s; + fr = +scale[s]; + } + + return pct; + } + + function percentToPixels(percent) { + return ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - handle[vertical ? "offsetHeight" : "offsetWidth"]) / 100) * percent; + } + + function pixelsToPercent(pixels) { + return pixels / ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - outerWrapper[handle ? "offsetHeight" : "offsetWidth"]) / 100); + } + + // Sets the form element with a valid value + function setInputValue(val) { + // The update callback doesn't mean the input value has changed + callback("update"); + + // If the user has not set this value or has entered an incorrect value then set a class + // to enable styling of the slider + if(!userSet) { + addClass(innerWrapper, "fd-slider-no-value"); + } else { + removeClass(innerWrapper, "fd-slider-no-value"); + } + + if(tagName == "select") { + try { + val = parseInt(val, 10); + if(inp.selectedIndex === val) { + updateAriaValues(); + return; + } + inp.options[val].selected = true; + } catch (err) {} + } else { + if(val !== "" && !userInput) { + val = (min + (Math.round((+val - min) / step) * step)).toFixed(precision); + } + if(inp.value === val) { + updateAriaValues(); + return; + } + inp.value = val; + } + + updateAriaValues(); + callback("change"); + } + + function checkInputValue(value) { + return !(isNaN(value) || value === "" || value < Math.min(rMin,rMax) || value > Math.max(rMin,rMax)); + } + + function setSliderRange(newMin, newMax) { + if(rMin > rMax) { + newMin = Math.min(min, Math.max(newMin, newMax)); + newMax = Math.max(max, Math.min(newMin, newMax)); + rMin = Math.max(newMin, newMax); + rMax = Math.min(newMin, newMax); + } else { + newMin = Math.max(min, Math.min(newMin, newMax)); + newMax = Math.min(max, Math.max(newMin, newMax)); + rMin = Math.min(newMin, newMax); + rMax = Math.max(newMin, newMax); + } + + if(defaultVal < Math.min(rMin, rMax)) { + defaultVal = Math.min(rMin, rMax); + } else if(defaultVal > Math.max(rMin, rMax)) { + defaultVal = Math.max(rMin, rMax); + } + + handle.setAttribute("aria-valuemin", rMin); + handle.setAttribute("aria-valuemax", rMax); + + checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + redraw(); + } + + function redrawRange() { + if(noRangeBar) { + return; + } + if(vertical) { + rangeBar.style["height"] = Math.max(1, (bar.offsetHeight - handle.offsetTop)) + "px"; + } else { + rangeBar.style["width"] = Math.max(1, handle.offsetLeft) + "px"; + } + } + + function findLabel() { + var label = false, + labelList = document.getElementsByTagName('label'); + // loop through label array attempting to match each 'for' attribute to the id of the current element + for(var i = 0, lbl; lbl = labelList[i]; i++) { + // Internet Explorer requires the htmlFor test + if((lbl['htmlFor'] && lbl['htmlFor'] == inp.id) || (lbl.getAttribute('for') == inp.id)) { + label = lbl; + break; + } + } + + if(label && !label.id) { + label.id = inp.id + "_label"; + } + + return label; + } + + function updateAriaValues() { + var val = tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value, + valTxt = ariaFormat ? ariaFormat(val) : tagName == "select" ? (inp.options[inp.selectedIndex].text ? inp.options[inp.selectedIndex].text : val) : val; + + handle.setAttribute("aria-valuenow", val); + handle.setAttribute("aria-valuetext", valTxt); + } + + function onInputChange(e) { + userSet = true; + userInput = userSnap; + valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + updateAriaValues(); + userInput = false; + } + + function onReset(e) { + if(tagName == "input") { + inp.value = inp.defaultValue; + } else { + inp.selectedIndex = resetDef; + } + checkValue(tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value); + redraw(); + updateAriaValues(); + } + + // Sets a tabindex attribute on an element, bends over for IE. + function setTabIndex(e, i) { + e.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", i); + e.tabIndex = i; + } + + (function() { + if(html5Shim || hideInput) { + addClass(inp, "fd-form-element-hidden"); + try { + // FF21 hack to change input type to text + if(inp.type != "range" && + getAttribute(inp, "type") == "range" && + document.defaultView.getComputedStyle(inp, null).getPropertyValue("display") == "inline-block") { + inp.type="number"; + } + } catch(err){} + } else { + addEvent(inp, 'change', onInputChange); + } + + // Add stepUp & stepDown methods to input element if using the html5Shim + if(html5Shim) { + inp.setAttribute("fd-range-enabled", 1); + inp.stepUp = function(n) { increment(n||1); }; + inp.stepDown = function(n) { increment(n||-1); }; + + if(useDOMAttrModEvt) { + addEvent(inp, typeof(inp.onpropertychange) == "object" ? "propertychange" : "DOMAttrModified", rescanAttrs); + } + } + + outerWrapper = document.createElement('span'); + outerWrapper.className = "fd-slider" + (vertical ? "-vertical " : " ") + classNames; + outerWrapper.id = "fd-slider-" + inp.id; + + if(vertical && inpHeight) { + outerWrapper.style.height = inpHeight + "px"; + } + + innerWrapper = document.createElement('span'); + innerWrapper.className = "fd-slider-wrapper" + (!html5Shim ? " fd-slider-no-value" : ""); + + ieBlur = document.createElement('span'); + ieBlur.className = "fd-slider-inner"; + + bar = document.createElement('span'); + bar.className = "fd-slider-bar"; + + if(fullARIA) { + handle = document.createElement('span'); + } else { + handle = document.createElement('a'); + handle.setAttribute("href", "#"); + addEvent(handle, "click", stopEvent); + } + + setTabIndex(handle, 0); + + handle.className = "fd-slider-handle"; + handle.appendChild(document.createTextNode(String.fromCharCode(160))); + + innerWrapper.appendChild(ieBlur); + + if(!noRangeBar) { + rangeBar = document.createElement('span'); + rangeBar.className = "fd-slider-range"; + innerWrapper.appendChild(rangeBar); + } + + innerWrapper.appendChild(bar); + innerWrapper.appendChild(handle); + outerWrapper.appendChild(innerWrapper); + + inp.parentNode.insertBefore(outerWrapper, inp); + + if(isOpera || /*@cc_on!@*/!true) { + handle.unselectable = "on"; + bar.unselectable = "on"; + ieBlur.unselectable = "on"; + outerWrapper.unselectable = "on"; + innerWrapper.unselectable = "on"; + if(!noRangeBar) { + rangeBar.unselectable = "on"; + } + } + + // Add ARIA accessibility info programmatically + outerWrapper.setAttribute("role", "application"); + + handle.setAttribute("role", "slider"); + handle.setAttribute("aria-valuemin", tagName == "select" ? inp.options[0].value : min); + handle.setAttribute("aria-valuemax", tagName == "select" ? inp.options[inp.options.length - 1].value : max); + + var lbl = findLabel(); + if(lbl) { + handle.setAttribute("aria-labelledby", lbl.id); + handle.id = "fd-slider-handle-" + inp.id; + /*@cc_on@*/ + /*@if(@_win32) + lbl.setAttribute("htmlFor", handle.id); + @else @*/ + lbl.setAttribute("for", handle.id); + /*@end@*/ + } + + // Are there page instructions + if(document.getElementById(describedBy)) { + handle.setAttribute("aria-describedby", describedBy); + } + + // Is the form element initially disabled + if(inp.getAttribute("disabled") === true || inp.getAttribute("disabled") == "disabled") { + disableSlider(true); + } else { + enableSlider(true); + } + + // Does an initial form element value mean the user has set a valid value? + // Also called onload in case browsers have automatically set the input value + if(varSetRules.onvalue) { + userSet = true; + checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); + } + + // Catch form reset events + if(inp.form) { + addEvent(inp.form, "reset", onReset); + } + + updateAriaValues(); + callback("create"); + redraw(); + })(); + + return { + onResize: function(e) { if(outerWrapper.offsetHeight != sliderH || outerWrapper.offsetWidth != sliderW) { redraw(); } }, + destroy: function() { destroySlider(); }, + reset: function() { valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); }, + stepUp: function(n) { increment(Math.abs(n)||1); }, + stepDown: function(n) { increment(-Math.abs(n)||-1); }, + increment: function(n) { increment(n); }, + disable: function() { disableSlider(); }, + enable: function() { enableSlider(); }, + setRange: function(mi, mx) { setSliderRange(mi, mx); }, + getValueSet: function() { return !!userSet; }, + setValueSet: function(tf) { valueSet(tf); }, + rescan: function() { rescanAttrs(); }, + checkValue: function() { if(varSetRules.onvalue) { userSet = true; checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); } updateAriaValues(); redraw(); } + }; + } + + addEvent(window, "load", init); + addEvent(window, "load", function() { setTimeout(function() { var slider; for(slider in sliders) { sliders[slider].checkValue(); } }, 0); }); + addEvent(window, "resize", resize); + addEvent(window, "unload", unload); + + // Have we been passed JSON within the including script tag + (function() { + var scriptFiles = document.getElementsByTagName('script'), + json = parseJSON(String(scriptFiles[scriptFiles.length - 1].innerHTML).replace(/[\n\r\s\t]+/g, " ").replace(/^\s+/, "").replace(/\s+$/, "")); + + if(typeof json === "object" && !("err" in json)) { + affectJSON(json); + } + })(); + + // Add oldie class if needed for IE < 9 + /*@cc_on@*/ + /*@if (@_jscript_version < 9) + addClass(document.documentElement, "oldie"); + /*@end@*/ + + return { + rescanDocument: init, + createSlider: function(opts) { return createSlider(opts); }, + onDomReady: function() { onDomReady(); }, + destroyAll: function() { destroyAllsliders(); }, + destroySlider: function(id) { return destroySingleSlider(id); }, + redrawAll: function() { resize(); }, + addEvent: addEvent, + removeEvent: removeEvent, + stopEvent: stopEvent, + increment: function(id, numSteps) { if(!sliderExists(id)) { return false; } sliders[id].increment(numSteps); }, + stepUp: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepUp(Math.abs(n)||1); }, + stepDown: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepDown(-Math.abs(n)||-1); }, + setRange: function(id, newMin, newMax) { if(!sliderExists(id)) { return false; } sliders[id].setRange(newMin, newMax); }, + updateSlider: function(id) { if(!sliderExists(id)) { return false; } sliders[id].onResize(); sliders[id].reset(); }, + disable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].disable(); }, + enable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].enable(); }, + getValueSet: function() { return getValueSet(); }, + setValueSet: function(a, tf) { if(!sliderExists(id)) { return false; } setValueSet(a, tf); }, + setGlobalVariables: function(json) { affectJSON(json); }, + removeOnload: function() { removeOnLoadEvent(); }, + rescanAttributes: rescanAttributes + }; +})(); diff --git a/static/dist/scripts/graphs.js b/static/dist/scripts/graphs.js new file mode 100644 index 0000000..7c05998 --- /dev/null +++ b/static/dist/scripts/graphs.js @@ -0,0 +1,186 @@ +/* Extend jquery */ +(function ( $ ) { + $.fn.graph = function(action, options) { + // These are the defaults + var settings = $.extend({ + width: undefined, + height: undefined, + animation_duration: 1000 // ms + }, options ); + /* The slug of each Graph object map to a function in the graphs object */ + var graphs = { + treatment: function(element) { + $(element).highcharts({ + chart: { + type: 'column', + width: settings.width, + height: settings.height, + animation: { + duration: settings.animation_duration + } + }, + title: { + text: 'Antall behandlinger' + }, + xAxis: { + title: { + text: 'År' + }, + minRange : 30 * 24 * 3600 * 1000, // + minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year + type: 'datetime' + }, + yAxis: { + title: { + text: 'Antall behandlinger' + } + + }, + series: [{ + name: 'Antall behandlinger', + data: [ + [Date.UTC(2007, 1), 35000], + [Date.UTC(2008, 1), 40000], + [Date.UTC(2009, 1), 60000], + [Date.UTC(2010, 1), 67000], + [Date.UTC(2011, 1), 70000], + [Date.UTC(2012, 1), 78000], + [Date.UTC(2013, 1), 97000], + [Date.UTC(2014, 1), 109000]], + enabled: false + + }], + legend: { + enabled: false + } + }); + }, + treatment_distribution: function(element) { + var last_year = new Date().getFullYear() - 1; + $(element).highcharts({ + chart: { + type: 'column', + width: settings.width, + height: settings.height, + animation: { + duration: settings.animation_duration + } + }, + title: { + text: 'Fordeling behandlinger' + }, + xAxis: { + title: { + text: 'Måned' + }, + minRange : 30 * 24 * 3600 * 1000, // + minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year + type: 'datetime' + }, + yAxis: { + title: { + text: 'Fordeling' + } + + }, + series: [{ + name: 'Preeksisterende', + data: [ + [Date.UTC(last_year, 0), 2], + [Date.UTC(last_year, 1), 5], + [Date.UTC(last_year, 2), 10], + [Date.UTC(last_year, 3), 20], + [Date.UTC(last_year, 4), 40], + [Date.UTC(last_year, 5), 70], + [Date.UTC(last_year, 6), 40], + [Date.UTC(last_year, 7), 40], + [Date.UTC(last_year, 8), 40]] + }, + { + name: 'Nye lidelser', + data: [ + [Date.UTC(last_year, 0), 8], + [Date.UTC(last_year, 1), 10], + [Date.UTC(last_year, 2), 15], + [Date.UTC(last_year, 3), 18], + [Date.UTC(last_year, 4), 20], + [Date.UTC(last_year, 5), 30], + [Date.UTC(last_year, 6), 40], + [Date.UTC(last_year, 7), 40], + [Date.UTC(last_year, 8), 40]] + }], + plotOptions: { + column: { + stacking: 'normal' + } + } + }); + }, + num_insured: function(element) { + $(element).highcharts({ + chart: { + type: 'column', + width: settings.width, + height: settings.height, + animation: { + duration: settings.animation_duration + } + }, + title: { + text: 'Antall forsikrede (behandlingsforsikring) per 30. juni 2003-2014' + }, + xAxis: { + title: { + text: 'År' + }, + tickInterval: Date.UTC(1902, 0, 1) - Date.UTC(1901, 0, 1), // A year + year: '%Y', + type: 'datetime' + }, + yAxis: { + title: { + text: 'Antall forsikrede' + } + + }, + series: [{ + name: 'Antall forsikrede', + data: [ + [Date.UTC(2003, 0), 14587], + [Date.UTC(2004, 0), 20634], + [Date.UTC(2005, 0), 35418], + [Date.UTC(2006, 0), 42073], + [Date.UTC(2007, 0), 74435], + [Date.UTC(2008, 0), 97661], + [Date.UTC(2009, 0), 115651], + [Date.UTC(2010, 0), 141742], + [Date.UTC(2011, 0), 233739], + [Date.UTC(2012, 0), 357468], + [Date.UTC(2013, 0), 404320], + [Date.UTC(2014, 0), 437137]], + enabled: false + + }], + legend: { + enabled: false + } + }); + } + }; + + /* What do do? */ + if(action == 'load') { + /* For each element get attr and load appropriate graph */ + return this.each(function() { + var slug = $(this).attr('data-graph-slug'); + // Create a graphs[slug] of this. + graphs[slug](this); + }); + } else if(action == 'get') { + /* Not used + return Highcharts.charts[loaded_graphs[slug].data('highchartsChart')]; + */ + } + }; + +}( jQuery )); diff --git a/static/dist/scripts/presentation_edit.js b/static/dist/scripts/presentation_edit.js new file mode 100644 index 0000000..4ce5f7a --- /dev/null +++ b/static/dist/scripts/presentation_edit.js @@ -0,0 +1,121 @@ +function get_offset(col, grid_height, min_widget_height) { + var num_slides = $('.slide[data-col="'+ col +'"]').length; + return (grid_height - (num_slides * min_widget_height)) * -1; +} + +/* Push add buttons up x px, close to the lowest slide in its section */ +function reposition_add_buttons(min_widget_height) { + var max_rows = _.max($(".slide"), function(slide){ return parseInt($(slide).attr('data-row')); }); + var grid_height = $(max_rows).attr('data-row') * min_widget_height; + + $(".slide-add").each(function() { + var offset = get_offset($(this).attr('data-col'), grid_height, min_widget_height); + $(this).css({ top: offset }); + }); +} +$(function(){ + // TODO: on document ready, to load: loading icon + var margin_x = 8; + var margin_y = 4; + var csrf_token = $.cookie('csrftoken'); + var grid = $(".gridster ul").gridster({ + widget_selector: "li.slide", + widget_margins: [margin_x, margin_y], + widget_base_dimensions: [113, 80], + min_cols: 6, + serialize_params: function($w, wgd) { + return { + slide: $w.attr('data-slide'), + section: $('.sections li[data-col="'+ wgd.col +'"]').attr('data-section'), + order: wgd.row + }; + }, + draggable: { + // https://github.com/ducksboard/gridster.js/issues/161 + handle: 'img', // FIXME: Edit link is not working on touch + stop: function() { + /* reposition add buttons */ + reposition_add_buttons(this.min_widget_height); + + /* Save grid order */ + var grid = this.serialize_changed(); + + var slides = []; + for(var i in grid ) { + slides.push({ name: "slide-order-"+grid[i].slide, value: grid[i].order }); + slides.push({ name: "slide-section-"+grid[i].slide, value: grid[i].section }); + } + /* Prepare data */ + var data = $("#presentation-form").serializeArray(); + data = data.concat(slides); + /* http post json */ + var url = $("#presentation").attr('data-save-url'); + $.ajax({ + type: "POST", + url: url, + data: data, + async: false, // FIXME: Make async + headers: { + 'X-CSRFToken': csrf_token + }, + success: function (result,l,o) { + if(result !== undefined && result.success) { + /* redirect to edit url */ + window.location = "/slideshow/" + result.presentation_id + "/edit/"; + } else { + //console.log("Saved"); //FIXME notify + } + }, + error: function (request, text_status, error_thrown) { + console.log("uffda..."); //FIXME notify + } + }); + } + } + }); + /* Note: gridster api add, remove, serialize */ + var gridster = grid.data('gridster'); + + /* reposition add buttons */ + reposition_add_buttons(gridster.min_widget_height); + + /* Datepicker */ + $("#id_datetime").datepicker({ + dateFormat: "yy-mm-dd" + }); + /* Disable slide controls */ + $(".slide-toggle").on('click', function(e) { + /* Set slide.active=false */ + var that = $(this); + var current_slide = $(this).parent().parent(); + var new_state = current_slide.hasClass("disabled"); + var url = $(this).attr('data-save-url'); + $.ajax({ + type: "PATCH", + url: url, + data: { + active: new_state + }, + headers: { + 'X-CSRFToken': csrf_token + }, + success: function (result,l,o) { + + /* toggle 'disabled' class */ + current_slide.toggleClass("disabled"); + /* switch icons class */ + var icon = that.find("i"); + if(icon.hasClass("fa-square-o")) { + icon.removeClass("fa-square-o").addClass("fa-check-square-o"); + } else { + icon.removeClass("fa-check-square-o").addClass("fa-square-o"); + } + }, + error: function (request, text_status, error_thrown) { + console.log("uffda..."); //FIXME notify + } + }); + + }); + +}); \ No newline at end of file diff --git a/static/dist/scripts/presentation_list.js b/static/dist/scripts/presentation_list.js new file mode 100644 index 0000000..5edc624 --- /dev/null +++ b/static/dist/scripts/presentation_list.js @@ -0,0 +1,9 @@ + +$(function(){ + //var options = { +    // valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] +    //}; + +    //var featureList = new List('presentation-table-sortable', options); + //featureList.sort('waittime', { asc: false }); +}); diff --git a/static/dist/scripts/product_calculator.js b/static/dist/scripts/product_calculator.js new file mode 100644 index 0000000..1036188 --- /dev/null +++ b/static/dist/scripts/product_calculator.js @@ -0,0 +1,541 @@ +$(document).ready( function() { + /* Slide: Product calculator */ + /* + * TODO: set discount based on url or user/session data + * + * */ + function set_progress(percent) { + if( percent < 1 || percent > 100 ) { + return; + } + $(".stb-progress .meter").css('width', percent+"%"); + } + function product_select(products, treatments, counceling) { + /* Searches products and returns the correct price */ + //console.log(products, treatments, counceling); + var selected = products; + if(counceling !== undefined) { + selected = _.filter(selected, function(product) { + return product.counceling_service == counceling; + }); + } + if(selected.length == 1) { + return selected[0]; + } + if(treatments !== undefined) { + selected = _.filter(selected, function(product) { + return product.treatments == treatments; + }); + } + if(selected.length == 1) { + return selected[0]; + } + //console.log("Fant ingen produkter, returnerer siste"); + return products[products.length-1]; + } + //function filter_product_risk(documents, product_order) { + // /* filter based on product risk variables */ + // var product_risk_variable_attrs = [ + // 'eligible_industry_discount', + // 'has_existing_insurance', + // 'employees', + // 'addon_psychiatric_treatment']; + + // /* which variables are set? */ + // var product_risk_variables = _.filter(product_risk_variable_attrs, function(attr) { + // return product_order[attr] !== undefined; + // }); + // //console.log("product risk variables: ", product_risk_variables); + + // /* filter based on vars in product_risk_variables and product_order + // * all must match */ + // documents = _.filter(documents, function(doc){ + // //console.log("looking at: ", doc.name, "(", doc.id, ")"); + // // filter when not specified + // if(!doc.product_risk_variables.length) { + // return false; + // } + + // /* Loop over the product_risks attached to this document */ + // var doc_matches = _.map(doc.product_risk_variables, function(variables, index, list) { + // /* Loop over each variable in the list of risks */ + // var var_matches = _.map(product_risk_variables, function(element) { + // //console.log("looping document risk vars: ", element, product_order[element], variables[element], variables); + // // num employees special case + // if(element == 'employees' && (product_order[element] > variables['employees_max'] || product_order[element] < variables['employees_min'])) { + // return false + // } + // else if(product_order[element] != variables[element] && element != 'employees') { + // return false; // drop document + // } + // return true; + // }); + // // All attributes in the product_order must match with variables + // return _.every(var_matches); + // }); + // // Need just one match to keep the document + // return _.some(doc_matches); + // }); + // return documents; + //} + //function filter_individual_risk(documents, product_order) { + // //console.log("individual risk variables: ", product_order.individual_term_employees); + // /* Filter based on age ranges */ + // var ages = _.map(product_order.individual_term_employees, function(employee) { + // return employee.age; + // }); + // /* Filter documents not referencing at least one individual risk variable matching the specified ages */ + // documents = _.filter(documents, function(doc) { + // // filter when not specified + // // Note: Unsure if this is correct + // if(!doc.employee_risk_variables.length) { + // return false; + // } + // var matches = _.map(doc.employee_risk_variables, function(variables, index, list) { + // var age_matches = _.map(ages, function(age) { + // return age >= variables.age_min && age <= variables.age_max; + // }); + // return _.some(age_matches); // matching at least one age + // }); + // return _.some(matches); //matching at least one risk variable + // }); + // return documents; + //} + //function filter_documents(documents, product_order) { + // /* Filter based on product selection + // * Note: only filters by product if below 100 employees */ + // if(product_order.employees < 100) { + // var documents = _.filter(documents, function(doc){ + // var product_ids = _.map(doc.products, function(product) { return product.id; }); + // return _.contains(product_ids, product_order.product.id); + // }); + + // if(product_order.employees >=1 && product_order.employees <= 4 && !product_order.eligible_industry_discount) { + // documents = filter_individual_risk(documents, product_order); + // } + // else { + // documents = filter_product_risk(documents, product_order); + // } + // } else { + // /* Filter based on dummy no-product */ + // documents = _.filter(documents, function(doc){ + // var product_slugs = _.map(doc.products, function(product) { return product.slug; }); + // return _.contains(product_slugs, 'no-product'); + // }); + // + // } + // return documents; + // + //} + //function update_document_list(documents) { + // if(documents.length == 0) { + // $(".product-calculator .documents-table").html("Fillern, det er ingen dokumenter knyttet til dette produktet og valgte variable :'("); + // return; + // } + // var html = ""; + // _.each(documents, function(doc) { + // html += ''; + // }); + // html += "
    NavnType
    '+ doc.name +''+ doc.category +'
    "; + // $(".product-calculator .documents-table").html(html); + //} + function get_price_individual(product, product_order) { + /* Need a valid product */ + if(product === undefined || product.employee_risk_variables.length === 0) { + return -1; + } + /* Invidual risk */ + var has_existing_insurance = false; + if( product_order.has_existing_insurance !== undefined) { + has_existing_insurance = product_order.has_existing_insurance; + } + /* Get list of prices for each employee */ + var prices = _.map(product_order.individual_term_employees, function(employee) { + /* Filter by employee-age */ + var variation = _.find(product.employee_risk_variables, function(variation) { + if(employee.age >= variation.age_min && employee.age <= variation.age_max) { + return true; + } + return false; + }); + return variation.price; + }); + return prices; + } + + function get_price(product, product_order) { + /* Group risk */ + var price = 0; + var has_existing_insurance = false; + if( product_order.has_existing_insurance !== undefined) { + has_existing_insurance = product_order.has_existing_insurance; + } + + /* Filter by boolean values */ + var variations = _.where(product.product_risk_variables, { + eligible_industry_discount: product_order.eligible_industry_discount, + has_existing_insurance: has_existing_insurance, + }); + /* Filter by num employees */ + variation = _.filter(variations, function(variation) { + if(variation.employees_max == product_order.employees ) { + return true; + } + }); + if(variation.length >= 1) { + price = parseInt(variation[0].price); + } else { + /* Error: Missing product data in db */ + price = -1; + } + /* include price for psychiatric treatment addon */ + // FIXME price is static. + if(product_order.addon_psychiatric_treatment !== undefined && product_order.addon_psychiatric_treatment) { + price += 204; + } + + return price; + } + function product_recalc(products, product_order) { + var product = product_select( + products, + product_order.treatments, + product_order.counceling); + + /* calculate price based in product and current risk data */ + var price_formatted; + + if(product_order.employees <= 4 && ! product_order.eligible_industry_discount) { + var prices = get_price_individual(product, product_order); + var sum = _.reduce(prices, function(memo, num) { return memo + parseInt(num); }, 0); + if(sum === 0) { + price_formatted = "Prøv andre valg, ingen pris funnet."; + } else { + if(prices.length == 1) { + price_formatted = "NOK " + sum + ",- per måned"; + } else { + price_formatted = prices.join(" + ")+" = NOK " + sum + ",- per måned"; + } + } + } else { + price = get_price(product, product_order); + if(price == -1) { + price_formatted = "Prøv andre valg, ingen pris funnet."; + } else { + price_formatted = "NOK " + price + ",- per år"; + } + } + product_order.product = product; + $("[data-prodcalc-product]").text(product.name); + $("[data-prodcalc-product-price]").text(price_formatted); + } + //function update_relevant_documents(product_order) { + + // var url = $(".product-calculator[data-documents-url]").attr('data-documents-url'); + // $.ajax({ + // url: url, + // method: 'GET', + // dataType: 'json', + // headers: { + // 'X-CSRFToken': $("[name=csrfmiddlewaretoken]").val() + // }, + // success: function(documents) { + // /* Present only the right documents, ordered by category */ + // //console.log("fetched the following documents:", documents); + // //console.log("filtering based on product_order", product_order); + + // var less_documents = filter_documents(documents, product_order); + // //console.log("returned these documents:", less_documents); + // update_document_list(less_documents); + // } + // }); + //} + + if($(".product-calculator").length) { + /* product_order stores the state of the order */ + var product_order = {}; + var product_order_steps = {}; + var num_product_order_steps = 6; + + /* Is the industry discount disabled? */ + if ( $('.product-calculator[data-disable-industry-discount]').length ) { + product_order.eligible_industry_discount = false; + $("[data-key=treatments][data-value=5]").show(); + } + + /* General layout of steps when user interacts with page: + * - update product_order state + * - update progress based on state + * - update the dom with the correct display state (button state, step description) + * - find product based on selection + * - calculate price based on discounts, selection and product + */ + + $.getJSON('/products.json', function(products) { + /* Attach to buttons and fields */ + + /* On every answer change */ + $("[data-answer]").on('click', function(e) { + var key = $(this).attr('data-key'); + var value = $(this).attr('data-value'); + + /* to_javascript */ + if (value == "no") { + value = false; + } + else if(value == "yes") { + value = true; + } + if(key == "treatments" || key == "employees") { + value = parseInt(value); + } + + /* limit options and change display */ + /* based on employees */ + if(key == "employees") { + if( value >= 20) { + if(product_order.has_exisiting_insurance === undefined) { + $(".modal-has-existing-insurance").foundation('reveal', 'open'); + } + } else { + /* Reset answer */ + delete product_order.has_exisiting_insurance; + $(".modal-has-existing-insurance button").removeClass("selected disabled"); + } + + var min_value = $(this).attr('data-min'); + /* if between 1 and 4 then.. */ + if( value <= 4 && min_value >= 1 && !product_order.eligible_industry_discount) { + /* display individual employee risk container */ + $(".individual-pricing-container").fadeIn('fast'); + /* Note: Fetching employee ages before anyone have been selected */ + update_employee_ages(); + } else { + $(".individual-pricing-container").fadeOut('fast'); + $("[data-key=treatments][data-value=12]").show(); + } + /* Next button */ + $("[data-goto-part=part-two]").fadeIn('fast'); + } + /* based on industry deal */ + if(key == "eligible_industry_discount") { + if(value) { + /* limit num treatments*/ + $("[data-key=treatments][data-value=5]").hide(); + } else { + $("[data-key=treatments][data-value=5]").show(); + } + if( !value && product_order.employees <= 4 && product_order.employees >= 1) { + $(".individual-pricing-container").fadeIn('fast'); + } else { + $(".individual-pricing-container").fadeOut('fast'); + } + + $(".prod-num-staff").fadeIn('fast'); + $(".part-one-zero").fadeOut('fast'); + setTimeout(function() { + $(".part-one-one").fadeIn('fast'); + }, 400); + } + /* based on counceling */ + if(key == "counceling") { + $(".prod-num-treatments").fadeIn('fast'); + $(".about-num-treatments").fadeIn('fast'); + if(value) { + /* limit num treatments and auto-select 24 */ + $("[data-key=treatments][data-value=5], [data-key=treatments][data-value=0]").hide(); + product_order.treatments = 24; + product_order_steps.treatments = 24; + $("[data-key=treatments]").removeClass("selected disabled"); + $("[data-key=treatments][data-value=24]").addClass("selected"); + /* update coverage */ + $(".coverage-treatments").text(product_order.treatments); + $(".selected-coverage .topp, .selected-coverage .treatments").fadeIn('fast'); + } else { + /* show all treatments, except 0 if industry deal */ + if( !product_order.eligible_industry_discount ) { + $("[data-key=treatments][data-value=5]").show(); + } + // FIXME: missing pricing data, just hide this option for now + if(product_order.employees <= 4) { + $("[data-key=treatments][data-value=0]").hide(); + } else { + $("[data-key=treatments][data-value=0]").show(); + } + $(".selected-coverage .topp").fadeOut('fast'); + } + } + /* based on addon_psychiatric_treatment */ + if(key == "addon_psychiatric_treatment") { + $(".prod-num-treatments").fadeIn('fast'); + $(".about-num-treatments").fadeIn('fast'); + $(".selected-coverage .counceling").fadeOut('fast'); + if(value) { + /* limit num treatments and auto-select 24 */ + $("[data-key=treatments][data-value=0]").hide(); + product_order.treatments = 24; + product_order_steps.treatments = 24; + $("[data-key=treatments]").removeClass("selected disabled"); + $("[data-key=treatments][data-value=24]").addClass("selected"); + /* update coverage */ + $(".coverage-treatments").text(product_order.treatments); + $("[data-prodcalc-addon]").text("med psykologi"); + $(".selected-coverage .treatments").fadeIn('fast'); + $(".selected-coverage .topp, .selected-coverage .psychology").fadeIn('fast'); + } else { + $(".selected-coverage .topp").fadeOut('fast'); + $("[data-prodcalc-addon]").text(""); + $("[data-key=treatments][data-value=0]").show(); + } + } + /* based on num treatments */ + if(key == "treatments") { + /* update coverage */ + if(value > 0) { + $(".selected-coverage .treatments").fadeIn('fast'); + $(".coverage-treatments").text(value); + } else if(value === 0) { + $(".selected-coverage .topp").fadeOut('fast'); + $(".selected-coverage .treatments").fadeOut('fast'); + $(".coverage-treatments").text(value); + } else { + $(".selected-coverage .treatments:visible").fadeOut('fast'); + } + } + + /* Update current answers. + * ie. industry discount, number of treatments, counceling and addon_psychiatric_treatment + */ + product_order[key] = value; + product_order_steps[key] = value; + + $(this).addClass("selected").removeClass("disabled"); + $("[data-key="+ key +"]").not(this).removeClass("selected").addClass("disabled"); + product_recalc(products, product_order); + /* total questions by number by answered questions */ + var current_progress = _.size(product_order_steps) / parseFloat(num_product_order_steps) * 100; + set_progress(current_progress); + }); + + /* Go on to the section after this one */ + $("[data-goto-part]").on('click', function(e) { + product_recalc(products, product_order); + var part = $(this).attr('data-goto-part'); + + + /* Product tailoring */ + if(part == 'part-two' && product_order.employees < 100) { + //console.log(product_order); + $(".part-zero, .part-one-right-container").fadeOut('fast'); + setTimeout(function() { + if(product_order.eligible_industry_discount) { + /* Don't ask for counceling, and set it to false */ + product_order.counceling = false; + $(".addon_psychiatric_treatment").fadeIn('fast'); + $(".about-addon-psychiatric-treatment").fadeIn('fast'); + $(".about-counceling").hide(); + } else { + $(".part-two .counceling").fadeIn('fast'); + // FIXME remove this if business rules are valid + //if(product_order.employees >= 20 && product_order.employees <= 99) { + // $(".about-num-treatments").fadeIn('fast'); + // $(".prod-num-treatments").fadeIn('fast'); + //} else { + // $(".part-two .counceling").fadeIn('fast'); + //} + } + $(".part-two-and-a-half-container").fadeIn('fast'); + $(".part-two").fadeIn('fast'); + if(product_order.has_exisiting_insurance) { + $(".part-two-right .need-stats").show(); + } else { + $(".part-two-right .need-stats").hide(); + } + }, 500); + } + /* Skip product tailoring */ + if( part == 'part-two' && product_order.employees >= 100) { + set_progress(100); + /* Get relevant product documents */ + //update_relevant_documents(product_order); + /* Show documents tab */ + $(".part-zero, .part-one-right-container").fadeOut('fast'); + setTimeout(function() { + if(product_order.has_exisiting_insurance) { + $(".part-three-special .need-stats").show(); + } else { + $(".part-three-special .need-stats").hide(); + } + $(".part-three-special").fadeIn('fast'); + }, 500); + } + + + /* "We recommend the product..." */ + if(part == 'part-two-and-a-half') { + $(".part-two-right").fadeOut('fast'); + $(".select-product-btn").fadeIn('fast'); + setTimeout(function() { + $(".part-two-and-a-half").fadeIn('fast'); + }, 500); + } + + + + /* Document "checkout" - fancy schmancy */ + if( part == 'part-three') { + set_progress(100); + /* Get relevant product documents */ + //update_relevant_documents(product_order); + + /* Show documents tab */ + $(".part-two, .part-one").fadeOut('fast'); + setTimeout(function() { + $(".part-two-and-a-half").parent().removeClass("small-7").addClass("small-12"); + $(".eula-container").removeClass("small-7").addClass("small-4"); + $(".product-description-inner").removeClass("small-5").addClass("small-3"); + $(".part-three").fadeIn('fast'); + }, 300); + $('[data-goto-part="part-three"]').fadeOut('fast'); + } + }); + + /* Update the product_order with individual employee ages */ + function update_employee_ages() { + var employees = []; + var i = 1; + $(".individual-pricing-container select.age-select-dropdown:visible").each(function(j, el) { + age = parseInt($(el).val().split(" -")[0]); + employees.push({ id: i, age: age }); + i++; + }); + product_order.individual_term_employees = employees; + } + $(".individual-pricing-container select.age-select-dropdown").on('change', update_employee_ages); + + /* add html for individual employee risk */ + $(".individual-pricing-container").on('click', "[data-add-new-employee]", function(e) { + e.preventDefault(); + /* No more than set amount */ + if( $(".person:visible").length == 4) { + return; + } + $(this).parent().next().fadeIn({ complete: update_employee_ages }); + }); + /* remove html for individual employee risk */ + $(".individual-pricing-container").on('click', "[data-remove-employee]", function(e) { + e.preventDefault(); + /* At least 1 */ + if( $(".person:visible").length == 1) { + return; + } + $(this).parent().fadeOut({ complete: update_employee_ages }); + }); + + /* Close modal on answer */ + $('[data-key="has_exisiting_insurance"]').on('click', function() { + $("#modal-has-existing-insurance").foundation('reveal', 'close'); + }); + }); + } +}); diff --git a/static/dist/scripts/slide_edit.js b/static/dist/scripts/slide_edit.js new file mode 100644 index 0000000..de812fd --- /dev/null +++ b/static/dist/scripts/slide_edit.js @@ -0,0 +1,276 @@ +$(function() { + /* Save part urls + * Ref: urls.py */ + var urls = { + slide_part_save: '/api/slide/part/', + slide_title_save: '/api/slide/{slide_id}/title/', + slide_part_update: '/api/slide/part/{part_id}/', + slide_part_remove: '/api/slide/part/{part_id}/', + image_save: '/api/image/' + }; + var slide_id = $("#slide").attr('data-slide-id'); + var csrf_token = $.cookie('csrftoken'); + + /* Editor fields */ + var elements = document.querySelectorAll('[data-type="text"], [data-type="html"], [data-type="wysihtml5"]'); + var mediumOptions = { + buttons: ['bold', 'italic', 'header1', 'header2', 'quote', 'anchor', 'unorderedlist', 'orderedlist', 'removeFormat'] + }; + var editor = new MediumEditor(elements, mediumOptions); + editor.subscribe('blur', function(event, el) { + var type = $(el).attr('data-type'); + var name = $(el).attr('data-name'); + var url = $(el).attr('data-url'); + var pk = $(el).attr('data-pk'); + var method = 'POST'; + + if (pk.length > 0 && name != 'slide-title') { + url = urls.slide_part_update.replace('{part_id}', pk); + method = 'PUT'; + } + + var value = el.innerHTML; + if(type == 'text') { + value = el.textContent; + } + var data = { + slide_id: slide_id, + pk: pk, + name: name, + value: value + }; + $.ajax({ + method: method, + headers: { + 'X-CSRFToken': csrf_token + }, + type: 'POST', + url: url, + data: JSON.stringify(data), + contentType : 'application/json' + }).done(function() { + // TODO set pk on part + // $('[data-name="part-' + response.part_created_name + '"]').attr('data-pk', response.part_created_pk); + }).fail(function() { + console.log("boo"); + }); + + }); + $('[data-type="dynamic"]').on('changed', function(e) { + /* Delete part */ + if($(this).attr('data-part-remove')) { + var that = this; + $.ajax({ + url: urls.slide_part_remove.replace('{part_id}', $(this).attr('data-pk')), + method: 'DELETE', + headers: { + 'X-CSRFToken': csrf_token + }, + success: function(response, newValue) { + $(that).removeAttr('data-part-remove'); + $(that).attr('data-pk', ''); + } + }); + return; + } + /* Create or update part */ + var value = ''; + var type = ''; + + if($(this).find('img').length) { + value = $($(this).find('img')[0]).attr('data-pk'); + type = 'image'; + } + else if($(this).find('[data-graph-pk]').length) { + value = $($(this).find('[data-graph-pk]')[0]).attr('data-graph-pk'); + type = 'graph'; + } + else { + console.log("Could not determine Part-type."); + return; + } + + var slide_pk = $(this).attr('data-pk'); + var url = urls.slide_part_save; + var method = 'POST'; + + if (slide_pk.length > 0) { + url = urls.slide_part_update.replace('{part_id}', slide_pk); + method = 'PUT'; + } + + $.ajax({ + url: url, + method: method, + dataType: 'json', + data: { + name: $(this).attr('data-name'), + value: value, + type: type, + slide_id: $("#slide").attr('data-slide-id'), + href: $(this).find('a').attr('href') + }, + headers: { + 'X-CSRFToken': csrf_token + }, + success: function(response, newValue) { + if(response !== undefined && response.part_name && response.part_pk) { + $('[data-name="part-' + response.part_name + '"]').attr('data-pk', response.part_pk); + } + } + }); + }); + + /* + * Gallery + */ + // Ref: https://github.com/blueimp/jQuery-File-Upload + // https://github.com/blueimp/jQuery-File-Upload/wiki/Options + $('#id_file').fileupload({ + dataType: 'json', + url: urls.image_save, + done: function(e, data) { + // add image in gallery + $(".gallery ul").prepend('
  • '+ data.result.name +'
  • '); + // click event + $(".gallery ul li:first-child").click(function (e) { + $(this).siblings().removeClass("selected"); + $(this).toggleClass("selected"); + }); + $("#progress .bar").fadeOut('slow'); + }, + fail: function(e, data) { + console.log("Failed uploading file: ",e, data); + }, + headers: { + 'X-CSRFToken': csrf_token, + 'cache-control': 'no-cache' + }, + send: function(e, data) { + $('#progress .bar').css('width', '0%'); + $("#progress .bar").show(); + }, + progressall: function (e, data) { + var progress = parseInt(data.loaded / data.total * 100, 10); + $('#progress .bar').css( + 'width', + progress + '%' + ); + } + }); + /* Green select */ + $(".image-select").not(".placeholder").click(function (e) { + $(this).siblings().removeClass("selected"); + $(this).toggleClass("selected"); + + }); + /* Insert image */ + $('[data-type="dynamic"]').each(function(i, el) { + /* Insert image-button */ + var button_area = '
    '; + var image_button = ''; + $(el).wrap('
    '); + $(el).after(button_area); + $('[data-buttons-for="'+ $(el).attr('data-name') +'"]').append(image_button); + }); + + $('[data-reveal-id="gallery-modal"]').click( function(e) { + /* Store where to but the image from the modal in the modal */ + var replacing = $(this).attr('data-replace'); + $(".image-insert-btn").attr('data-replacing', replacing); + }); + $(".image-insert-btn").click(function(e) { + var img = $(".gallery .selected img"); + if(!img.length) { + // nothing selected + return; + } + var replacing = $(this).attr('data-replacing'); + var part = $('[data-name="'+ replacing +'"]'); + part.html(''); + part.find('img').attr('data-pk', img.attr('data-pk')); + part.trigger('changed'); + $("#gallery-modal").foundation('reveal', 'close'); + $('.image-select').removeClass("selected"); + }); + /* DELETE image part */ + $("[data-remove-image]").click(function(e) { + var replacing = $('.image-insert-btn').attr('data-replacing'); + var part = $('[data-name="'+ replacing +'"]'); + part.attr('data-part-remove','1'); + part.html(''); + part.trigger('changed'); + $('.image-select').removeClass("selected"); + $("#gallery-modal").foundation('reveal', 'close'); + }); + + /* Link between slides */ + /* ...for "dynamic" areas */ + $('[data-type="dynamic"]').each(function(i, el) { + /* Insert link-button on images */ + var last_button = $(el).siblings().find("a:last-child"); + last_button.after(''); + }); + + /* Set element target on modal */ + $('[data-url-target]').click( function(e) { + var target = $(this).attr('data-url-target'); + if(!$('[data-name="' + target + '"]').find('img').length) { + /* if there is no image, dont link to nothing */ + e.stopPropagation(); + return; + } + $(".modal-links").attr('data-wrapping', target); + }); + + $("[data-is-slide-link]").click(function(e) { + e.preventDefault(); + if($(this).attr('data-get-value-from-id')) { + /* Insert own link via input-field */ + var input_id = $(this).attr('data-get-value-from-id'); + $(this).attr('href', $("#"+input_id).val()); + } + var link = $(this).attr('href'); + var wrapping = $(".modal-links").attr('data-wrapping'); + var el_target = $('[data-name="'+ wrapping +'"]'); + // replace href in targets children if it exists + var potential_link = el_target.children(); + if(potential_link.is('a')) { + potential_link.attr('href',link); + } else { + el_target.find('img').wrap(''); + } + el_target.trigger('changed'); + $(".modal-links").foundation('reveal', 'close'); + }); + + /* Graphs - sticks in divs with data-type=dynamic */ + $('[data-type="dynamic"]').each(function(i, el) { + /* Insert link-button on images */ + var last_button = $(el).siblings().find("a:last-child"); + last_button.after(''); + + /* Set element target on modal */ + $('[data-target="'+ $(el).attr('data-name') +'"]').click( function(e) { + var target = $(this).attr('data-target'); + $(".modal-graph").attr('data-graph-target', target); + }); + }); + + $("[data-is-graph] a").click(function(e) { + e.preventDefault(); + var part_name = $('[data-graph-target]').attr('data-graph-target'); + var graph = $(this).parent(); + var part = $('[data-name="'+ part_name +'"]'); + var html = graph.find('[data-graph-html-copy]')[0].outerHTML; + part.html(html); + part.find('[data-graph-slug]').graph('load'); + part.trigger('changed'); + $(".modal-graph").foundation('reveal', 'close'); + }); + + /* Load graphs initially */ + $('.template [data-graph-slug]').graph('load'); + $('.modal-graph [data-graph-slug]').graph('load', {width: 300, height: 200}); + +}); diff --git a/static/dist/scripts/slides.js b/static/dist/scripts/slides.js new file mode 100644 index 0000000..92a10dc --- /dev/null +++ b/static/dist/scripts/slides.js @@ -0,0 +1,440 @@ +$(document).ready( function() { + var all_icons = $("[data-section-icon]").map(function() { + return $(this).attr('data-section-icon'); + }).get(); + all_icons = _.uniq(all_icons).join(" "); + + function update_title_bar( event ) { + if($(event.currentSlide).is('[data-section-title-hidden]') ) { + $(".title-bar").css('opacity', '0'); + } else { + $(".title-bar").css('opacity', '1'); + } + // event.previousSlide, event.currentSlide, event.indexh, event.indexv + var title = $(event.currentSlide).attr('data-section-title') || ""; + /* Only update when title has changed */ + if($(".title-bar .title span:first").text() !== title) { + $(""+title+"").hide().appendTo(".title-bar .title").fadeIn("normal"); + $(".title-bar .title span:not(:last)").fadeOut("normal", function() { + $(this).remove(); + }); + } + + var edit_url = $(event.currentSlide).attr('data-edit-url'); + $(".title-bar a.title").attr('href', edit_url); // Only update if a is found + + var icon = $(event.currentSlide).attr('data-section-icon') || ""; + if( !$(".title-bar .title i").hasClass(icon) ) { + $(".title-bar .title i") + .removeClass(all_icons) + .addClass(icon); +  } + } + /* Slides: with "wheel" */ + function wheel_toggle_slides(el) { + $("[data-wheel-order]").removeClass('active'); + $(el).addClass('active'); + var order = $(el).attr('data-wheel-order'); + var related = $('[data-wheel-order="' + order +'"]').not('.wheel-image'); + related.addClass('active'); + $('.wheel-text [data-type="wysihtml5"]').hide(); + related.show(); + } + $(".top-bar .links a").click(function() { + $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); + }); + + /* Presentation? */ + if( $('.page-presentation-play').length) { + /* Initialize reveal.js */ + Reveal.initialize({ + // Display controls in the bottom right corner + controls: true, + // Display a presentation progress bar + progress: true, + // Push each slide change to the browser history + history: true, + // Enable keyboard shortcuts for navigation + keyboard: true, + // Enable the slide overview mode + overview: false, + // Vertical centering of slides + center: false, + // Enables touch navigation on devices with touch input + touch: true, + // Loop the presentation + loop: false, + // Change the presentation direction to be RTL + rtl: false, + // Number of milliseconds between automatically proceeding to the + // next slide, disabled when set to 0, this value can be overwritten + // by using a data-autoslide attribute on your slides + autoSlide: 0, + // Enable slide navigation via mouse wheel + mouseWheel: false, + // Apply a 3D roll to links on hover + rollingLinks: false, + // Transition style + transition: 'linear', // default/cube/page/concave/zoom/linear/fade/none + // Factor of the display size that should remain empty around the content + margin: 0.15, + // The "normal" size of the presentation, aspect ratio will be preserved + // when the presentation is scaled to fit different resolutions. Can be + // specified using percentage units. + //width: 960, + //height: 700, + width: 768, // Note: Could set this to 100% and make presentation content responsive instead of using zoom; + height: 576, + minScale: 0.2, + maxScale: 1 + // FIXME: use user agent / device width ? + }); + + + Reveal.addEventListener( 'ready', function(event) { + /* On small screen? disable transitions */ + var small_screen = $(window).width() < 480; + if( small_screen ) { + Reveal.configure({ transition: 'none' }); + } + + update_title_bar(event); + + /* Load chart if one exists on current slide (animate) */ + if( $(event.currentSlide).find('[class^="graph-"]').length) { + $(event.currentSlide).find('[class^="graph-"]').graph('load'); + } + + }); + + Reveal.addEventListener( 'slidechanged', function( event ) { + + /* Update title bar */ + update_title_bar(event); + + /* Chart slide - Wait until it is current to load (animate) */ + if( $(event.currentSlide).find('[class^="graph-"]').length) { + $(event.currentSlide).find('[class^="graph-"]').graph('load'); + } + + /* Disable touch on specific slides*/ + if( $(event.currentSlide).find("[data-swipe-disable]").length ) { + Reveal.configure({ touch: false }); + } else { + Reveal.configure({ touch: true }); + } + + /* Search previous slide for video elements and pause them */ + $(event.previousSlide).find("video").each(function(i, el) { + el.pause(); + }); + + /* Setup/Reset wheel state on wheel-slide enter */ + if( $(event.currentSlide).find('.wheel').length) { + $('.wheel-text [data-wheel-order]').hide(); + $('[data-wheel-order]').removeClass('active'); + $('[data-wheel-order="1"]').addClass('active').show(); + } + } ); + + + $(".wheel-images .wheel-image .trigger, .wheel-head .trigger").on('mousedown', function(e) { + wheel_toggle_slides(this); + }); + /* Hover fix for touch: Only bind on hover for non-touch devices */ + $(".no-touch .wheel-images .wheel-image .trigger, .no-touch .wheel-head .trigger").on('mouseenter', function(e) { + wheel_toggle_slides(this); + }); + } + + /* Swipebox */ + $('a.fancybox').swipebox(); + + /* Video */ + $('video').mediaelementplayer({ + success: function (mediaElement, domObject) { + /* Track video plays */ + mediaElement.addEventListener( + 'play', + function(e) { + mixpanel.track("Played video."); + }, + false); + } + }); + + /* Skip home if you are on the play-slide */ + $("[data-goto-first-slide]").on('click', function(e) { + e.preventDefault(); + $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); + Reveal.slide(0, 0); + }); + + + /* Slide: Sick cost calculator */ + function get_salary() { + var industry_pk = parseInt($("#id_calc_industry").val(), 10); + /* Note: stb_industries is defined in the calculator.html-template */ + var industry = _.findWhere(stb_industries, {pk: industry_pk}); + + if(industry === undefined) { + return 0; + } + return industry.fields.yearly_salary; + } + function calc_cost(sick_rate, num_staff) { + var salary = get_salary(); + sick_rate = sick_rate / 100.0; // percent + return sick_rate * num_staff * salary; + } + /* Format norwegian */ + function format_number_norwegian(num) { + num = num.toString(); + var formatted_str = ""; + /* Add spaces backwards every third char */ + for(var i=0; i< num.length; i++){ + if(i % 3 === 0) { + formatted_str += " "; + } + formatted_str += num.charAt(num.length-i-1); + } + /* reverse the string */ + return formatted_str.split("").reverse().join(""); + } + function calc_savings(sick_rate, goal_sick_rate, num_staff) { + var current = calc_cost(sick_rate, num_staff); + var goal = calc_cost(goal_sick_rate, num_staff); + return current - goal; //total savings per year + } + function recalc() { + /* Get data */ + var num_staff = parseInt($(".num-staff").slider('value'), 10); + var sick_rate = $(".sick-rate").slider('value'); + var sick_rate_float = parseFloat(sick_rate); + var goal_sick_rate = $(".goal-sick-rate").slider('value'); + var goal_sick_rate_float = parseFloat(goal_sick_rate); + /* Calculate */ + var cost = calc_cost(sick_rate_float, num_staff); + cost = parseInt(Math.round( cost / 100), 10) * 100; + var savings = calc_savings(sick_rate_float, goal_sick_rate, num_staff); + savings = parseInt(Math.round( savings / 1000), 10) * 1000; + /* Output data */ + $("[data-calc-staff]").text(num_staff); + $("[data-calc-rate]").text(Math.round(sick_rate_float * 10) / 10); + $("[data-calc-goal-rate]").text(Math.round(goal_sick_rate_float * 10) / 10); + $("[data-calc-savings]").text(format_number_norwegian(savings)); + $("[data-calc-savings-employee]").text(format_number_norwegian(Math.round(savings / num_staff))); + /* cost */ + $("[data-calc-cost]").text(format_number_norwegian(cost)); + $("[data-calc-cost-employee]").text(format_number_norwegian(Math.round(cost / num_staff))); + + } + if($(".sick-cost-calculator").length) { + $( ".num-staff" ).slider({ + animate: "fast", + value: 600, + min: 1, + max: 2000, + step: 1, + stop: recalc, + slide: recalc + }); + $( ".sick-rate" ).slider({ + animate: "fast", + value: 10.2, + min: 1, + max: 15, + step: 0.2, + stop: recalc, + slide: recalc + }); + $( ".goal-sick-rate" ).slider({ + animate: "fast", + value: 5, + min: 1, + max: 15, + step: 0.2, + stop: recalc, + slide: recalc + }); + $(".sick-cost-industry-form").on('change', function(e) { + recalc(); + }); + + recalc(); // Initial calc + + /* Workaround for slider not working on touch devices + * Click/touch and change */ + $("[data-calc-staff], [data-calc-rate], [data-calc-goal-rate]").on('click', function(e) { + $(".set-value-modal").attr('data-updating', $(this).attr('data-updating')); + var old_value = $(this).text(); + $("input[name=set-value]").val(old_value); + $(".set-value-modal").foundation('reveal', 'open'); + }); + $(".set-value-button").on('click', function(e) { + var new_value = $("input[name=set-value]").val(); + var key = "#" + $(".set-value-modal").attr('data-updating'); + $( key ).slider({ value: parseFloat(new_value)}); + $(".set-value-modal").foundation('reveal', 'close'); + recalc(); + }); + } + + /* Slide: Public treatment comparison */ + if($(".public-treatment-comparison").length) { +        var options = { +     valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] +        }; + +        var featureList = new List('treatment-list', options); + featureList.sort('waittime', { asc: false }); + +        $('.filter-region, .filter-diagnose').change(function() { +            featureList.filter(function(item) { + var diagnose = $('.filter-diagnose').val(); + var region = $(".filter-region").val(); +                return (item.values().region == region || region == "Alle") && item.values().diagnose == diagnose; +            }); +            return false; +        }); +        $('.filter-none').click(function() { +            featureList.filter(); +            return false; +        }); + $(".filter-diagnose").trigger('change'); + } + + function init_treatment_map() { + // mapbox.com: nikolaik.map-hyrf1sef + var tile_url = 'http://{s}.tiles.mapbox.com/v3/nikolaik.map-hyrf1sef/{z}/{x}/{y}.png'; + var tiles = L.tileLayer(tile_url, {maxZoom: 17, minZoom: 4}); + var latlng = L.latLng(65.57, 12.56); + + var map = L.map('treament-network-map', {center: latlng, zoom: 4, layers: [tiles]}); + + var markers = L.markerClusterGroup({ showCoverageOnHover: false}); + /* Marker icon style */ + var static_url = $('meta[name="x-django-static-url"]').attr('content'); + var icon = L.icon({ + iconUrl: static_url + 'dist/images/storebrand_map_marker.png', + iconSize: new L.Point(35, 35), + iconAnchor: new L.Point(35, 35), + popupAnchor: new L.Point(-17.5, -35), + shadowUrl: '', + shadowSize: new L.Point(0, 0), + }); + + /* Add specialist markers */ + var _url = 'http://zeppelin.brill.no/blifrisk/data/no.json'; + $.getJSON(_url, function(data) { + _.each(data.specialists, function(s, i) { + if(s.position) { + var marker = L.marker(new L.LatLng(s.position.lat, s.position.lng), { title: s.name, icon: icon }); + marker.bindPopup("

    "+ s.name +"

    "+ s.address +"
    "+ s.postalCode +" "+ s.city +"

    "); + markers.addLayer(marker); + } + }); + map.addLayer(markers); + }); + } + /* Slide: Treatment locations map */ + if($(".treament-network-map").length) { + + /* Load the treatment map when the slide comes in to view when in presentation mode */ + if (window.Reveal && !$(".page-slide-edit").length) { + var handler = function(event) { + if($(event.currentSlide).find(".treament-network-map").length) { + init_treatment_map(); + Reveal.removeEventListener( 'slidechanged', handler, false); // run only once + } + }; + Reveal.addEventListener( 'slidechanged', handler); + Reveal.addEventListener( 'ready', function(event) { + if($(event.currentSlide).find(".treament-network-map").length) { + /* Load map */ + init_treatment_map(); + } + }); + } else { + init_treatment_map(); + } + + } + /* Placeholder polyfill for IE9 */ + placeholderSupport = ("placeholder" in document.createElement("input")); + if(!placeholderSupport){ + //This browser does not support the placeholder attribute + //use javascript instead + $('[placeholder]').focus(function() { + var input = $(this); + if (input.val() === input.attr('placeholder')) { + input.val(''); + input.removeClass('placeholder'); + } + }).blur(function() { + var input = $(this); + if (input.val() === '' || input.val() === input.attr('placeholder')) { + input.addClass('placeholder'); + input.val(input.attr('placeholder')); + } + }).blur().parents('form').submit(function() { + $(this).find('[placeholder]').each(function() { + var input = $(this); + if (input.val() === input.attr('placeholder')) { + input.val(''); + } + }); + }); + } + /* Highcarts graph theme */ + Highcharts.theme = { + colors: ['#da291c', '#425563', '#ed786f'], + chart: { + backgroundColor: null + }, + credits: { + enabled: false + }, + title: { + style: { + color: '#1e394d', + font: 'bold 16px "SignaColumn", Helvetica, Arial, sans-serif' + } + }, + subtitle: { + style: { + color: '#425563', + font: 'bold 12px "SignaColumn", Helvetica, Arial, sans-serif' + } + }, + yAxis: { + title: { + style: { + color: 'gray' + } + } + }, + xAxis: { + title: { + style: { + color: 'gray' + } + } + }, + legend: { + itemStyle: { + font: '9pt "SignaColumn", Helvetica, Arial, sans-serif', + color: 'black' + }, + itemHoverStyle:{ + color: 'gray' + } + }, + exporting: { + enabled: false + } + }; + + // Apply the theme + Highcharts.setOptions(Highcharts.theme); +}); diff --git a/static/dist/scripts/vendor.js b/static/dist/scripts/vendor.js new file mode 100644 index 0000000..3c13698 --- /dev/null +++ b/static/dist/scripts/vendor.js @@ -0,0 +1,19779 @@ +/*! + * jQuery JavaScript Library v2.1.4 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-28T16:01Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Support: Firefox 18+ +// Can't be in strict mode, several libs including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// + +var arr = []; + +var slice = arr.slice; + +var concat = arr.concat; + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + version = "2.1.4", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray, + + isWindow: function( obj ) { + return obj != null && obj === obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isPlainObject: function( obj ) { + // Not plain objects: + // - Any object or value whose internal [[Class]] property is not "[object Object]" + // - DOM nodes + // - window + if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.constructor && + !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { + return false; + } + + // If the function hasn't returned already, we're confident that + // |obj| is a plain object, created by {} or constructed with new Object + return true; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + // Support: Android<4.0, iOS<6 (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + globalEval: function( code ) { + var script, + indirect = eval; + + code = jQuery.trim( code ); + + if ( code ) { + // If the code includes a valid, prologue position + // strict mode pragma, execute code by injecting a + // script tag into the document. + if ( code.indexOf("use strict") === 1 ) { + script = document.createElement("script"); + script.text = code; + document.head.appendChild( script ).parentNode.removeChild( script ); + } else { + // Otherwise, avoid the DOM node creation, insertion + // and removal by using an indirect global eval + indirect( code ); + } + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Support: IE9-11+ + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: Date.now, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + len = this.length, + ret = [], + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Support: Blackberry 4.6 + // gEBID returns nodes no longer in the document (#6963) + if ( elem && elem.parentNode ) { + // Inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; + }, + + sibling: function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter(function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return elem.contentDocument || jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.unique( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // Add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // If we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * The ready event handler and self cleanup method + */ +function completed() { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + jQuery.ready(); +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // We once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + } else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + } + } + return readyList.promise( obj ); +}; + +// Kick off the DOM ready check even if the user does not +jQuery.ready.promise(); + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + len ? fn( elems[0], key ) : emptyGet; +}; + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( owner ) { + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + /* jshint -W018 */ + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + +function Data() { + // Support: Android<4, + // Old WebKit does not have Object.preventExtensions/freeze method, + // return new empty object instead with no [[set]] accessor + Object.defineProperty( this.cache = {}, 0, { + get: function() { + return {}; + } + }); + + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; +Data.accepts = jQuery.acceptData; + +Data.prototype = { + key: function( owner ) { + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return the key for a frozen object. + if ( !Data.accepts( owner ) ) { + return 0; + } + + var descriptor = {}, + // Check if the owner object already has a cache key + unlock = owner[ this.expando ]; + + // If not, create one + if ( !unlock ) { + unlock = Data.uid++; + + // Secure it in a non-enumerable, non-writable property + try { + descriptor[ this.expando ] = { value: unlock }; + Object.defineProperties( owner, descriptor ); + + // Support: Android<4 + // Fallback to a less secure definition + } catch ( e ) { + descriptor[ this.expando ] = unlock; + jQuery.extend( owner, descriptor ); + } + } + + // Ensure the cache object + if ( !this.cache[ unlock ] ) { + this.cache[ unlock ] = {}; + } + + return unlock; + }, + set: function( owner, data, value ) { + var prop, + // There may be an unlock assigned to this node, + // if there is no entry for this "owner", create one inline + // and set the unlock as though an owner entry had always existed + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + // Handle: [ owner, key, value ] args + if ( typeof data === "string" ) { + cache[ data ] = value; + + // Handle: [ owner, { properties } ] args + } else { + // Fresh assignments by object are shallow copied + if ( jQuery.isEmptyObject( cache ) ) { + jQuery.extend( this.cache[ unlock ], data ); + // Otherwise, copy the properties one-by-one to the cache object + } else { + for ( prop in data ) { + cache[ prop ] = data[ prop ]; + } + } + } + return cache; + }, + get: function( owner, key ) { + // Either a valid cache is found, or will be created. + // New caches will be created and the unlock returned, + // allowing direct access to the newly created + // empty data object. A valid owner object must be provided. + var cache = this.cache[ this.key( owner ) ]; + + return key === undefined ? + cache : cache[ key ]; + }, + access: function( owner, key, value ) { + var stored; + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ((key && typeof key === "string") && value === undefined) ) { + + stored = this.get( owner, key ); + + return stored !== undefined ? + stored : this.get( owner, jQuery.camelCase(key) ); + } + + // [*]When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, name, camel, + unlock = this.key( owner ), + cache = this.cache[ unlock ]; + + if ( key === undefined ) { + this.cache[ unlock ] = {}; + + } else { + // Support array or space separated string of keys + if ( jQuery.isArray( key ) ) { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = key.concat( key.map( jQuery.camelCase ) ); + } else { + camel = jQuery.camelCase( key ); + // Try the string as a key before any manipulation + if ( key in cache ) { + name = [ key, camel ]; + } else { + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + name = camel; + name = name in cache ? + [ name ] : ( name.match( rnotwhite ) || [] ); + } + } + + i = name.length; + while ( i-- ) { + delete cache[ name[ i ] ]; + } + } + }, + hasData: function( owner ) { + return !jQuery.isEmptyObject( + this.cache[ owner[ this.expando ] ] || {} + ); + }, + discard: function( owner ) { + if ( owner[ this.expando ] ) { + delete this.cache[ owner[ this.expando ] ]; + } + } +}; +var data_priv = new Data(); + +var data_user = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + data_user.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend({ + hasData: function( elem ) { + return data_user.hasData( elem ) || data_priv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return data_user.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + data_user.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to data_priv methods, these can be deprecated. + _data: function( elem, name, data ) { + return data_priv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + data_priv.remove( elem, name ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = data_user.get( elem ); + + if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + data_priv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + data_user.set( this, key ); + }); + } + + return access( this, function( value ) { + var data, + camelKey = jQuery.camelCase( key ); + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + // Attempt to get data from the cache + // with the key as-is + data = data_user.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to get data from the cache + // with the key camelized + data = data_user.get( elem, camelKey ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, camelKey, undefined ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each(function() { + // First, attempt to store a copy or reference of any + // data that might've been store with a camelCased key. + var data = data_user.get( this, camelKey ); + + // For HTML5 data-* attribute interop, we have to + // store property names with dashes in a camelCase form. + // This might not apply to all properties...* + data_user.set( this, camelKey, value ); + + // *... In the case of properties that might _actually_ + // have dashes, we need to also store a copy of that + // unchanged property. + if ( key.indexOf("-") !== -1 && data !== undefined ) { + data_user.set( this, key, value ); + } + }); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each(function() { + data_user.remove( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = data_priv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray( data ) ) { + queue = data_priv.access( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return data_priv.get( elem, key ) || data_priv.access( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + data_priv.remove( elem, [ type + "queue", key ] ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = data_priv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Safari<=5.1 + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Safari<=5.1, Android<4.2 + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<=11+ + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; +})(); +var strundefined = typeof undefined; + + + +support.focusinBubbles = "onfocusin" in window; + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.get( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = data_priv.hasData( elem ) && data_priv.get( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + data_priv.remove( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, j, ret, matched, handleObj, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or 2) have namespace(s) + // a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, matches, sel, handleObj, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: Cordova 2.5 (WebKit) (#13255) + // All events should have a target; Cordova deviceready doesn't + if ( !event.target ) { + event.target = document; + } + + // Support: Safari 6.0+, Chrome<28 + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + this.focus(); + return false; + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } +}; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: Android<4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && e.preventDefault ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && e.stopPropagation ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +// Support: Chrome 15+ +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// Support: Firefox, Chrome, Safari +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + data_priv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = data_priv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + data_priv.remove( doc, fix ); + + } else { + data_priv.access( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +var + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + + // Support: IE9 + option: [ 1, "" ], + + thead: [ 1, "", "
    " ], + col: [ 2, "", "
    " ], + tr: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + _default: [ 0, "", "" ] + }; + +// Support: IE9 +wrapMap.optgroup = wrapMap.option; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: 1.x compatibility +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + + if ( match ) { + elem.type = match[ 1 ]; + } else { + elem.removeAttribute("type"); + } + + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + data_priv.set( + elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) + ); + } +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( data_priv.hasData( src ) ) { + pdataOld = data_priv.access( src ); + pdataCur = data_priv.set( dest, pdataOld ); + events = pdataOld.events; + + if ( events ) { + delete pdataCur.handle; + pdataCur.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( data_user.hasData( src ) ) { + udataOld = data_user.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + data_user.set( dest, udataCur ); + } +} + +function getAll( context, tag ) { + var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : + context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : + []; + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], ret ) : + ret; +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = jQuery.contains( elem.ownerDocument, elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var elem, tmp, tag, wrap, contains, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + // Support: QtWebKit, PhantomJS + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: QtWebKit, PhantomJS + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; + }, + + cleanData: function( elems ) { + var data, elem, type, key, + special = jQuery.event.special, + i = 0; + + for ( ; (elem = elems[ i ]) !== undefined; i++ ) { + if ( jQuery.acceptData( elem ) ) { + key = elem[ data_priv.expando ]; + + if ( key && (data = data_priv.cache[ key ]) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + if ( data_priv.cache[ key ] ) { + // Discard any remaining `private` data + delete data_priv.cache[ key ]; + } + } + } + // Discard any remaining `user` data + delete data_user.cache[ elem[ data_user.expando ] ]; + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each(function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + }); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[ 0 ], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + // Support: QtWebKit + // jQuery.merge because push.apply(_, arraylike) throws + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); + } + } + } + } + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: QtWebKit + // .get() because push.apply(_, arraylike) throws + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optimization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "