diff --git a/Gruntfile.js b/Gruntfile.js
index bcbe53c3..23680f6e 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -51,7 +51,8 @@ module.exports = function(grunt) {
'./public/vendor/jquery-form/jquery.form.js',
'./public/vendor/humane-js/humane.js',
'./public/vendor/RRSSB/js/rrssb.js',
- './public/vendor/curioussolutions-datetimepicker/dist/DateTimePicker.js',
+ './public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.js',
+ './public/vendor/curioussolutions-datetimepicker/dist/DateTimePicker.js',
'./public/assets/javascript/app.js'
],
dest: './public/assets/javascript/backend.js',
diff --git a/bower.json b/bower.json
index 540e7cc1..f0ee9816 100644
--- a/bower.json
+++ b/bower.json
@@ -25,7 +25,8 @@
"RRSSB": "~1.6.0",
"jquery-backstretch": "~2.0.4",
"fontawesome": "~4.2.0",
- "simplemde": "~1.8.1"
+ "simplemde": "~1.8.1",
+ "bootstrap-touchspin": "~3.0.1"
},
"resolutions": {
"jquery": ">=1.5"
diff --git a/public/assets/javascript/backend.js b/public/assets/javascript/backend.js
index 34d09eeb..983b4b72 100644
--- a/public/assets/javascript/backend.js
+++ b/public/assets/javascript/backend.js
@@ -5212,6 +5212,684 @@ function log() {
window.rrssbInit = rrssbInit;
})(window, jQuery);
+;(function($) {
+ 'use strict';
+
+ var _currentSpinnerId = 0;
+
+ function _scopedEventName(name, id) {
+ return name + '.touchspin_' + id;
+ }
+
+ function _scopeEventNames(names, id) {
+ return $.map(names, function(name) {
+ return _scopedEventName(name, id);
+ });
+ }
+
+ $.fn.TouchSpin = function(options) {
+
+ if (options === 'destroy') {
+ this.each(function() {
+ var originalinput = $(this),
+ originalinput_data = originalinput.data();
+ $(document).off(_scopeEventNames([
+ 'mouseup',
+ 'touchend',
+ 'touchcancel',
+ 'mousemove',
+ 'touchmove',
+ 'scroll',
+ 'scrollstart'], originalinput_data.spinnerid).join(' '));
+ });
+ return;
+ }
+
+ var defaults = {
+ min: 0,
+ max: 100,
+ initval: '',
+ step: 1,
+ decimals: 0,
+ stepinterval: 100,
+ forcestepdivisibility: 'round', // none | floor | round | ceil
+ stepintervaldelay: 500,
+ verticalbuttons: false,
+ verticalupclass: 'glyphicon glyphicon-chevron-up',
+ verticaldownclass: 'glyphicon glyphicon-chevron-down',
+ prefix: '',
+ postfix: '',
+ prefix_extraclass: '',
+ postfix_extraclass: '',
+ booster: true,
+ boostat: 10,
+ maxboostedstep: false,
+ mousewheel: true,
+ buttondown_class: 'btn btn-default',
+ buttonup_class: 'btn btn-default',
+ buttondown_txt: '-',
+ buttonup_txt: '+'
+ };
+
+ var attributeMap = {
+ min: 'min',
+ max: 'max',
+ initval: 'init-val',
+ step: 'step',
+ decimals: 'decimals',
+ stepinterval: 'step-interval',
+ verticalbuttons: 'vertical-buttons',
+ verticalupclass: 'vertical-up-class',
+ verticaldownclass: 'vertical-down-class',
+ forcestepdivisibility: 'force-step-divisibility',
+ stepintervaldelay: 'step-interval-delay',
+ prefix: 'prefix',
+ postfix: 'postfix',
+ prefix_extraclass: 'prefix-extra-class',
+ postfix_extraclass: 'postfix-extra-class',
+ booster: 'booster',
+ boostat: 'boostat',
+ maxboostedstep: 'max-boosted-step',
+ mousewheel: 'mouse-wheel',
+ buttondown_class: 'button-down-class',
+ buttonup_class: 'button-up-class',
+ buttondown_txt: 'button-down-txt',
+ buttonup_txt: 'button-up-txt'
+ };
+
+ return this.each(function() {
+
+ var settings,
+ originalinput = $(this),
+ originalinput_data = originalinput.data(),
+ container,
+ elements,
+ value,
+ downSpinTimer,
+ upSpinTimer,
+ downDelayTimeout,
+ upDelayTimeout,
+ spincount = 0,
+ spinning = false;
+
+ init();
+
+
+ function init() {
+ if (originalinput.data('alreadyinitialized')) {
+ return;
+ }
+
+ originalinput.data('alreadyinitialized', true);
+ _currentSpinnerId += 1;
+ originalinput.data('spinnerid', _currentSpinnerId);
+
+
+ if (!originalinput.is('input')) {
+ console.log('Must be an input.');
+ return;
+ }
+
+ _initSettings();
+ _setInitval();
+ _checkValue();
+ _buildHtml();
+ _initElements();
+ _hideEmptyPrefixPostfix();
+ _bindEvents();
+ _bindEventsInterface();
+ elements.input.css('display', 'block');
+ }
+
+ function _setInitval() {
+ if (settings.initval !== '' && originalinput.val() === '') {
+ originalinput.val(settings.initval);
+ }
+ }
+
+ function changeSettings(newsettings) {
+ _updateSettings(newsettings);
+ _checkValue();
+
+ var value = elements.input.val();
+
+ if (value !== '') {
+ value = Number(elements.input.val());
+ elements.input.val(value.toFixed(settings.decimals));
+ }
+ }
+
+ function _initSettings() {
+ settings = $.extend({}, defaults, originalinput_data, _parseAttributes(), options);
+ }
+
+ function _parseAttributes() {
+ var data = {};
+ $.each(attributeMap, function(key, value) {
+ var attrName = 'bts-' + value + '';
+ if (originalinput.is('[data-' + attrName + ']')) {
+ data[key] = originalinput.data(attrName);
+ }
+ });
+ return data;
+ }
+
+ function _updateSettings(newsettings) {
+ settings = $.extend({}, settings, newsettings);
+ }
+
+ function _buildHtml() {
+ var initval = originalinput.val(),
+ parentelement = originalinput.parent();
+
+ if (initval !== '') {
+ initval = Number(initval).toFixed(settings.decimals);
+ }
+
+ originalinput.data('initvalue', initval).val(initval);
+ originalinput.addClass('form-control');
+
+ if (parentelement.hasClass('input-group')) {
+ _advanceInputGroup(parentelement);
+ }
+ else {
+ _buildInputGroup();
+ }
+ }
+
+ function _advanceInputGroup(parentelement) {
+ parentelement.addClass('bootstrap-touchspin');
+
+ var prev = originalinput.prev(),
+ next = originalinput.next();
+
+ var downhtml,
+ uphtml,
+ prefixhtml = '' + settings.prefix + ' ',
+ postfixhtml = '' + settings.postfix + ' ';
+
+ if (prev.hasClass('input-group-btn')) {
+ downhtml = '' + settings.buttondown_txt + ' ';
+ prev.append(downhtml);
+ }
+ else {
+ downhtml = '' + settings.buttondown_txt + ' ';
+ $(downhtml).insertBefore(originalinput);
+ }
+
+ if (next.hasClass('input-group-btn')) {
+ uphtml = '' + settings.buttonup_txt + ' ';
+ next.prepend(uphtml);
+ }
+ else {
+ uphtml = '' + settings.buttonup_txt + ' ';
+ $(uphtml).insertAfter(originalinput);
+ }
+
+ $(prefixhtml).insertBefore(originalinput);
+ $(postfixhtml).insertAfter(originalinput);
+
+ container = parentelement;
+ }
+
+ function _buildInputGroup() {
+ var html;
+
+ if (settings.verticalbuttons) {
+ html = '
' + settings.prefix + ' ' + settings.postfix + '
';
+ }
+ else {
+ html = '' + settings.buttondown_txt + ' ' + settings.prefix + ' ' + settings.postfix + ' ' + settings.buttonup_txt + '
';
+ }
+
+ container = $(html).insertBefore(originalinput);
+
+ $('.bootstrap-touchspin-prefix', container).after(originalinput);
+
+ if (originalinput.hasClass('input-sm')) {
+ container.addClass('input-group-sm');
+ }
+ else if (originalinput.hasClass('input-lg')) {
+ container.addClass('input-group-lg');
+ }
+ }
+
+ function _initElements() {
+ elements = {
+ down: $('.bootstrap-touchspin-down', container),
+ up: $('.bootstrap-touchspin-up', container),
+ input: $('input', container),
+ prefix: $('.bootstrap-touchspin-prefix', container).addClass(settings.prefix_extraclass),
+ postfix: $('.bootstrap-touchspin-postfix', container).addClass(settings.postfix_extraclass)
+ };
+ }
+
+ function _hideEmptyPrefixPostfix() {
+ if (settings.prefix === '') {
+ elements.prefix.hide();
+ }
+
+ if (settings.postfix === '') {
+ elements.postfix.hide();
+ }
+ }
+
+ function _bindEvents() {
+ originalinput.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 38) {
+ if (spinning !== 'up') {
+ upOnce();
+ startUpSpin();
+ }
+ ev.preventDefault();
+ }
+ else if (code === 40) {
+ if (spinning !== 'down') {
+ downOnce();
+ startDownSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ originalinput.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 38) {
+ stopSpin();
+ }
+ else if (code === 40) {
+ stopSpin();
+ }
+ });
+
+ originalinput.on('blur', function() {
+ _checkValue();
+ });
+
+ elements.down.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ if (spinning !== 'down') {
+ downOnce();
+ startDownSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ elements.down.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ stopSpin();
+ }
+ });
+
+ elements.up.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ if (spinning !== 'up') {
+ upOnce();
+ startUpSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ elements.up.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ stopSpin();
+ }
+ });
+
+ elements.down.on('mousedown.touchspin', function(ev) {
+ elements.down.off('touchstart.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ downOnce();
+ startDownSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.down.on('touchstart.touchspin', function(ev) {
+ elements.down.off('mousedown.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ downOnce();
+ startDownSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('mousedown.touchspin', function(ev) {
+ elements.up.off('touchstart.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ upOnce();
+ startUpSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('touchstart.touchspin', function(ev) {
+ elements.up.off('mousedown.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ upOnce();
+ startUpSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('mouseout touchleave touchend touchcancel', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ stopSpin();
+ });
+
+ elements.down.on('mouseout touchleave touchend touchcancel', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ stopSpin();
+ });
+
+ elements.down.on('mousemove touchmove', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ ev.preventDefault();
+ });
+
+ elements.up.on('mousemove touchmove', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ ev.preventDefault();
+ });
+
+ $(document).on(_scopeEventNames(['mouseup', 'touchend', 'touchcancel'], _currentSpinnerId).join(' '), function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.preventDefault();
+ stopSpin();
+ });
+
+ $(document).on(_scopeEventNames(['mousemove', 'touchmove', 'scroll', 'scrollstart'], _currentSpinnerId).join(' '), function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.preventDefault();
+ stopSpin();
+ });
+
+ originalinput.on('mousewheel DOMMouseScroll', function(ev) {
+ if (!settings.mousewheel || !originalinput.is(':focus')) {
+ return;
+ }
+
+ var delta = ev.originalEvent.wheelDelta || -ev.originalEvent.deltaY || -ev.originalEvent.detail;
+
+ ev.stopPropagation();
+ ev.preventDefault();
+
+ if (delta < 0) {
+ downOnce();
+ }
+ else {
+ upOnce();
+ }
+ });
+ }
+
+ function _bindEventsInterface() {
+ originalinput.on('touchspin.uponce', function() {
+ stopSpin();
+ upOnce();
+ });
+
+ originalinput.on('touchspin.downonce', function() {
+ stopSpin();
+ downOnce();
+ });
+
+ originalinput.on('touchspin.startupspin', function() {
+ startUpSpin();
+ });
+
+ originalinput.on('touchspin.startdownspin', function() {
+ startDownSpin();
+ });
+
+ originalinput.on('touchspin.stopspin', function() {
+ stopSpin();
+ });
+
+ originalinput.on('touchspin.updatesettings', function(e, newsettings) {
+ changeSettings(newsettings);
+ });
+ }
+
+ function _forcestepdivisibility(value) {
+ switch (settings.forcestepdivisibility) {
+ case 'round':
+ return (Math.round(value / settings.step) * settings.step).toFixed(settings.decimals);
+ case 'floor':
+ return (Math.floor(value / settings.step) * settings.step).toFixed(settings.decimals);
+ case 'ceil':
+ return (Math.ceil(value / settings.step) * settings.step).toFixed(settings.decimals);
+ default:
+ return value;
+ }
+ }
+
+ function _checkValue() {
+ var val, parsedval, returnval;
+
+ val = originalinput.val();
+
+ if (val === '') {
+ return;
+ }
+
+ if (settings.decimals > 0 && val === '.') {
+ return;
+ }
+
+ parsedval = parseFloat(val);
+
+ if (isNaN(parsedval)) {
+ parsedval = 0;
+ }
+
+ returnval = parsedval;
+
+ if (parsedval.toString() !== val) {
+ returnval = parsedval;
+ }
+
+ if (parsedval < settings.min) {
+ returnval = settings.min;
+ }
+
+ if (parsedval > settings.max) {
+ returnval = settings.max;
+ }
+
+ returnval = _forcestepdivisibility(returnval);
+
+ if (Number(val).toString() !== returnval.toString()) {
+ originalinput.val(returnval);
+ originalinput.trigger('change');
+ }
+ }
+
+ function _getBoostedStep() {
+ if (!settings.booster) {
+ return settings.step;
+ }
+ else {
+ var boosted = Math.pow(2, Math.floor(spincount / settings.boostat)) * settings.step;
+
+ if (settings.maxboostedstep) {
+ if (boosted > settings.maxboostedstep) {
+ boosted = settings.maxboostedstep;
+ value = Math.round((value / boosted)) * boosted;
+ }
+ }
+
+ return Math.max(settings.step, boosted);
+ }
+ }
+
+ function upOnce() {
+ _checkValue();
+
+ value = parseFloat(elements.input.val());
+ if (isNaN(value)) {
+ value = 0;
+ }
+
+ var initvalue = value,
+ boostedstep = _getBoostedStep();
+
+ value = value + boostedstep;
+
+ if (value > settings.max) {
+ value = settings.max;
+ originalinput.trigger('touchspin.on.max');
+ stopSpin();
+ }
+
+ elements.input.val(Number(value).toFixed(settings.decimals));
+
+ if (initvalue !== value) {
+ originalinput.trigger('change');
+ }
+ }
+
+ function downOnce() {
+ _checkValue();
+
+ value = parseFloat(elements.input.val());
+ if (isNaN(value)) {
+ value = 0;
+ }
+
+ var initvalue = value,
+ boostedstep = _getBoostedStep();
+
+ value = value - boostedstep;
+
+ if (value < settings.min) {
+ value = settings.min;
+ originalinput.trigger('touchspin.on.min');
+ stopSpin();
+ }
+
+ elements.input.val(value.toFixed(settings.decimals));
+
+ if (initvalue !== value) {
+ originalinput.trigger('change');
+ }
+ }
+
+ function startDownSpin() {
+ stopSpin();
+
+ spincount = 0;
+ spinning = 'down';
+
+ originalinput.trigger('touchspin.on.startspin');
+ originalinput.trigger('touchspin.on.startdownspin');
+
+ downDelayTimeout = setTimeout(function() {
+ downSpinTimer = setInterval(function() {
+ spincount++;
+ downOnce();
+ }, settings.stepinterval);
+ }, settings.stepintervaldelay);
+ }
+
+ function startUpSpin() {
+ stopSpin();
+
+ spincount = 0;
+ spinning = 'up';
+
+ originalinput.trigger('touchspin.on.startspin');
+ originalinput.trigger('touchspin.on.startupspin');
+
+ upDelayTimeout = setTimeout(function() {
+ upSpinTimer = setInterval(function() {
+ spincount++;
+ upOnce();
+ }, settings.stepinterval);
+ }, settings.stepintervaldelay);
+ }
+
+ function stopSpin() {
+ clearTimeout(downDelayTimeout);
+ clearTimeout(upDelayTimeout);
+ clearInterval(downSpinTimer);
+ clearInterval(upSpinTimer);
+
+ switch (spinning) {
+ case 'up':
+ originalinput.trigger('touchspin.on.stopupspin');
+ originalinput.trigger('touchspin.on.stopspin');
+ break;
+ case 'down':
+ originalinput.trigger('touchspin.on.stopdownspin');
+ originalinput.trigger('touchspin.on.stopspin');
+ break;
+ }
+
+ spincount = 0;
+ spinning = false;
+ }
+
+ });
+
+ };
+
+})(jQuery);
;$.DateTimePicker = $.DateTimePicker || {
name: "DateTimePicker",
@@ -7791,7 +8469,7 @@ $.cf = {
window.Attendize = {
DateFormat: 'dd-MM-yyyy',
- DateTimeFormat: 'dd-MM-yyyy hh:mm:ss',
+ DateTimeFormat: 'dd-MM-yyyy hh:mm',
GenericErrorMessage: 'Whoops!, An unknown error has occurred.'
+ 'Please try again or contact support if the problem persists. '
};
diff --git a/public/assets/stylesheet/application.css b/public/assets/stylesheet/application.css
index 9dfc2541..2ca06a32 100644
--- a/public/assets/stylesheet/application.css
+++ b/public/assets/stylesheet/application.css
@@ -104,4 +104,49 @@ body {
----------------------------------------------------------------------------- */
-.dtpicker-overlay{z-index:2000;display:none;min-width:300px;background:rgba(0,0,0,.2);font-size:12px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dtpicker-mobile{position:fixed;top:0;left:0;width:100%;height:100%}.dtpicker-overlay *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-ms-box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.dtpicker-bg{width:100%;height:100%;font-family:Arial}.dtpicker-cont{border:1px solid #ECF0F1}.dtpicker-mobile .dtpicker-cont{position:relative;top:50%;-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);border:0}.dtpicker-content{margin:0 auto;padding:1em 0;max-width:500px;background:#fff}.dtpicker-mobile .dtpicker-content{width:97%}.dtpicker-subcontent{position:relative}.dtpicker-header{margin:.2em 1em}.dtpicker-header .dtpicker-title{color:#2980B9;text-align:center;font-size:1.1em}.dtpicker-header .dtpicker-close{position:absolute;top:-.7em;right:.3em;padding:.5em .5em 1em 1em;color:#FF3B30;font-size:1.5em;cursor:pointer}.dtpicker-header .dtpicker-close:hover{color:#FF3B30}.dtpicker-header .dtpicker-value{padding:.8em .2em .2em;color:#FF3B30;text-align:center;font-size:1.4em}.dtpicker-components{overflow:hidden;margin:1em;font-size:1.3em}.dtpicker-components *{margin:0;padding:0}.dtpicker-components .dtpicker-compOutline{display:inline-block;float:left}.dtpicker-comp2{width:50%}.dtpicker-comp3{width:33.3%}.dtpicker-comp4{width:25%}.dtpicker-comp5{width:20%}.dtpicker-comp6{width:16.66%}.dtpicker-comp7{width:14.285%}.dtpicker-components .dtpicker-comp{margin:2%;text-align:center}.dtpicker-components .dtpicker-comp>*{display:block;height:30px;color:#2980B9;text-align:center;line-height:30px}.dtpicker-components .dtpicker-comp>:hover{color:#2980B9}.dtpicker-components .dtpicker-compButtonEnable{opacity:1}.dtpicker-components .dtpicker-compButtonDisable{opacity:.5}.dtpicker-components .dtpicker-compButton{background:#FFF;font-size:140%;cursor:pointer}.dtpicker-components .dtpicker-compValue{margin:.4em 0;width:100%;border:0;background:#FFF;font-size:100%;-webkit-appearance:none;-moz-appearance:none}.dtpicker-overlay .dtpicker-compValue:focus{outline:0;background:#F2FCFF}.dtpicker-buttonCont{overflow:hidden;margin:.2em 1em}.dtpicker-buttonCont .dtpicker-button{display:block;padding:.6em 0;width:47%;background:#FF3B30;color:#FFF;text-align:center;font-size:1.3em;cursor:pointer}.dtpicker-buttonCont .dtpicker-button:hover{color:#FFF}.dtpicker-singleButton .dtpicker-button{margin:.2em auto}.dtpicker-twoButtons .dtpicker-buttonSet{float:left}.dtpicker-twoButtons .dtpicker-buttonClear{float:right}.page-title .title .organiser_logo{position:absolute;height:45px;right:20px;top:5px;bottom:5px}.page-title .title .organiser_logo img{max-height:45px}.nav li.nav-button a span{padding:10px;background-color:#037c9c}.event.panel{margin-top:10px}.event .event-date{border:1px solid #fff;padding-bottom:9px;padding-top:7px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,0.1);width:46px;position:absolute;background-color:#fff;top:-13px;border-color:#0384a6;color:#666}.event .event-date .day{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:22px;font-weight:500;margin:-2px auto -6px auto}.event .event-date .month{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:10px;font-weight:500;margin:-2px auto 0 auto}.event .event-meta{margin:0;padding:0;margin-left:60px;height:55px;margin-top:10px;color:#fff}.event .event-meta li{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;list-style:none;font-size:12px}.event .event-meta li a{color:#fff}.event .event-meta li.event-title a{font-size:16px}.event .event-meta li.event-organiser a{font-weight:bold}.event .panel-title{height:60px;padding:10px}.event .panel-title a{margin:0;height:40px;display:table-cell;vertical-align:middle;text-indent:50px}.stat-box{padding:20px;background-color:#0398bf;color:#fff;text-align:center;margin-bottom:10px;border-bottom:4px solid rgba(0,0,0,0.2)}.stat-box h3{margin-bottom:5px;margin-top:0;font-weight:200}.stat-box span{text-transform:uppercase;font-weight:lighter;color:#d0f0fe}.stat-box:nth-child(odd){background-color:#0384a6}.top_of_page_alert{border:none;margin:0;text-align:center;border-bottom:5px solid}.v-align-text{text-align:center;position:relative;top:50%;-ms-transform:translateY(-50%);-wekbit-transform:translateY(-50%);transform:translateY(-50%)}@media (max-width:992px){.page-header>[class*=" col-"],.page-header>[class^="col-"]{margin-bottom:10px}}@media (max-width:480px){.btn-group-responsive{margin-bottom:-10px;float:none !important;display:block !important}.btn-group-responsive .btn{width:100%;padding-left:0;padding-right:0;margin-bottom:10px}.btn-group-responsive .pull-left,.btn-group-responsive .pull-right{float:none !important}}label.required::after{content:'*';color:red;padding-left:3px;font-size:9px}.hasDatepicker[disabled],.hasDatepicker[readonly],fieldset[disabled] .hasDatepicker{cursor:pointer !important;background-color:#fff !important;opacity:1}.more-options{display:none}.col-sort{color:#fff}.col-sort :hover{color:#fff}.pac-container{z-index:9999}.dtpicker-overlay{z-index:9999}.dtpicker-close{display:none}.dtpicker-header .dtpicker-title{color:#afafaf;text-align:center;font-size:18px;font-weight:normal}.dtpicker-header .dtpicker-value{padding:.8em .2em .2em .2em;color:#0384a6;text-align:center;font-size:1.4em}.dtpicker-buttonCont .dtpicker-button{background:#0384a6;border-radius:0}.dtpicker-content{border-radius:0}.sidebar-open-ltr body{overflow-x:hidden}.order_options{margin:10px 0;padding:5px 15px;margin-top:0}.order_options .event_count{font-weight:bold;color:#777;line-height:30px}.well{background-color:#f9f9f9;box-shadow:none}.input-group-btn select{width:115px !important;border-left:0;font-size:12px}.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;background:red;cursor:inherit;display:block}input[readonly]{background-color:white !important;cursor:text !important}
\ No newline at end of file
+.dtpicker-overlay{z-index:2000;display:none;min-width:300px;background:rgba(0,0,0,.2);font-size:12px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.dtpicker-mobile{position:fixed;top:0;left:0;width:100%;height:100%}.dtpicker-overlay *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-ms-box-sizing:border-box;-webkit-tap-highlight-color:rgba(0,0,0,0)}.dtpicker-bg{width:100%;height:100%;font-family:Arial}.dtpicker-cont{border:1px solid #ECF0F1}.dtpicker-mobile .dtpicker-cont{position:relative;top:50%;-webkit-transform:translateY(-50%);-moz-transform:translateY(-50%);-o-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);border:0}.dtpicker-content{margin:0 auto;padding:1em 0;max-width:500px;background:#fff}.dtpicker-mobile .dtpicker-content{width:97%}.dtpicker-subcontent{position:relative}.dtpicker-header{margin:.2em 1em}.dtpicker-header .dtpicker-title{color:#2980B9;text-align:center;font-size:1.1em}.dtpicker-header .dtpicker-close{position:absolute;top:-.7em;right:.3em;padding:.5em .5em 1em 1em;color:#FF3B30;font-size:1.5em;cursor:pointer}.dtpicker-header .dtpicker-close:hover{color:#FF3B30}.dtpicker-header .dtpicker-value{padding:.8em .2em .2em;color:#FF3B30;text-align:center;font-size:1.4em}.dtpicker-components{overflow:hidden;margin:1em;font-size:1.3em}.dtpicker-components *{margin:0;padding:0}.dtpicker-components .dtpicker-compOutline{display:inline-block;float:left}.dtpicker-comp2{width:50%}.dtpicker-comp3{width:33.3%}.dtpicker-comp4{width:25%}.dtpicker-comp5{width:20%}.dtpicker-comp6{width:16.66%}.dtpicker-comp7{width:14.285%}.dtpicker-components .dtpicker-comp{margin:2%;text-align:center}.dtpicker-components .dtpicker-comp>*{display:block;height:30px;color:#2980B9;text-align:center;line-height:30px}.dtpicker-components .dtpicker-comp>:hover{color:#2980B9}.dtpicker-components .dtpicker-compButtonEnable{opacity:1}.dtpicker-components .dtpicker-compButtonDisable{opacity:.5}.dtpicker-components .dtpicker-compButton{background:#FFF;font-size:140%;cursor:pointer}.dtpicker-components .dtpicker-compValue{margin:.4em 0;width:100%;border:0;background:#FFF;font-size:100%;-webkit-appearance:none;-moz-appearance:none}.dtpicker-overlay .dtpicker-compValue:focus{outline:0;background:#F2FCFF}.dtpicker-buttonCont{overflow:hidden;margin:.2em 1em}.dtpicker-buttonCont .dtpicker-button{display:block;padding:.6em 0;width:47%;background:#FF3B30;color:#FFF;text-align:center;font-size:1.3em;cursor:pointer}.dtpicker-buttonCont .dtpicker-button:hover{color:#FFF}.dtpicker-singleButton .dtpicker-button{margin:.2em auto}.dtpicker-twoButtons .dtpicker-buttonSet{float:left}.dtpicker-twoButtons .dtpicker-buttonClear{float:right}/*
+ * Bootstrap TouchSpin - v3.0.1
+ * A mobile and touch friendly input spinner component for Bootstrap 3.
+ * http://www.virtuosoft.eu/code/bootstrap-touchspin/
+ *
+ * Made by István Ujj-Mészáros
+ * Under Apache License v2.0 License
+ */
+
+.bootstrap-touchspin .input-group-btn-vertical {
+ position: relative;
+ white-space: nowrap;
+ width: 1%;
+ vertical-align: middle;
+ display: table-cell;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+ padding: 8px 10px;
+ margin-left: -1px;
+ position: relative;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up {
+ border-radius: 0;
+ border-top-right-radius: 4px;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down {
+ margin-top: -2px;
+ border-radius: 0;
+ border-bottom-right-radius: 4px;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical i {
+ position: absolute;
+ top: 3px;
+ left: 5px;
+ font-size: 9px;
+ font-weight: normal;
+}
+.page-title .title .organiser_logo{position:absolute;height:45px;right:20px;top:5px;bottom:5px}.page-title .title .organiser_logo img{max-height:45px}.nav li.nav-button a span{padding:10px;background-color:#037c9c}.event.panel{margin-top:10px}.event .event-date{border:1px solid #fff;padding-bottom:9px;padding-top:7px;text-align:center;text-shadow:0 1px 1px rgba(0,0,0,0.1);width:46px;position:absolute;background-color:#fff;top:-13px;border-color:#0384a6;color:#666}.event .event-date .day{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:22px;font-weight:500;margin:-2px auto -6px auto}.event .event-date .month{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:10px;font-weight:500;margin:-2px auto 0 auto}.event .event-meta{margin:0;padding:0;margin-left:60px;height:55px;margin-top:10px;color:#fff}.event .event-meta li{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;list-style:none;font-size:12px}.event .event-meta li a{color:#fff}.event .event-meta li.event-title a{font-size:16px}.event .event-meta li.event-organiser a{font-weight:bold}.event .panel-title{height:60px;padding:10px}.event .panel-title a{margin:0;height:40px;display:table-cell;vertical-align:middle;text-indent:50px}.stat-box{padding:20px;background-color:#0398bf;color:#fff;text-align:center;margin-bottom:10px;border-bottom:4px solid rgba(0,0,0,0.2)}.stat-box h3{margin-bottom:5px;margin-top:0;font-weight:200}.stat-box span{text-transform:uppercase;font-weight:lighter;color:#d0f0fe}.stat-box:nth-child(odd){background-color:#0384a6}.top_of_page_alert{border:none;margin:0;text-align:center;border-bottom:5px solid}.v-align-text{text-align:center;position:relative;top:50%;-ms-transform:translateY(-50%);-wekbit-transform:translateY(-50%);transform:translateY(-50%)}@media (max-width:992px){.page-header>[class*=" col-"],.page-header>[class^="col-"]{margin-bottom:10px}}@media (max-width:480px){.btn-group-responsive{margin-bottom:-10px;float:none !important;display:block !important}.btn-group-responsive .btn{width:100%;padding-left:0;padding-right:0;margin-bottom:10px}.btn-group-responsive .pull-left,.btn-group-responsive .pull-right{float:none !important}}label.required::after{content:'*';color:red;padding-left:3px;font-size:9px}.hasDatepicker[disabled],.hasDatepicker[readonly],fieldset[disabled] .hasDatepicker{cursor:pointer !important;background-color:#fff !important;opacity:1}.more-options{display:none}.col-sort{color:#fff}.col-sort :hover{color:#fff}.pac-container{z-index:9999}.dtpicker-overlay{z-index:9999}.dtpicker-close{display:none}.dtpicker-header .dtpicker-title{color:#afafaf;text-align:center;font-size:18px;font-weight:normal}.dtpicker-header .dtpicker-value{padding:.8em .2em .2em .2em;color:#0384a6;text-align:center;font-size:1.4em}.dtpicker-buttonCont .dtpicker-button{background:#0384a6;border-radius:0}.dtpicker-content{border-radius:0}.sidebar-open-ltr body{overflow-x:hidden}.order_options{margin:10px 0;padding:5px 15px;margin-top:0}.order_options .event_count{font-weight:bold;color:#777;line-height:30px}.well{background-color:#f9f9f9;box-shadow:none}.input-group-btn select{width:115px !important;border-left:0;font-size:12px}.btn-file{position:relative;overflow:hidden}.btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;background:red;cursor:inherit;display:block}input[readonly]{background-color:white !important;cursor:text !important}
\ No newline at end of file
diff --git a/public/assets/stylesheet/application.less b/public/assets/stylesheet/application.less
index 1b513c71..42c623dd 100644
--- a/public/assets/stylesheet/application.less
+++ b/public/assets/stylesheet/application.less
@@ -34,6 +34,7 @@
@import (inline) "../../vendor/RRSSB/css/rrssb.css";
@import (inline) "../../vendor/humane-js/themes/flatty.css";
@import (inline) "../../vendor/curioussolutions-datetimepicker/dist/DateTimePicker.min.css";
+@import (inline) "../../vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.css";
@import "custom.less";
diff --git a/public/vendor/bootstrap-touchspin/.bower.json b/public/vendor/bootstrap-touchspin/.bower.json
new file mode 100644
index 00000000..3d5f3909
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/.bower.json
@@ -0,0 +1,39 @@
+{
+ "name": "bootstrap-touchspin",
+ "version": "3.0.3",
+ "homepage": "http://www.virtuosoft.eu/code/bootstrap-touchspin/",
+ "authors": [
+ {
+ "name": "István Ujj-Mészáros",
+ "url": "https://github.com/istvan-ujjmeszaros"
+ }
+ ],
+ "description": "Bootstrap TouchSpin is a mobile and touch friendly input spinner component for Bootstrap 3.",
+ "dependencies": {
+ "jquery": ">=1.9.0",
+ "bootstrap": ">=3.0.0"
+ },
+ "license": "Apache License, Version 2.0",
+ "keywords": [
+ "jquery",
+ "plugin",
+ "bootstrap",
+ "ui"
+ ],
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "_release": "3.0.3",
+ "_resolution": {
+ "type": "version",
+ "tag": "3.0.3",
+ "commit": "81fc55dd525f08a6af6f3a8465026ae1e672bdae"
+ },
+ "_source": "git://github.com/istvan-ujjmeszaros/bootstrap-touchspin.git",
+ "_target": "~3.0.1",
+ "_originalSource": "bootstrap-touchspin"
+}
\ No newline at end of file
diff --git a/public/vendor/bootstrap-touchspin/CONTRIBUTING.md b/public/vendor/bootstrap-touchspin/CONTRIBUTING.md
new file mode 100644
index 00000000..40053ac1
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/CONTRIBUTING.md
@@ -0,0 +1,10 @@
+# Contributing
+
+Before sending a pull request remember to follow [jQuery Core Style Guide](http://contribute.jquery.org/style-guide/js/).
+
+1. Fork it!
+2. Create your feature branch: `git checkout -b my-new-feature`
+3. Make your changes on the `src` folder, never on the `dist` folder.
+4. Commit your changes: `git commit -m 'Add some feature'`
+5. Push to the branch: `git push origin my-new-feature`
+6. Submit a pull request :D
diff --git a/public/vendor/bootstrap-touchspin/Gruntfile.js b/public/vendor/bootstrap-touchspin/Gruntfile.js
new file mode 100644
index 00000000..9188459d
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/Gruntfile.js
@@ -0,0 +1,73 @@
+module.exports = function (grunt) {
+
+ grunt.initConfig({
+
+ // Import package manifest
+ pkg: grunt.file.readJSON("bootstrap-touchspin.jquery.json"),
+
+ // Banner definitions
+ meta: {
+ banner: "/*\n" +
+ " * <%= pkg.title || pkg.name %> - v<%= pkg.version %>\n" +
+ " * <%= pkg.description %>\n" +
+ " * <%= pkg.homepage %>\n" +
+ " *\n" +
+ " * Made by <%= pkg.author.name %>\n" +
+ " * Under <%= pkg.licenses[0].type %> License\n" +
+ " */\n"
+ },
+
+ // Concat definitions
+ concat: {
+ js: {
+ src: ["src/jquery.bootstrap-touchspin.js"],
+ dest: "dist/jquery.bootstrap-touchspin.js"
+ },
+ css: {
+ src: ["src/jquery.bootstrap-touchspin.css"],
+ dest: "dist/jquery.bootstrap-touchspin.css"
+ },
+ options: {
+ banner: "<%= meta.banner %>"
+ }
+ },
+
+ // Lint definitions
+ jshint: {
+ files: ["src/jquery.bootstrap-touchspin.js"],
+ options: {
+ jshintrc: ".jshintrc"
+ }
+ },
+
+ // Minify definitions
+ uglify: {
+ js: {
+ src: ["dist/jquery.bootstrap-touchspin.js"],
+ dest: "dist/jquery.bootstrap-touchspin.min.js"
+ },
+ options: {
+ banner: "<%= meta.banner %>"
+ }
+ },
+
+ cssmin: {
+ css: {
+ src: ["dist/jquery.bootstrap-touchspin.css"],
+ dest: "dist/jquery.bootstrap-touchspin.min.css"
+ },
+ options: {
+ banner: "<%= meta.banner %>"
+ }
+ }
+ });
+
+ grunt.loadNpmTasks("grunt-contrib-concat");
+ grunt.loadNpmTasks("grunt-contrib-jshint");
+ grunt.loadNpmTasks("grunt-contrib-uglify");
+ grunt.loadNpmTasks("grunt-contrib-cssmin");
+
+ grunt.registerTask("default", ["jshint", "concat", "uglify", "cssmin"]);
+ grunt.registerTask("travis", ["jshint"]);
+
+};
diff --git a/public/vendor/bootstrap-touchspin/LICENSE.md b/public/vendor/bootstrap-touchspin/LICENSE.md
new file mode 100644
index 00000000..b9f1b00f
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/LICENSE.md
@@ -0,0 +1,21 @@
+Bootstrap TouchSpin
+v1.0.0
+
+A mobile and touch friendly input spinner component for Bootstrap 3.
+
+ https://github.com/istvan-meszaros/bootstrap-touchspin
+ http://www.virtuosoft.eu/code/bootstrap-touchspin/
+
+Copyright 2013 István Ujj-Mészáros
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git a/public/vendor/bootstrap-touchspin/README.md b/public/vendor/bootstrap-touchspin/README.md
new file mode 100644
index 00000000..b66dd57d
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/README.md
@@ -0,0 +1,13 @@
+# Bootstrap TouchSpin [](https://travis-ci.org/istvan-ujjmeszaros/bootstrap-touchspin)
+
+##### Bootstrap TouchSpin is a mobile and touch friendly input spinner component for Bootstrap 3.
+
+- [Website](http://www.virtuosoft.eu/code/bootstrap-touchspin/)
+
+Please report issues and feel free to make feature suggestions as well.
+
+## License
+
+Apache License, Version 2.0
+
+[](http://githalytics.com/istvan-ujjmeszaros/bootstrap-touchspin)
diff --git a/public/vendor/bootstrap-touchspin/bootstrap-touchspin.jquery.json b/public/vendor/bootstrap-touchspin/bootstrap-touchspin.jquery.json
new file mode 100644
index 00000000..ee1efc53
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/bootstrap-touchspin.jquery.json
@@ -0,0 +1,31 @@
+{
+ "name": "bootstrap-touchspin",
+ "title": "Bootstrap TouchSpin",
+ "description": "A mobile and touch friendly input spinner component for Bootstrap 3.",
+ "keywords": [
+ "input",
+ "bootstrap",
+ "number",
+ "range",
+ "spinbutton",
+ "spinner"
+ ],
+ "version": "3.0.1",
+ "author": {
+ "name": "István Ujj-Mészáros",
+ "url": "https://github.com/istvan-ujjmeszaros"
+ },
+ "licenses": [
+ {
+ "type": "Apache License v2.0",
+ "url": "http://www.apache.org/licenses/LICENSE-2.0"
+ }
+ ],
+ "homepage": "http://www.virtuosoft.eu/code/bootstrap-touchspin/",
+ "demo": "http://www.virtuosoft.eu/code/bootstrap-touchspin/",
+ "docs": "http://www.virtuosoft.eu/code/bootstrap-touchspin/",
+ "download": "https://github.com/istvan-ujjmeszaros/bootstrap-touchspin/archive/master.zip",
+ "dependencies": {
+ "jquery": ">=1.7"
+ }
+}
\ No newline at end of file
diff --git a/public/vendor/bootstrap-touchspin/bower.json b/public/vendor/bootstrap-touchspin/bower.json
new file mode 100644
index 00000000..a82ad9e2
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/bower.json
@@ -0,0 +1,30 @@
+{
+ "name": "bootstrap-touchspin",
+ "version": "3.0.1",
+ "homepage": "http://www.virtuosoft.eu/code/bootstrap-touchspin/",
+ "authors": [
+ {
+ "name": "István Ujj-Mészáros",
+ "url": "https://github.com/istvan-ujjmeszaros"
+ }
+ ],
+ "description": "Bootstrap TouchSpin is a mobile and touch friendly input spinner component for Bootstrap 3.",
+ "dependencies": {
+ "jquery": ">=1.9.0",
+ "bootstrap": ">=3.0.0"
+ },
+ "license": "Apache License, Version 2.0",
+ "keywords": [
+ "jquery",
+ "plugin",
+ "bootstrap",
+ "ui"
+ ],
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ]
+}
diff --git a/public/vendor/bootstrap-touchspin/demo/demo.css b/public/vendor/bootstrap-touchspin/demo/demo.css
new file mode 100644
index 00000000..4a97ca97
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/demo/demo.css
@@ -0,0 +1,383 @@
+body {
+ font-family: Arial, Ubuntu, Helvetica, sans-serif;
+ color: #333;
+ padding-top: 20px;
+}
+
+h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
+ font-family: Arial, Ubuntu, Helvetica, sans-serif;
+ font-weight: normal;
+}
+
+hr {
+ border-color: #ccc;
+}
+
+a,
+a:hover {
+ color: #d64513;
+}
+
+p {
+ margin-bottom: 15px;
+}
+
+h1 {
+ font-family: "Century Gothic", Arial, Ubuntu, Helvetica, sans-serif;
+ font-size: 28px;
+}
+
+h1 small {
+ font-size: 22px;
+}
+
+h2 {
+ font-family: "Century Gothic", Arial, Ubuntu, Helvetica, sans-serif;
+ font-size: 26px;
+ margin: 30px 0 20px;
+}
+
+h2 small {
+ font-size: 18px;
+}
+
+h3 {
+ margin-top: 25px;
+ font-size: 18px;
+ font-weight: bold;
+}
+
+h3 small {
+ font-size: 16px;
+}
+
+h4 {
+ font-size: 18px;
+}
+
+h4 small {
+ font-size: 14px;
+}
+
+h5 {
+ font-size: 16px;
+}
+
+h5 small {
+ font-size: 12px;
+}
+
+h6 {
+ font-size: 14px;
+}
+
+h6 small {
+ font-size: 10px;
+}
+
+.dl-horizontal dt {
+ width: 200px;
+}
+
+.dl-horizontal dd {
+ margin-left: 220px;
+}
+
+small {
+ font-size: 12px;
+}
+
+.navbar-brand {
+ padding: 5px 0px 5px;
+}
+
+.navbar-default {
+ font-family: "Century Gothic", Arial, sans-serif;
+ background: #000 url(img/bg-menu.png) repeat-x left top; /*#377fa0;*/
+ color: #fff;
+ text-transform: uppercase;
+ border: none;
+ box-shadow: 0px 0px 1px #000;
+ /*background-image: linear-gradient(to top, rgb(62, 86, 112) 0%, rgb(69, 94, 122) 100%)*/;
+}
+
+.navbar-default .navbar-nav > .dropdown > a .caret,
+.navbar-default .navbar-nav > .dropdown > a:hover .caret,
+.navbar-default .navbar-nav > .dropdown > a:focus .caret {
+ border-top-color: #fff;
+ border-bottom-color: #fff;
+}
+
+.navbar > .container .navbar-brand {
+ margin-left: 0;
+}
+
+.navbar .nav > li > a {
+ color: #fff;
+}
+
+.navbar-default .navbar-brand,
+.navbar-default .navbar-brand:hover,
+.navbar-default .navbar-brand:focus {
+ color: #fff;
+}
+
+.navbar .nav > .active {
+}
+
+.navbar .nav > .active > a,
+.navbar .nav > .active > a:hover,
+.navbar .nav > .active > a:focus,
+.navbar .nav li.dropdown.active > .dropdown-toggle,
+.navbar .nav li.dropdown.open.active > .dropdown-toggle {
+ background: url(img/bg-menu-selected.png) no-repeat center bottom; /*#a5360f;*/
+ background: #BC451B;
+ color: #fff;
+ /*height: 65px;*/
+}
+
+.navbar .nav > li > a:focus,
+.navbar .nav > li > a:hover,
+.navbar .nav li.dropdown.open > .dropdown-toggle {
+ background: rgba(188, 69, 27, 0.6);
+ color: #fff;
+}
+
+
+.dropdown-menu {
+ border-radius: 0;
+ padding: 10px 0;
+}
+
+.dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus, .dropdown-submenu:hover > a, .dropdown-submenu:focus > a,
+.dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus {
+ background: #d64513;
+}
+
+.nav-tabs .open .dropdown-toggle, .nav-pills .open .dropdown-toggle, .nav > li.dropdown.open.active > a:hover {
+ border: none;
+}
+
+.dropdown-menu > li > a {
+ padding: 10px 20px;
+ color: #585858;
+}
+
+.navbar .addthis_toolbox {
+ margin-top: 9px;
+ float: right;
+ margin-left: 15px;
+}
+
+.navbar .followus {
+ display: none;
+ float: right;
+ color: white;
+ margin-top: 15px;
+ margin-right: 10px;
+}
+
+.panel {
+ border-radius: 10px;
+ background: #f5f5f5;
+ box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2);
+}
+
+.panel-heading {
+ border-bottom: 1px solid #ddd;
+ color: #4d4d4d;
+ font-size: 14px;
+ margin: 0;
+}
+
+.panel-heading a {
+ color: #4d4d4d;
+}
+
+.panel-body {
+ border-top: 1px solid #fff;
+}
+
+.abstract {
+ min-height: 60px;
+}
+
+.btn-info {
+ border: none;
+ background: #d64513;
+ color: #fff;
+ box-shadow: none;
+ text-shadow: none;
+}
+
+.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .btn-info.disabled, .btn-info[disabled] {
+ background: #a5360f;
+}
+
+.socialbuttons,
+.addthis_toolbox {
+ min-height: 26px;
+}
+
+.row-fluid .socialbuttons {
+ margin-bottom: 15px;
+}
+
+.navbar .socialbuttons {
+ float: right;
+ height: 20px;
+ width: 220px;
+ white-space: nowrap;
+ margin-top: 15px;
+}
+
+.navbar .btn-navbar {
+ background: #474747;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.navbar .btn-navbar {
+ background: #a5360f;
+ border: none;
+ border-radius: 0;
+}
+
+.navbar .btn-navbar:hover, .navbar .btn-navbar:focus, .navbar .btn-navbar:active, .navbar .btn-navbar.active, .navbar .btn-navbar.disabled, .navbar .btn-navbar[disabled] {
+ background: #474747;
+}
+
+.nav-collapse .nav > li > a, .nav-collapse .dropdown-menu a {
+ border-radius: 0;
+}
+
+
+/* woodpaul on board */
+.hero-unit {
+ text-align: center;
+ margin: 0 0 50px;
+}
+
+.hero-unit h1 {
+ font-size: 48px;
+ text-align: center;
+ text-shadow: 1px 1px 0px rgba(255,255,255,1);
+}
+
+.hero-unit h1 small {
+ display: block;
+}
+
+.hero-unit .btn {
+ margin: 0;
+}
+
+.socialbuttons {
+ text-align: center;
+ margin: 0 0 -15px;
+}
+
+.socialbuttons iframe {
+ display: inline-block;
+}
+
+.socialbuttons .addthis_toolbox {
+ width: 420px;
+ display: inline-block;
+}
+
+.socialbuttons .share-github {
+ position: relative;
+ top: -5px;
+}
+
+.socialbuttons .addthis_button_facebook_like {
+ margin: 0 30px 0 0;
+}
+
+hr{
+ background-color: transparent;
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #fff;
+}
+
+.controls-row {
+ margin: 0 0 10px;
+}
+
+/* table */
+.table thead th {
+ font-family: "Century Gothic", Arial, sans-serif;
+ text-transform: uppercase;
+ font-weight: normal;
+ background-color: #bc451b;
+ color: #fff;
+ vertical-align: middle!important;
+}
+
+code {
+ padding: 1px 4px;
+}
+
+@media (min-width: 768px) {
+ .navbar-collapse {
+ float: left;
+ }
+
+ .dropdown:hover .dropdown-menu {
+ display: block;
+ }
+}
+
+@media (max-width: 1000px) {
+ .navbar .followus {
+ display: none;
+ }
+}
+
+@media (max-width: 767px) {
+ body {
+ padding-top: 110px;
+ }
+
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a {
+ color: #fff;
+ }
+
+ .navbar-collapse {
+ background: #000 url(img/bg-menu.png) repeat-x left top; /*#377fa0;*/
+ color: #fff;
+ }
+
+ .navbar .nav > .active > a, .navbar .nav > .active > a:hover, .navbar .nav > .active > a:focus, .navbar .nav li.dropdown.active > .dropdown-toggle, .navbar .nav li.dropdown.open.active > .dropdown-toggle,
+ .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus,
+ .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {
+ background: #d64513;
+ color: #fff;
+ height: auto;
+ }
+
+ .navbar-fixed-top > .container {
+ position: relative;
+ }
+
+ .navbar > .container .navbar-brand {
+ margin-left: 15px;
+ }
+
+ .navbar .socialbuttons {
+ position: absolute;
+ right: 100px;
+ top: 0;
+ width: 200px;
+ margin-top: 12px;
+ }
+
+ .navbar .addthis_toolbox {
+ display: none;
+ }
+}
+
diff --git a/public/vendor/bootstrap-touchspin/demo/favicon.ico b/public/vendor/bootstrap-touchspin/demo/favicon.ico
new file mode 100644
index 00000000..048fef35
Binary files /dev/null and b/public/vendor/bootstrap-touchspin/demo/favicon.ico differ
diff --git a/public/vendor/bootstrap-touchspin/demo/index.html b/public/vendor/bootstrap-touchspin/demo/index.html
new file mode 100644
index 00000000..90b29155
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/demo/index.html
@@ -0,0 +1,778 @@
+
+
+
+
+ Bootstrap TouchSpin
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A mobile and touch friendly input spinner component for Bootstrap 3.
+ It supports the mousewheel and the up/down keys.
+
+
+
Examples
+
+
+
+ Example using data attributes:
+
+
+
+
+<input id="demo0"
+ type="text"
+ value="55"
+ name="demo0"
+ data-bts-min="0"
+ data-bts-max="100"
+ data-bts-init-val=""
+ data-bts-step="1"
+ data-bts-decimal="0"
+ data-bts-step-interval="100"
+ data-bts-force-step-divisibility="round"
+ data-bts-step-interval-delay="500"
+ data-bts-prefix=""
+ data-bts-postfix=""
+ data-bts-prefix-extra-class=""
+ data-bts-postfix-extra-class=""
+ data-bts-booster="true"
+ data-bts-boostat="10"
+ data-bts-max-boosted-step="false"
+ data-bts-mousewheel="true"
+ data-bts-button-down-class="btn btn-default"
+ data-bts-button-up-class="btn btn-default"
+ />
+<script>
+ $("input[name='demo0']").TouchSpin({
+ });
+</script>
+
+
+
+
+
+
+
+
+
+ Vertical button alignment:
+
+
+
+
+<input id="demo_vertical" type="text" value="" name="demo_vertical">
+<script>
+ $("input[name='demo_vertical']").TouchSpin({
+ verticalbuttons: true
+ });
+</script>
+
+
+
+
+
+
+
+
+
+ Vertical buttons with custom icons:
+
+
+
+
+<input id="demo_vertical2" type="text" value="" name="demo_vertical2">
+<script>
+ $("input[name='demo_vertical2']").TouchSpin({
+ verticalbuttons: true,
+ verticalupclass: 'glyphicon glyphicon-plus',
+ verticaldownclass: 'glyphicon glyphicon-minus'
+ });
+</script>
+
+
+
+
+
+
+
+
+
+ Example with postfix (large):
+
+
+
+
+<input id="demo1" type="text" value="55" name="demo1">
+<script>
+ $("input[name='demo1']").TouchSpin({
+ min: 0,
+ max: 100,
+ step: 0.1,
+ decimals: 2,
+ boostat: 5,
+ maxboostedstep: 10,
+ postfix: '%'
+ });
+</script>
+
+
+
+
+
+
+
+
+
+
+
+<form class="form-horizontal" role="form">
+ <div class="form-group">
+ <label for="demo2" class="col-md-5 control-label">Example:</label> <input id="demo2" type="text" value="0" name="demo2" class="col-md-7 form-control">
+ </div>
+</form>
+
+<script>
+ $("input[name='demo2']").TouchSpin({
+ min: -1000000000,
+ max: 1000000000,
+ stepinterval: 50,
+ maxboostedstep: 10000000,
+ prefix: '$'
+ });
+</script>
+
+
+
+
+
+
+
+
+ Init with empty value:
+
+
+
+
+<input id="demo3" type="text" value="" name="demo3">
+<script>
+ $("input[name='demo3']").TouchSpin();
+</script>
+
+
+
+
+
+
+
+
+
+ The initval setting is only applied when no explicit value is set on the input with the
+ value attribute.
+
+
+
+ Value attribute is not set
+ (applying settings.initval)
+ :
+ Value is set explicitly to 33
+ (skipping settings.initval)
+ :
+
+
+
+
+<input id="demo3_21" type="text" value="" name="demo3_21">
+<script>
+ $("input[name='demo3_21']").TouchSpin({
+ initval: 40
+ });
+</script>
+<input id="demo3_22" type="text" value="33" name="demo3_22">
+<script>
+ $("input[name='demo3_22']").TouchSpin({
+ initval: 40
+ });
+</script>
+
+
+
+
+
+
+
+
+ Size of the whole controller can be set with applying input-sm or input-lg class on the
+ input, or by applying the plugin on an input inside an input-group with the proper size class(input-group-sm
+ or input-group-lg).
+
+
+
+
+ Button postfix (small):
+
+
+
+
+<input id="demo4" type="text" value="" name="demo4" class="input-sm">
+<script>
+ $("input[name='demo4']").TouchSpin({
+ postfix: "a button",
+ postfix_extraclass: "btn btn-default"
+ });
+</script>
+
+
+
+
+
+
+
+
+
+
Button postfix (large):
+
+
+
+
+
+
+
+
+<div class="input-group input-group-lg">
+ <input id="demo4_2" type="text" value="" name="demo4_2" class="form-control input-lg">
+</div>
+<script>
+ $("input[name='demo4_2']").TouchSpin({
+ postfix: "a button",
+ postfix_extraclass: "btn btn-default"
+ });
+</script>
+
+
+
+
+
+
+
+
+
+
+
Button group:
+
+
+
+
+
+
+
+<div class="input-group">
+ <input id="demo5" type="text" class="form-control" name="demo5" value="50">
+ <div class="input-group-btn">
+ <button type="button" class="btn btn-default">Action</button>
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+ <span class="caret"></span>
+ <span class="sr-only">Toggle Dropdown</span>
+ </button>
+ <ul class="dropdown-menu pull-right" role="menu">
+ <li><a href="#">Action</a></li>
+ <li><a href="#">Another action</a></li>
+ <li><a href="#">Something else here</a></li>
+ <li class="divider"></li>
+ <li><a href="#">Separated link</a></li>
+ </ul>
+ </div>
+</div>
+<script>
+ $("input[name='demo5']").TouchSpin({
+ prefix: "pre",
+ postfix: "post"
+ });
+</script>
+
+
+
+
+
+
+
+
+
+ Change button class:
+
+
+
+
+$("input[name='demo6']").TouchSpin({
+ buttondown_class: "btn btn-link",
+ buttonup_class: "btn btn-link"
+});
+
+
+
+
+
+
+
+
+
+ Blank/Non-Number replaced:
+
+
+
+
+$("input[name='demo7']").TouchSpin({
+ replacementval: 10
+});
+
+
+
+
+
+
+
+
Event demo
+
+
+
+
Settings
+
+
+
+ Option
+ Default
+ Description
+
+
+
+
+ initval
+ ""
+ Applied when no explicit value is set on the input with the value attribute. Empty string means
+ that the value remains empty on initialization.
+
+
+
+ replacementval
+ ""
+ Applied when user leaves the field empty/blank or enters non-number. Empty string means that the value will not be replaced.
+
+
+
+ min
+ 0
+ Minimum value.
+
+
+ max
+ 100
+ Maximum value.
+
+
+ step
+ 1
+ Incremental/decremental step on up/down change.
+
+
+ forcestepdivisibility
+ 'round'
+ How to force the value to be divisible by step value: 'none' | 'round' | 'floor'
+ | 'ceil'
+
+
+ decimals
+ 0
+ Number of decimal points.
+
+
+ stepinterval
+ 100
+ Refresh rate of the spinner in milliseconds.
+
+
+ stepintervaldelay
+ 500
+ Time in milliseconds before the spinner starts to spin.
+
+
+ verticalbuttons
+ false
+ Enables the traditional up/down buttons.
+
+
+ verticalupclass
+ 'glyphicon glyphicon-chevron-up'
+ Class of the up button with vertical buttons mode enabled.
+
+
+ verticaldownclass
+ 'glyphicon glyphicon-chevron-down'
+ Class of the down button with vertical buttons mode enabled.
+
+
+ prefix
+ ""
+ Text before the input.
+
+
+ postfix
+ ""
+ Text after the input.
+
+
+ prefix_extraclass
+ ""
+ Extra class(es) for prefix.
+
+
+ postfix_extraclass
+ ""
+ Extra class(es) for postfix.
+
+
+ booster
+ true
+ If enabled, the the spinner is continually becoming faster as holding the button.
+
+
+ boostat
+ 10
+ Boost at every nth step.
+
+
+ maxboostedstep
+ false
+ Maximum step when boosted.
+
+
+ mousewheel
+ true
+ Enables the mouse wheel to change the value of the input.
+
+
+ buttondown_class
+ 'btn btn-default'
+ Class(es) of down button.
+
+
+ buttonup_class
+ 'btn btn-default'
+ Class(es) of up button.
+
+
+ buttondown_txt
+ '-'
+ Content inside the down button.
+
+
+ buttonup_txt
+ '+'
+ Content inside the up button.
+
+
+
+
+
Events
+
+
Triggered events
+
+
The following events are triggered on the original input by the plugin and can be listened on.
+
+
+
+
+ Event
+ Description
+
+
+
+
+ change
+ Triggered when the value is changed with one of the buttons (but not triggered when the spinner hits the
+ limit set by settings.min or settings.max.
+
+
+
+ touchspin.on.startspin
+ Triggered when the spinner starts spinning upwards or downwards.
+
+
+ touchspin.on.startupspin
+ Triggered when the spinner starts spinning upwards.
+
+
+ touchspin.on.startdownspin
+ Triggered when the spinner starts spinning downwards.
+
+
+ touchspin.on.stopspin
+ Triggered when the spinner stops spinning.
+
+
+ touchspin.on.stopupspin
+ Triggered when the spinner stops upspinning.
+
+
+ touchspin.on.stopdownspin
+ Triggered when the spinner stops downspinning.
+
+
+ touchspin.on.min
+ Triggered when the spinner hits the limit set by settings.min.
+
+
+ touchspin.on.max
+ Triggered when the spinner hits the limit set by settings.max.
+
+
+
+
+
Callable events
+
+
The following events can be triggered on the original input.
+
+
+ Example usages:
+ $("input").trigger("touchspin.uponce");
+ $("input").trigger("touchspin.updatesettings", {max: 1000});
+
+
+
+
+
+ Event
+ Description
+
+
+
+
+ touchspin.updatesettings
+ function(newoptions): Update any setting of an already initialized TouchSpin instance.
+
+
+ touchspin.uponce
+ Increase the value by one step.
+
+
+ touchspin.downonce
+ Decrease the value by one step.
+
+
+ touchspin.startupspin
+ Starts the spinner upwards.
+
+
+ touchspin.startdownspin
+ Starts the spinner downwards.
+
+
+ touchspin.stopspin
+ Stops the spinner.
+
+
+
+
+
Download
+
+
Download from
+ github. Please report issues and suggestions to github's issue tracker or contact me on g+ or
+ twitter !
+
+
+
+
diff --git a/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.css b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.css
new file mode 100644
index 00000000..ed316c46
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.css
@@ -0,0 +1,45 @@
+/*
+ * Bootstrap TouchSpin - v3.0.1
+ * A mobile and touch friendly input spinner component for Bootstrap 3.
+ * http://www.virtuosoft.eu/code/bootstrap-touchspin/
+ *
+ * Made by István Ujj-Mészáros
+ * Under Apache License v2.0 License
+ */
+
+.bootstrap-touchspin .input-group-btn-vertical {
+ position: relative;
+ white-space: nowrap;
+ width: 1%;
+ vertical-align: middle;
+ display: table-cell;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical > .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+ padding: 8px 10px;
+ margin-left: -1px;
+ position: relative;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up {
+ border-radius: 0;
+ border-top-right-radius: 4px;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down {
+ margin-top: -2px;
+ border-radius: 0;
+ border-bottom-right-radius: 4px;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical i {
+ position: absolute;
+ top: 3px;
+ left: 5px;
+ font-size: 9px;
+ font-weight: normal;
+}
diff --git a/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.js b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.js
new file mode 100644
index 00000000..5f737a45
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.js
@@ -0,0 +1,686 @@
+/*
+ * Bootstrap TouchSpin - v3.0.1
+ * A mobile and touch friendly input spinner component for Bootstrap 3.
+ * http://www.virtuosoft.eu/code/bootstrap-touchspin/
+ *
+ * Made by István Ujj-Mészáros
+ * Under Apache License v2.0 License
+ */
+(function($) {
+ 'use strict';
+
+ var _currentSpinnerId = 0;
+
+ function _scopedEventName(name, id) {
+ return name + '.touchspin_' + id;
+ }
+
+ function _scopeEventNames(names, id) {
+ return $.map(names, function(name) {
+ return _scopedEventName(name, id);
+ });
+ }
+
+ $.fn.TouchSpin = function(options) {
+
+ if (options === 'destroy') {
+ this.each(function() {
+ var originalinput = $(this),
+ originalinput_data = originalinput.data();
+ $(document).off(_scopeEventNames([
+ 'mouseup',
+ 'touchend',
+ 'touchcancel',
+ 'mousemove',
+ 'touchmove',
+ 'scroll',
+ 'scrollstart'], originalinput_data.spinnerid).join(' '));
+ });
+ return;
+ }
+
+ var defaults = {
+ min: 0,
+ max: 100,
+ initval: '',
+ step: 1,
+ decimals: 0,
+ stepinterval: 100,
+ forcestepdivisibility: 'round', // none | floor | round | ceil
+ stepintervaldelay: 500,
+ verticalbuttons: false,
+ verticalupclass: 'glyphicon glyphicon-chevron-up',
+ verticaldownclass: 'glyphicon glyphicon-chevron-down',
+ prefix: '',
+ postfix: '',
+ prefix_extraclass: '',
+ postfix_extraclass: '',
+ booster: true,
+ boostat: 10,
+ maxboostedstep: false,
+ mousewheel: true,
+ buttondown_class: 'btn btn-default',
+ buttonup_class: 'btn btn-default',
+ buttondown_txt: '-',
+ buttonup_txt: '+'
+ };
+
+ var attributeMap = {
+ min: 'min',
+ max: 'max',
+ initval: 'init-val',
+ step: 'step',
+ decimals: 'decimals',
+ stepinterval: 'step-interval',
+ verticalbuttons: 'vertical-buttons',
+ verticalupclass: 'vertical-up-class',
+ verticaldownclass: 'vertical-down-class',
+ forcestepdivisibility: 'force-step-divisibility',
+ stepintervaldelay: 'step-interval-delay',
+ prefix: 'prefix',
+ postfix: 'postfix',
+ prefix_extraclass: 'prefix-extra-class',
+ postfix_extraclass: 'postfix-extra-class',
+ booster: 'booster',
+ boostat: 'boostat',
+ maxboostedstep: 'max-boosted-step',
+ mousewheel: 'mouse-wheel',
+ buttondown_class: 'button-down-class',
+ buttonup_class: 'button-up-class',
+ buttondown_txt: 'button-down-txt',
+ buttonup_txt: 'button-up-txt'
+ };
+
+ return this.each(function() {
+
+ var settings,
+ originalinput = $(this),
+ originalinput_data = originalinput.data(),
+ container,
+ elements,
+ value,
+ downSpinTimer,
+ upSpinTimer,
+ downDelayTimeout,
+ upDelayTimeout,
+ spincount = 0,
+ spinning = false;
+
+ init();
+
+
+ function init() {
+ if (originalinput.data('alreadyinitialized')) {
+ return;
+ }
+
+ originalinput.data('alreadyinitialized', true);
+ _currentSpinnerId += 1;
+ originalinput.data('spinnerid', _currentSpinnerId);
+
+
+ if (!originalinput.is('input')) {
+ console.log('Must be an input.');
+ return;
+ }
+
+ _initSettings();
+ _setInitval();
+ _checkValue();
+ _buildHtml();
+ _initElements();
+ _hideEmptyPrefixPostfix();
+ _bindEvents();
+ _bindEventsInterface();
+ elements.input.css('display', 'block');
+ }
+
+ function _setInitval() {
+ if (settings.initval !== '' && originalinput.val() === '') {
+ originalinput.val(settings.initval);
+ }
+ }
+
+ function changeSettings(newsettings) {
+ _updateSettings(newsettings);
+ _checkValue();
+
+ var value = elements.input.val();
+
+ if (value !== '') {
+ value = Number(elements.input.val());
+ elements.input.val(value.toFixed(settings.decimals));
+ }
+ }
+
+ function _initSettings() {
+ settings = $.extend({}, defaults, originalinput_data, _parseAttributes(), options);
+ }
+
+ function _parseAttributes() {
+ var data = {};
+ $.each(attributeMap, function(key, value) {
+ var attrName = 'bts-' + value + '';
+ if (originalinput.is('[data-' + attrName + ']')) {
+ data[key] = originalinput.data(attrName);
+ }
+ });
+ return data;
+ }
+
+ function _updateSettings(newsettings) {
+ settings = $.extend({}, settings, newsettings);
+ }
+
+ function _buildHtml() {
+ var initval = originalinput.val(),
+ parentelement = originalinput.parent();
+
+ if (initval !== '') {
+ initval = Number(initval).toFixed(settings.decimals);
+ }
+
+ originalinput.data('initvalue', initval).val(initval);
+ originalinput.addClass('form-control');
+
+ if (parentelement.hasClass('input-group')) {
+ _advanceInputGroup(parentelement);
+ }
+ else {
+ _buildInputGroup();
+ }
+ }
+
+ function _advanceInputGroup(parentelement) {
+ parentelement.addClass('bootstrap-touchspin');
+
+ var prev = originalinput.prev(),
+ next = originalinput.next();
+
+ var downhtml,
+ uphtml,
+ prefixhtml = '' + settings.prefix + ' ',
+ postfixhtml = '' + settings.postfix + ' ';
+
+ if (prev.hasClass('input-group-btn')) {
+ downhtml = '' + settings.buttondown_txt + ' ';
+ prev.append(downhtml);
+ }
+ else {
+ downhtml = '' + settings.buttondown_txt + ' ';
+ $(downhtml).insertBefore(originalinput);
+ }
+
+ if (next.hasClass('input-group-btn')) {
+ uphtml = '' + settings.buttonup_txt + ' ';
+ next.prepend(uphtml);
+ }
+ else {
+ uphtml = '' + settings.buttonup_txt + ' ';
+ $(uphtml).insertAfter(originalinput);
+ }
+
+ $(prefixhtml).insertBefore(originalinput);
+ $(postfixhtml).insertAfter(originalinput);
+
+ container = parentelement;
+ }
+
+ function _buildInputGroup() {
+ var html;
+
+ if (settings.verticalbuttons) {
+ html = '' + settings.prefix + ' ' + settings.postfix + '
';
+ }
+ else {
+ html = '' + settings.buttondown_txt + ' ' + settings.prefix + ' ' + settings.postfix + ' ' + settings.buttonup_txt + '
';
+ }
+
+ container = $(html).insertBefore(originalinput);
+
+ $('.bootstrap-touchspin-prefix', container).after(originalinput);
+
+ if (originalinput.hasClass('input-sm')) {
+ container.addClass('input-group-sm');
+ }
+ else if (originalinput.hasClass('input-lg')) {
+ container.addClass('input-group-lg');
+ }
+ }
+
+ function _initElements() {
+ elements = {
+ down: $('.bootstrap-touchspin-down', container),
+ up: $('.bootstrap-touchspin-up', container),
+ input: $('input', container),
+ prefix: $('.bootstrap-touchspin-prefix', container).addClass(settings.prefix_extraclass),
+ postfix: $('.bootstrap-touchspin-postfix', container).addClass(settings.postfix_extraclass)
+ };
+ }
+
+ function _hideEmptyPrefixPostfix() {
+ if (settings.prefix === '') {
+ elements.prefix.hide();
+ }
+
+ if (settings.postfix === '') {
+ elements.postfix.hide();
+ }
+ }
+
+ function _bindEvents() {
+ originalinput.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 38) {
+ if (spinning !== 'up') {
+ upOnce();
+ startUpSpin();
+ }
+ ev.preventDefault();
+ }
+ else if (code === 40) {
+ if (spinning !== 'down') {
+ downOnce();
+ startDownSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ originalinput.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 38) {
+ stopSpin();
+ }
+ else if (code === 40) {
+ stopSpin();
+ }
+ });
+
+ originalinput.on('blur', function() {
+ _checkValue();
+ });
+
+ elements.down.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ if (spinning !== 'down') {
+ downOnce();
+ startDownSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ elements.down.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ stopSpin();
+ }
+ });
+
+ elements.up.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ if (spinning !== 'up') {
+ upOnce();
+ startUpSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ elements.up.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ stopSpin();
+ }
+ });
+
+ elements.down.on('mousedown.touchspin', function(ev) {
+ elements.down.off('touchstart.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ downOnce();
+ startDownSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.down.on('touchstart.touchspin', function(ev) {
+ elements.down.off('mousedown.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ downOnce();
+ startDownSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('mousedown.touchspin', function(ev) {
+ elements.up.off('touchstart.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ upOnce();
+ startUpSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('touchstart.touchspin', function(ev) {
+ elements.up.off('mousedown.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ upOnce();
+ startUpSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('mouseout touchleave touchend touchcancel', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ stopSpin();
+ });
+
+ elements.down.on('mouseout touchleave touchend touchcancel', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ stopSpin();
+ });
+
+ elements.down.on('mousemove touchmove', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ ev.preventDefault();
+ });
+
+ elements.up.on('mousemove touchmove', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ ev.preventDefault();
+ });
+
+ $(document).on(_scopeEventNames(['mouseup', 'touchend', 'touchcancel'], _currentSpinnerId).join(' '), function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.preventDefault();
+ stopSpin();
+ });
+
+ $(document).on(_scopeEventNames(['mousemove', 'touchmove', 'scroll', 'scrollstart'], _currentSpinnerId).join(' '), function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.preventDefault();
+ stopSpin();
+ });
+
+ originalinput.on('mousewheel DOMMouseScroll', function(ev) {
+ if (!settings.mousewheel || !originalinput.is(':focus')) {
+ return;
+ }
+
+ var delta = ev.originalEvent.wheelDelta || -ev.originalEvent.deltaY || -ev.originalEvent.detail;
+
+ ev.stopPropagation();
+ ev.preventDefault();
+
+ if (delta < 0) {
+ downOnce();
+ }
+ else {
+ upOnce();
+ }
+ });
+ }
+
+ function _bindEventsInterface() {
+ originalinput.on('touchspin.uponce', function() {
+ stopSpin();
+ upOnce();
+ });
+
+ originalinput.on('touchspin.downonce', function() {
+ stopSpin();
+ downOnce();
+ });
+
+ originalinput.on('touchspin.startupspin', function() {
+ startUpSpin();
+ });
+
+ originalinput.on('touchspin.startdownspin', function() {
+ startDownSpin();
+ });
+
+ originalinput.on('touchspin.stopspin', function() {
+ stopSpin();
+ });
+
+ originalinput.on('touchspin.updatesettings', function(e, newsettings) {
+ changeSettings(newsettings);
+ });
+ }
+
+ function _forcestepdivisibility(value) {
+ switch (settings.forcestepdivisibility) {
+ case 'round':
+ return (Math.round(value / settings.step) * settings.step).toFixed(settings.decimals);
+ case 'floor':
+ return (Math.floor(value / settings.step) * settings.step).toFixed(settings.decimals);
+ case 'ceil':
+ return (Math.ceil(value / settings.step) * settings.step).toFixed(settings.decimals);
+ default:
+ return value;
+ }
+ }
+
+ function _checkValue() {
+ var val, parsedval, returnval;
+
+ val = originalinput.val();
+
+ if (val === '') {
+ return;
+ }
+
+ if (settings.decimals > 0 && val === '.') {
+ return;
+ }
+
+ parsedval = parseFloat(val);
+
+ if (isNaN(parsedval)) {
+ parsedval = 0;
+ }
+
+ returnval = parsedval;
+
+ if (parsedval.toString() !== val) {
+ returnval = parsedval;
+ }
+
+ if (parsedval < settings.min) {
+ returnval = settings.min;
+ }
+
+ if (parsedval > settings.max) {
+ returnval = settings.max;
+ }
+
+ returnval = _forcestepdivisibility(returnval);
+
+ if (Number(val).toString() !== returnval.toString()) {
+ originalinput.val(returnval);
+ originalinput.trigger('change');
+ }
+ }
+
+ function _getBoostedStep() {
+ if (!settings.booster) {
+ return settings.step;
+ }
+ else {
+ var boosted = Math.pow(2, Math.floor(spincount / settings.boostat)) * settings.step;
+
+ if (settings.maxboostedstep) {
+ if (boosted > settings.maxboostedstep) {
+ boosted = settings.maxboostedstep;
+ value = Math.round((value / boosted)) * boosted;
+ }
+ }
+
+ return Math.max(settings.step, boosted);
+ }
+ }
+
+ function upOnce() {
+ _checkValue();
+
+ value = parseFloat(elements.input.val());
+ if (isNaN(value)) {
+ value = 0;
+ }
+
+ var initvalue = value,
+ boostedstep = _getBoostedStep();
+
+ value = value + boostedstep;
+
+ if (value > settings.max) {
+ value = settings.max;
+ originalinput.trigger('touchspin.on.max');
+ stopSpin();
+ }
+
+ elements.input.val(Number(value).toFixed(settings.decimals));
+
+ if (initvalue !== value) {
+ originalinput.trigger('change');
+ }
+ }
+
+ function downOnce() {
+ _checkValue();
+
+ value = parseFloat(elements.input.val());
+ if (isNaN(value)) {
+ value = 0;
+ }
+
+ var initvalue = value,
+ boostedstep = _getBoostedStep();
+
+ value = value - boostedstep;
+
+ if (value < settings.min) {
+ value = settings.min;
+ originalinput.trigger('touchspin.on.min');
+ stopSpin();
+ }
+
+ elements.input.val(value.toFixed(settings.decimals));
+
+ if (initvalue !== value) {
+ originalinput.trigger('change');
+ }
+ }
+
+ function startDownSpin() {
+ stopSpin();
+
+ spincount = 0;
+ spinning = 'down';
+
+ originalinput.trigger('touchspin.on.startspin');
+ originalinput.trigger('touchspin.on.startdownspin');
+
+ downDelayTimeout = setTimeout(function() {
+ downSpinTimer = setInterval(function() {
+ spincount++;
+ downOnce();
+ }, settings.stepinterval);
+ }, settings.stepintervaldelay);
+ }
+
+ function startUpSpin() {
+ stopSpin();
+
+ spincount = 0;
+ spinning = 'up';
+
+ originalinput.trigger('touchspin.on.startspin');
+ originalinput.trigger('touchspin.on.startupspin');
+
+ upDelayTimeout = setTimeout(function() {
+ upSpinTimer = setInterval(function() {
+ spincount++;
+ upOnce();
+ }, settings.stepinterval);
+ }, settings.stepintervaldelay);
+ }
+
+ function stopSpin() {
+ clearTimeout(downDelayTimeout);
+ clearTimeout(upDelayTimeout);
+ clearInterval(downSpinTimer);
+ clearInterval(upSpinTimer);
+
+ switch (spinning) {
+ case 'up':
+ originalinput.trigger('touchspin.on.stopupspin');
+ originalinput.trigger('touchspin.on.stopspin');
+ break;
+ case 'down':
+ originalinput.trigger('touchspin.on.stopdownspin');
+ originalinput.trigger('touchspin.on.stopspin');
+ break;
+ }
+
+ spincount = 0;
+ spinning = false;
+ }
+
+ });
+
+ };
+
+})(jQuery);
diff --git a/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css
new file mode 100644
index 00000000..a376fb6b
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.css
@@ -0,0 +1,10 @@
+/*
+ * Bootstrap TouchSpin - v3.0.1
+ * A mobile and touch friendly input spinner component for Bootstrap 3.
+ * http://www.virtuosoft.eu/code/bootstrap-touchspin/
+ *
+ * Made by István Ujj-Mészáros
+ * Under Apache License v2.0 License
+ */
+
+.bootstrap-touchspin .input-group-btn-vertical{position:relative;white-space:nowrap;width:1%;vertical-align:middle;display:table-cell}.bootstrap-touchspin .input-group-btn-vertical>.btn{display:block;float:none;width:100%;max-width:100%;padding:8px 10px;margin-left:-1px;position:relative}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up{border-radius:0;border-top-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down{margin-top:-2px;border-radius:0;border-bottom-right-radius:4px}.bootstrap-touchspin .input-group-btn-vertical i{position:absolute;top:3px;left:5px;font-size:9px;font-weight:400}
\ No newline at end of file
diff --git a/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js
new file mode 100644
index 00000000..9e67a88b
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.min.js
@@ -0,0 +1,9 @@
+/*
+ * Bootstrap TouchSpin - v3.0.1
+ * A mobile and touch friendly input spinner component for Bootstrap 3.
+ * http://www.virtuosoft.eu/code/bootstrap-touchspin/
+ *
+ * Made by István Ujj-Mészáros
+ * Under Apache License v2.0 License
+ */
+!function(a){"use strict";function b(a,b){return a+".touchspin_"+b}function c(c,d){return a.map(c,function(a){return b(a,d)})}var d=0;a.fn.TouchSpin=function(b){if("destroy"===b)return void this.each(function(){var b=a(this),d=b.data();a(document).off(c(["mouseup","touchend","touchcancel","mousemove","touchmove","scroll","scrollstart"],d.spinnerid).join(" "))});var e={min:0,max:100,initval:"",step:1,decimals:0,stepinterval:100,forcestepdivisibility:"round",stepintervaldelay:500,verticalbuttons:!1,verticalupclass:"glyphicon glyphicon-chevron-up",verticaldownclass:"glyphicon glyphicon-chevron-down",prefix:"",postfix:"",prefix_extraclass:"",postfix_extraclass:"",booster:!0,boostat:10,maxboostedstep:!1,mousewheel:!0,buttondown_class:"btn btn-default",buttonup_class:"btn btn-default",buttondown_txt:"-",buttonup_txt:"+"},f={min:"min",max:"max",initval:"init-val",step:"step",decimals:"decimals",stepinterval:"step-interval",verticalbuttons:"vertical-buttons",verticalupclass:"vertical-up-class",verticaldownclass:"vertical-down-class",forcestepdivisibility:"force-step-divisibility",stepintervaldelay:"step-interval-delay",prefix:"prefix",postfix:"postfix",prefix_extraclass:"prefix-extra-class",postfix_extraclass:"postfix-extra-class",booster:"booster",boostat:"boostat",maxboostedstep:"max-boosted-step",mousewheel:"mouse-wheel",buttondown_class:"button-down-class",buttonup_class:"button-up-class",buttondown_txt:"button-down-txt",buttonup_txt:"button-up-txt"};return this.each(function(){function g(){if(!J.data("alreadyinitialized")){if(J.data("alreadyinitialized",!0),d+=1,J.data("spinnerid",d),!J.is("input"))return void console.log("Must be an input.");j(),h(),u(),m(),p(),q(),r(),s(),D.input.css("display","block")}}function h(){""!==B.initval&&""===J.val()&&J.val(B.initval)}function i(a){l(a),u();var b=D.input.val();""!==b&&(b=Number(D.input.val()),D.input.val(b.toFixed(B.decimals)))}function j(){B=a.extend({},e,K,k(),b)}function k(){var b={};return a.each(f,function(a,c){var d="bts-"+c;J.is("[data-"+d+"]")&&(b[a]=J.data(d))}),b}function l(b){B=a.extend({},B,b)}function m(){var a=J.val(),b=J.parent();""!==a&&(a=Number(a).toFixed(B.decimals)),J.data("initvalue",a).val(a),J.addClass("form-control"),b.hasClass("input-group")?n(b):o()}function n(b){b.addClass("bootstrap-touchspin");var c,d,e=J.prev(),f=J.next(),g=''+B.prefix+" ",h=''+B.postfix+" ";e.hasClass("input-group-btn")?(c=''+B.buttondown_txt+" ",e.append(c)):(c=''+B.buttondown_txt+" ",a(c).insertBefore(J)),f.hasClass("input-group-btn")?(d=''+B.buttonup_txt+" ",f.prepend(d)):(d=''+B.buttonup_txt+" ",a(d).insertAfter(J)),a(g).insertBefore(J),a(h).insertAfter(J),C=b}function o(){var b;b=B.verticalbuttons?''+B.prefix+' '+B.postfix+'
':''+B.buttondown_txt+' '+B.prefix+' '+B.postfix+' '+B.buttonup_txt+"
",C=a(b).insertBefore(J),a(".bootstrap-touchspin-prefix",C).after(J),J.hasClass("input-sm")?C.addClass("input-group-sm"):J.hasClass("input-lg")&&C.addClass("input-group-lg")}function p(){D={down:a(".bootstrap-touchspin-down",C),up:a(".bootstrap-touchspin-up",C),input:a("input",C),prefix:a(".bootstrap-touchspin-prefix",C).addClass(B.prefix_extraclass),postfix:a(".bootstrap-touchspin-postfix",C).addClass(B.postfix_extraclass)}}function q(){""===B.prefix&&D.prefix.hide(),""===B.postfix&&D.postfix.hide()}function r(){J.on("keydown",function(a){var b=a.keyCode||a.which;38===b?("up"!==M&&(w(),z()),a.preventDefault()):40===b&&("down"!==M&&(x(),y()),a.preventDefault())}),J.on("keyup",function(a){var b=a.keyCode||a.which;38===b?A():40===b&&A()}),J.on("blur",function(){u()}),D.down.on("keydown",function(a){var b=a.keyCode||a.which;(32===b||13===b)&&("down"!==M&&(x(),y()),a.preventDefault())}),D.down.on("keyup",function(a){var b=a.keyCode||a.which;(32===b||13===b)&&A()}),D.up.on("keydown",function(a){var b=a.keyCode||a.which;(32===b||13===b)&&("up"!==M&&(w(),z()),a.preventDefault())}),D.up.on("keyup",function(a){var b=a.keyCode||a.which;(32===b||13===b)&&A()}),D.down.on("mousedown.touchspin",function(a){D.down.off("touchstart.touchspin"),J.is(":disabled")||(x(),y(),a.preventDefault(),a.stopPropagation())}),D.down.on("touchstart.touchspin",function(a){D.down.off("mousedown.touchspin"),J.is(":disabled")||(x(),y(),a.preventDefault(),a.stopPropagation())}),D.up.on("mousedown.touchspin",function(a){D.up.off("touchstart.touchspin"),J.is(":disabled")||(w(),z(),a.preventDefault(),a.stopPropagation())}),D.up.on("touchstart.touchspin",function(a){D.up.off("mousedown.touchspin"),J.is(":disabled")||(w(),z(),a.preventDefault(),a.stopPropagation())}),D.up.on("mouseout touchleave touchend touchcancel",function(a){M&&(a.stopPropagation(),A())}),D.down.on("mouseout touchleave touchend touchcancel",function(a){M&&(a.stopPropagation(),A())}),D.down.on("mousemove touchmove",function(a){M&&(a.stopPropagation(),a.preventDefault())}),D.up.on("mousemove touchmove",function(a){M&&(a.stopPropagation(),a.preventDefault())}),a(document).on(c(["mouseup","touchend","touchcancel"],d).join(" "),function(a){M&&(a.preventDefault(),A())}),a(document).on(c(["mousemove","touchmove","scroll","scrollstart"],d).join(" "),function(a){M&&(a.preventDefault(),A())}),J.on("mousewheel DOMMouseScroll",function(a){if(B.mousewheel&&J.is(":focus")){var b=a.originalEvent.wheelDelta||-a.originalEvent.deltaY||-a.originalEvent.detail;a.stopPropagation(),a.preventDefault(),0>b?x():w()}})}function s(){J.on("touchspin.uponce",function(){A(),w()}),J.on("touchspin.downonce",function(){A(),x()}),J.on("touchspin.startupspin",function(){z()}),J.on("touchspin.startdownspin",function(){y()}),J.on("touchspin.stopspin",function(){A()}),J.on("touchspin.updatesettings",function(a,b){i(b)})}function t(a){switch(B.forcestepdivisibility){case"round":return(Math.round(a/B.step)*B.step).toFixed(B.decimals);case"floor":return(Math.floor(a/B.step)*B.step).toFixed(B.decimals);case"ceil":return(Math.ceil(a/B.step)*B.step).toFixed(B.decimals);default:return a}}function u(){var a,b,c;a=J.val(),""!==a&&(B.decimals>0&&"."===a||(b=parseFloat(a),isNaN(b)&&(b=0),c=b,b.toString()!==a&&(c=b),bB.max&&(c=B.max),c=t(c),Number(a).toString()!==c.toString()&&(J.val(c),J.trigger("change"))))}function v(){if(B.booster){var a=Math.pow(2,Math.floor(L/B.boostat))*B.step;return B.maxboostedstep&&a>B.maxboostedstep&&(a=B.maxboostedstep,E=Math.round(E/a)*a),Math.max(B.step,a)}return B.step}function w(){u(),E=parseFloat(D.input.val()),isNaN(E)&&(E=0);var a=E,b=v();E+=b,E>B.max&&(E=B.max,J.trigger("touchspin.on.max"),A()),D.input.val(Number(E).toFixed(B.decimals)),a!==E&&J.trigger("change")}function x(){u(),E=parseFloat(D.input.val()),isNaN(E)&&(E=0);var a=E,b=v();E-=b,E .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ max-width: 100%;
+ padding: 8px 10px;
+ margin-left: -1px;
+ position: relative;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-up {
+ border-radius: 0;
+ border-top-right-radius: 4px;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical .bootstrap-touchspin-down {
+ margin-top: -2px;
+ border-radius: 0;
+ border-bottom-right-radius: 4px;
+}
+
+.bootstrap-touchspin .input-group-btn-vertical i {
+ position: absolute;
+ top: 3px;
+ left: 5px;
+ font-size: 9px;
+ font-weight: normal;
+}
diff --git a/public/vendor/bootstrap-touchspin/src/jquery.bootstrap-touchspin.js b/public/vendor/bootstrap-touchspin/src/jquery.bootstrap-touchspin.js
new file mode 100644
index 00000000..f5752c3b
--- /dev/null
+++ b/public/vendor/bootstrap-touchspin/src/jquery.bootstrap-touchspin.js
@@ -0,0 +1,689 @@
+(function($) {
+ 'use strict';
+
+ var _currentSpinnerId = 0;
+
+ function _scopedEventName(name, id) {
+ return name + '.touchspin_' + id;
+ }
+
+ function _scopeEventNames(names, id) {
+ return $.map(names, function(name) {
+ return _scopedEventName(name, id);
+ });
+ }
+
+ $.fn.TouchSpin = function(options) {
+
+ if (options === 'destroy') {
+ this.each(function() {
+ var originalinput = $(this),
+ originalinput_data = originalinput.data();
+ $(document).off(_scopeEventNames([
+ 'mouseup',
+ 'touchend',
+ 'touchcancel',
+ 'mousemove',
+ 'touchmove',
+ 'scroll',
+ 'scrollstart'], originalinput_data.spinnerid).join(' '));
+ });
+ return;
+ }
+
+ var defaults = {
+ min: 0,
+ max: 100,
+ initval: '',
+ replacementval: '',
+ step: 1,
+ decimals: 0,
+ stepinterval: 100,
+ forcestepdivisibility: 'round', // none | floor | round | ceil
+ stepintervaldelay: 500,
+ verticalbuttons: false,
+ verticalupclass: 'glyphicon glyphicon-chevron-up',
+ verticaldownclass: 'glyphicon glyphicon-chevron-down',
+ prefix: '',
+ postfix: '',
+ prefix_extraclass: '',
+ postfix_extraclass: '',
+ booster: true,
+ boostat: 10,
+ maxboostedstep: false,
+ mousewheel: true,
+ buttondown_class: 'btn btn-default',
+ buttonup_class: 'btn btn-default',
+ buttondown_txt: '-',
+ buttonup_txt: '+'
+ };
+
+ var attributeMap = {
+ min: 'min',
+ max: 'max',
+ initval: 'init-val',
+ replacementval: 'replacement-val',
+ step: 'step',
+ decimals: 'decimals',
+ stepinterval: 'step-interval',
+ verticalbuttons: 'vertical-buttons',
+ verticalupclass: 'vertical-up-class',
+ verticaldownclass: 'vertical-down-class',
+ forcestepdivisibility: 'force-step-divisibility',
+ stepintervaldelay: 'step-interval-delay',
+ prefix: 'prefix',
+ postfix: 'postfix',
+ prefix_extraclass: 'prefix-extra-class',
+ postfix_extraclass: 'postfix-extra-class',
+ booster: 'booster',
+ boostat: 'boostat',
+ maxboostedstep: 'max-boosted-step',
+ mousewheel: 'mouse-wheel',
+ buttondown_class: 'button-down-class',
+ buttonup_class: 'button-up-class',
+ buttondown_txt: 'button-down-txt',
+ buttonup_txt: 'button-up-txt'
+ };
+
+ return this.each(function() {
+
+ var settings,
+ originalinput = $(this),
+ originalinput_data = originalinput.data(),
+ container,
+ elements,
+ value,
+ downSpinTimer,
+ upSpinTimer,
+ downDelayTimeout,
+ upDelayTimeout,
+ spincount = 0,
+ spinning = false;
+
+ init();
+
+
+ function init() {
+ if (originalinput.data('alreadyinitialized')) {
+ return;
+ }
+
+ originalinput.data('alreadyinitialized', true);
+ _currentSpinnerId += 1;
+ originalinput.data('spinnerid', _currentSpinnerId);
+
+
+ if (!originalinput.is('input')) {
+ console.log('Must be an input.');
+ return;
+ }
+
+ _initSettings();
+ _setInitval();
+ _checkValue();
+ _buildHtml();
+ _initElements();
+ _hideEmptyPrefixPostfix();
+ _bindEvents();
+ _bindEventsInterface();
+ elements.input.css('display', 'block');
+ }
+
+ function _setInitval() {
+ if (settings.initval !== '' && originalinput.val() === '') {
+ originalinput.val(settings.initval);
+ }
+ }
+
+ function changeSettings(newsettings) {
+ _updateSettings(newsettings);
+ _checkValue();
+
+ var value = elements.input.val();
+
+ if (value !== '') {
+ value = Number(elements.input.val());
+ elements.input.val(value.toFixed(settings.decimals));
+ }
+ }
+
+ function _initSettings() {
+ settings = $.extend({}, defaults, originalinput_data, _parseAttributes(), options);
+ }
+
+ function _parseAttributes() {
+ var data = {};
+ $.each(attributeMap, function(key, value) {
+ var attrName = 'bts-' + value + '';
+ if (originalinput.is('[data-' + attrName + ']')) {
+ data[key] = originalinput.data(attrName);
+ }
+ });
+ return data;
+ }
+
+ function _updateSettings(newsettings) {
+ settings = $.extend({}, settings, newsettings);
+ }
+
+ function _buildHtml() {
+ var initval = originalinput.val(),
+ parentelement = originalinput.parent();
+
+ if (initval !== '') {
+ initval = Number(initval).toFixed(settings.decimals);
+ }
+
+ originalinput.data('initvalue', initval).val(initval);
+ originalinput.addClass('form-control');
+
+ if (parentelement.hasClass('input-group')) {
+ _advanceInputGroup(parentelement);
+ }
+ else {
+ _buildInputGroup();
+ }
+ }
+
+ function _advanceInputGroup(parentelement) {
+ parentelement.addClass('bootstrap-touchspin');
+
+ var prev = originalinput.prev(),
+ next = originalinput.next();
+
+ var downhtml,
+ uphtml,
+ prefixhtml = '' + settings.prefix + ' ',
+ postfixhtml = '' + settings.postfix + ' ';
+
+ if (prev.hasClass('input-group-btn')) {
+ downhtml = '' + settings.buttondown_txt + ' ';
+ prev.append(downhtml);
+ }
+ else {
+ downhtml = '' + settings.buttondown_txt + ' ';
+ $(downhtml).insertBefore(originalinput);
+ }
+
+ if (next.hasClass('input-group-btn')) {
+ uphtml = '' + settings.buttonup_txt + ' ';
+ next.prepend(uphtml);
+ }
+ else {
+ uphtml = '' + settings.buttonup_txt + ' ';
+ $(uphtml).insertAfter(originalinput);
+ }
+
+ $(prefixhtml).insertBefore(originalinput);
+ $(postfixhtml).insertAfter(originalinput);
+
+ container = parentelement;
+ }
+
+ function _buildInputGroup() {
+ var html;
+
+ if (settings.verticalbuttons) {
+ html = '' + settings.prefix + ' ' + settings.postfix + '
';
+ }
+ else {
+ html = '' + settings.buttondown_txt + ' ' + settings.prefix + ' ' + settings.postfix + ' ' + settings.buttonup_txt + '
';
+ }
+
+ container = $(html).insertBefore(originalinput);
+
+ $('.bootstrap-touchspin-prefix', container).after(originalinput);
+
+ if (originalinput.hasClass('input-sm')) {
+ container.addClass('input-group-sm');
+ }
+ else if (originalinput.hasClass('input-lg')) {
+ container.addClass('input-group-lg');
+ }
+ }
+
+ function _initElements() {
+ elements = {
+ down: $('.bootstrap-touchspin-down', container),
+ up: $('.bootstrap-touchspin-up', container),
+ input: $('input', container),
+ prefix: $('.bootstrap-touchspin-prefix', container).addClass(settings.prefix_extraclass),
+ postfix: $('.bootstrap-touchspin-postfix', container).addClass(settings.postfix_extraclass)
+ };
+ }
+
+ function _hideEmptyPrefixPostfix() {
+ if (settings.prefix === '') {
+ elements.prefix.hide();
+ }
+
+ if (settings.postfix === '') {
+ elements.postfix.hide();
+ }
+ }
+
+ function _bindEvents() {
+ originalinput.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 38) {
+ if (spinning !== 'up') {
+ upOnce();
+ startUpSpin();
+ }
+ ev.preventDefault();
+ }
+ else if (code === 40) {
+ if (spinning !== 'down') {
+ downOnce();
+ startDownSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ originalinput.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 38) {
+ stopSpin();
+ }
+ else if (code === 40) {
+ stopSpin();
+ }
+ });
+
+ originalinput.on('blur', function() {
+ _checkValue();
+ });
+
+ elements.down.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ if (spinning !== 'down') {
+ downOnce();
+ startDownSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ elements.down.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ stopSpin();
+ }
+ });
+
+ elements.up.on('keydown', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ if (spinning !== 'up') {
+ upOnce();
+ startUpSpin();
+ }
+ ev.preventDefault();
+ }
+ });
+
+ elements.up.on('keyup', function(ev) {
+ var code = ev.keyCode || ev.which;
+
+ if (code === 32 || code === 13) {
+ stopSpin();
+ }
+ });
+
+ elements.down.on('mousedown.touchspin', function(ev) {
+ elements.down.off('touchstart.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ downOnce();
+ startDownSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.down.on('touchstart.touchspin', function(ev) {
+ elements.down.off('mousedown.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ downOnce();
+ startDownSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('mousedown.touchspin', function(ev) {
+ elements.up.off('touchstart.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ upOnce();
+ startUpSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('touchstart.touchspin', function(ev) {
+ elements.up.off('mousedown.touchspin'); // android 4 workaround
+
+ if (originalinput.is(':disabled')) {
+ return;
+ }
+
+ upOnce();
+ startUpSpin();
+
+ ev.preventDefault();
+ ev.stopPropagation();
+ });
+
+ elements.up.on('mouseout touchleave touchend touchcancel', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ stopSpin();
+ });
+
+ elements.down.on('mouseout touchleave touchend touchcancel', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ stopSpin();
+ });
+
+ elements.down.on('mousemove touchmove', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ ev.preventDefault();
+ });
+
+ elements.up.on('mousemove touchmove', function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.stopPropagation();
+ ev.preventDefault();
+ });
+
+ $(document).on(_scopeEventNames(['mouseup', 'touchend', 'touchcancel'], _currentSpinnerId).join(' '), function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.preventDefault();
+ stopSpin();
+ });
+
+ $(document).on(_scopeEventNames(['mousemove', 'touchmove', 'scroll', 'scrollstart'], _currentSpinnerId).join(' '), function(ev) {
+ if (!spinning) {
+ return;
+ }
+
+ ev.preventDefault();
+ stopSpin();
+ });
+
+ originalinput.on('mousewheel DOMMouseScroll', function(ev) {
+ if (!settings.mousewheel || !originalinput.is(':focus')) {
+ return;
+ }
+
+ var delta = ev.originalEvent.wheelDelta || -ev.originalEvent.deltaY || -ev.originalEvent.detail;
+
+ ev.stopPropagation();
+ ev.preventDefault();
+
+ if (delta < 0) {
+ downOnce();
+ }
+ else {
+ upOnce();
+ }
+ });
+ }
+
+ function _bindEventsInterface() {
+ originalinput.on('touchspin.uponce', function() {
+ stopSpin();
+ upOnce();
+ });
+
+ originalinput.on('touchspin.downonce', function() {
+ stopSpin();
+ downOnce();
+ });
+
+ originalinput.on('touchspin.startupspin', function() {
+ startUpSpin();
+ });
+
+ originalinput.on('touchspin.startdownspin', function() {
+ startDownSpin();
+ });
+
+ originalinput.on('touchspin.stopspin', function() {
+ stopSpin();
+ });
+
+ originalinput.on('touchspin.updatesettings', function(e, newsettings) {
+ changeSettings(newsettings);
+ });
+ }
+
+ function _forcestepdivisibility(value) {
+ switch (settings.forcestepdivisibility) {
+ case 'round':
+ return (Math.round(value / settings.step) * settings.step).toFixed(settings.decimals);
+ case 'floor':
+ return (Math.floor(value / settings.step) * settings.step).toFixed(settings.decimals);
+ case 'ceil':
+ return (Math.ceil(value / settings.step) * settings.step).toFixed(settings.decimals);
+ default:
+ return value;
+ }
+ }
+
+ function _checkValue() {
+ var val, parsedval, returnval;
+
+ val = originalinput.val();
+
+ if (val === '') {
+ if (settings.replacementval !== '') {
+ originalinput.val(settings.replacementval);
+ originalinput.trigger('change');
+ }
+ return;
+ }
+
+ if (settings.decimals > 0 && val === '.') {
+ return;
+ }
+
+ parsedval = parseFloat(val);
+
+ if (isNaN(parsedval)) {
+ if (settings.replacementval !== '') {
+ parsedval = settings.replacementval;
+ }
+ else {
+ parsedval = 0;
+ }
+ }
+
+ returnval = parsedval;
+
+ if (parsedval.toString() !== val) {
+ returnval = parsedval;
+ }
+
+ if (parsedval < settings.min) {
+ returnval = settings.min;
+ }
+
+ if (parsedval > settings.max) {
+ returnval = settings.max;
+ }
+
+ returnval = _forcestepdivisibility(returnval);
+
+ if (Number(val).toString() !== returnval.toString()) {
+ originalinput.val(returnval);
+ originalinput.trigger('change');
+ }
+ }
+
+ function _getBoostedStep() {
+ if (!settings.booster) {
+ return settings.step;
+ }
+ else {
+ var boosted = Math.pow(2, Math.floor(spincount / settings.boostat)) * settings.step;
+
+ if (settings.maxboostedstep) {
+ if (boosted > settings.maxboostedstep) {
+ boosted = settings.maxboostedstep;
+ value = Math.round((value / boosted)) * boosted;
+ }
+ }
+
+ return Math.max(settings.step, boosted);
+ }
+ }
+
+ function upOnce() {
+ _checkValue();
+
+ value = parseFloat(elements.input.val());
+ if (isNaN(value)) {
+ value = 0;
+ }
+
+ var initvalue = value,
+ boostedstep = _getBoostedStep();
+
+ value = value + boostedstep;
+
+ if (value > settings.max) {
+ value = settings.max;
+ originalinput.trigger('touchspin.on.max');
+ stopSpin();
+ }
+
+ elements.input.val(Number(value).toFixed(settings.decimals));
+
+ if (initvalue !== value) {
+ originalinput.trigger('change');
+ }
+ }
+
+ function downOnce() {
+ _checkValue();
+
+ value = parseFloat(elements.input.val());
+ if (isNaN(value)) {
+ value = 0;
+ }
+
+ var initvalue = value,
+ boostedstep = _getBoostedStep();
+
+ value = value - boostedstep;
+
+ if (value < settings.min) {
+ value = settings.min;
+ originalinput.trigger('touchspin.on.min');
+ stopSpin();
+ }
+
+ elements.input.val(value.toFixed(settings.decimals));
+
+ if (initvalue !== value) {
+ originalinput.trigger('change');
+ }
+ }
+
+ function startDownSpin() {
+ stopSpin();
+
+ spincount = 0;
+ spinning = 'down';
+
+ originalinput.trigger('touchspin.on.startspin');
+ originalinput.trigger('touchspin.on.startdownspin');
+
+ downDelayTimeout = setTimeout(function() {
+ downSpinTimer = setInterval(function() {
+ spincount++;
+ downOnce();
+ }, settings.stepinterval);
+ }, settings.stepintervaldelay);
+ }
+
+ function startUpSpin() {
+ stopSpin();
+
+ spincount = 0;
+ spinning = 'up';
+
+ originalinput.trigger('touchspin.on.startspin');
+ originalinput.trigger('touchspin.on.startupspin');
+
+ upDelayTimeout = setTimeout(function() {
+ upSpinTimer = setInterval(function() {
+ spincount++;
+ upOnce();
+ }, settings.stepinterval);
+ }, settings.stepintervaldelay);
+ }
+
+ function stopSpin() {
+ clearTimeout(downDelayTimeout);
+ clearTimeout(upDelayTimeout);
+ clearInterval(downSpinTimer);
+ clearInterval(upSpinTimer);
+
+ switch (spinning) {
+ case 'up':
+ originalinput.trigger('touchspin.on.stopupspin');
+ originalinput.trigger('touchspin.on.stopspin');
+ break;
+ case 'down':
+ originalinput.trigger('touchspin.on.stopdownspin');
+ originalinput.trigger('touchspin.on.stopspin');
+ break;
+ }
+
+ spincount = 0;
+ spinning = false;
+ }
+
+ });
+
+ };
+
+})(jQuery);