');\n\n if (this.el.nodeName == 'INPUT') {\n if (!this.opts.inline) {\n $appendTarget = $datepickersContainer;\n } else {\n $appendTarget = $inline.insertAfter(this.$el);\n }\n } else {\n $appendTarget = $inline.appendTo(this.$el);\n }\n\n this.$datepicker = $(baseTemplate).appendTo($appendTarget);\n this.$content = $('.datepicker--content', this.$datepicker);\n this.$nav = $('.datepicker--nav', this.$datepicker);\n },\n\n _triggerOnChange: function() {\n if (!this.selectedDates.length) {\n return this.opts.onSelect('', '', this);\n }\n\n var selectedDates = this.selectedDates;\n var parsedSelected = datepicker.getParsedDate(selectedDates[0]);\n var formattedDates;\n var _this = this;\n var dates = new Date(parsedSelected.year, parsedSelected.month, parsedSelected.date);\n\n formattedDates = selectedDates.map(function(date) {\n return _this.formatDate(_this.loc.dateFormat, date);\n }).join(this.opts.multipleDatesSeparator);\n\n // Create new dates array, to separate it from original selectedDates\n if (this.opts.multipleDates) {\n dates = selectedDates.map(function(date) {\n var parsedDate = datepicker.getParsedDate(date);\n\n return new Date(parsedDate.year, parsedDate.month, parsedDate.date);\n });\n }\n\n this.opts.onSelect(formattedDates, dates, this);\n },\n\n next: function() {\n var d = this.parsedDate;\n var o = this.opts;\n\n switch (this.view) {\n case 'days':\n this.date = new Date(d.year, d.month + 1, 1);\n if (o.onChangeMonth) o.onChangeMonth(this.parsedDate.month, this.parsedDate.year);\n break;\n case 'months':\n this.date = new Date(d.year + 1, d.month, 1);\n if (o.onChangeYear) o.onChangeYear(this.parsedDate.year);\n break;\n case 'years':\n this.date = new Date(d.year + 10, 0, 1);\n if (o.onChangeDecade) o.onChangeDecade(this.curDecade);\n break;\n }\n },\n\n prev: function() {\n var d = this.parsedDate;\n var o = this.opts;\n\n switch (this.view) {\n case 'days':\n this.date = new Date(d.year, d.month - 1, 1);\n if (o.onChangeMonth) o.onChangeMonth(this.parsedDate.month, this.parsedDate.year);\n break;\n case 'months':\n this.date = new Date(d.year - 1, d.month, 1);\n if (o.onChangeYear) o.onChangeYear(this.parsedDate.year);\n break;\n case 'years':\n this.date = new Date(d.year - 10, 0, 1);\n if (o.onChangeDecade) o.onChangeDecade(this.curDecade);\n break;\n }\n },\n\n formatDate: function(string, date) {\n date = date || this.date;\n var result = string;\n var boundary = this._getWordBoundaryRegExp;\n var locale = this.loc;\n var decade = datepicker.getDecade(date);\n var d = datepicker.getParsedDate(date);\n\n switch (true) {\n case (/@/).test(result):\n result = result.replace(/@/, date.getTime());\n // falls through\n case (/dd/).test(result):\n result = result.replace(boundary('dd'), d.fullDate);\n // falls through\n case (/d/).test(result):\n result = result.replace(boundary('d'), d.date);\n // falls through\n case (/DD/).test(result):\n result = result.replace(boundary('DD'), locale.days[d.day]);\n // falls through\n case (/D/).test(result):\n result = result.replace(boundary('D'), locale.daysShort[d.day]);\n // falls through\n case (/mm/).test(result):\n result = result.replace(boundary('mm'), d.fullMonth);\n // falls through\n case (/m/).test(result):\n result = result.replace(boundary('m'), d.month + 1);\n // falls through\n case (/MM/).test(result):\n result = result.replace(boundary('MM'), this.loc.months[d.month]);\n // falls through\n case (/M/).test(result):\n result = result.replace(boundary('M'), locale.monthsShort[d.month]);\n // falls through\n case (/yyyy/).test(result):\n result = result.replace(boundary('yyyy'), d.year);\n // falls through\n case (/yyyy1/).test(result):\n result = result.replace(boundary('yyyy1'), decade[0]);\n // falls through\n case (/yyyy2/).test(result):\n result = result.replace(boundary('yyyy2'), decade[1]);\n // falls through\n case (/yy/).test(result):\n result = result.replace(boundary('yy'), d.year.toString().slice(-2));\n }\n\n return result;\n },\n\n _getWordBoundaryRegExp: function(sign) {\n return new RegExp('\\\\b(?=[a-zA-Z0-9äöüßÄÖÜ<])' + sign + '(?![>a-zA-Z0-9äöüßÄÖÜ])');\n },\n\n selectDate: function(date) {\n var _this = this;\n var opts = _this.opts;\n var d = _this.parsedDate;\n var selectedDates = _this.selectedDates;\n var len = selectedDates.length;\n var newDate = '';\n\n if (!(date instanceof Date)) return;\n\n if (_this.view == 'days') {\n if ((date.getMonth() != d.month || date.getFullYear() != d.year) && opts.moveToOtherMonthsOnSelect) {\n newDate = new Date(date.getFullYear(), date.getMonth(), 1);\n }\n }\n\n if (_this.view == 'years') {\n if (date.getFullYear() != d.year && opts.moveToOtherYearsOnSelect) {\n newDate = new Date(date.getFullYear(), 0, 1);\n }\n }\n\n if (newDate) {\n _this.silent = true;\n _this.date = newDate;\n _this.silent = false;\n _this.nav._render();\n }\n\n if (opts.multipleDates) {\n if (len === opts.multipleDates) return;\n if (!_this._isSelected(date)) {\n _this.selectedDates.push(date);\n }\n } else if (opts.range) {\n if (len == 2) {\n _this.selectedDates = [date];\n _this.minRange = date;\n _this.maxRange = '';\n } else if (len == 1) {\n _this.selectedDates.push(date);\n if (!_this.maxRange) {\n _this.maxRange = date;\n } else {\n _this.minRange = date;\n }\n _this.selectedDates = [_this.minRange, _this.maxRange];\n } else {\n _this.selectedDates = [date];\n _this.minRange = date;\n }\n } else {\n _this.selectedDates = [date];\n }\n\n _this._setInputValue();\n\n if (opts.onSelect && opts.minView == this.currentView) {\n _this._triggerOnChange();\n }\n\n if (opts.autoClose) {\n if (!opts.multipleDates && !opts.range) {\n _this.hide();\n } else if (opts.range && _this.selectedDates.length == 2) {\n _this.hide();\n }\n }\n\n _this.views[this.currentView]._render();\n },\n\n removeDate: function(date) {\n var selected = this.selectedDates;\n var _this = this;\n\n if (!(date instanceof Date)) return;\n\n return selected.some(function(curDate, i) {\n if (datepicker.isSame(curDate, date)) {\n selected.splice(i, 1);\n\n if (!_this.selectedDates.length) {\n _this.minRange = '';\n _this.maxRange = '';\n }\n\n _this.views[_this.currentView]._render();\n _this._setInputValue();\n\n if (_this.opts.onSelect) {\n _this._triggerOnChange();\n }\n\n return true;\n }\n });\n },\n\n today: function() {\n this.silent = true;\n this.view = this.opts.minView;\n this.silent = false;\n this.date = new Date();\n },\n\n clear: function() {\n this.selectedDates = [];\n this.minRange = '';\n this.maxRange = '';\n this.views[this.currentView]._render();\n this._setInputValue();\n if (this.opts.onSelect) {\n this._triggerOnChange();\n }\n },\n\n /**\n * Updates datepicker options\n * @param {String|Object} param - parameter's name to update. If object then it will extend current options\n * @param {String|Number|Object} [value] - new param value\n */\n update: function(param, value) {\n var len = arguments.length;\n\n if (len == 2) {\n this.opts[param] = value;\n } else if (len == 1 && typeof param == 'object') {\n this.opts = $.extend(true, this.opts, param);\n }\n\n this._createShortCuts();\n this._syncWithMinMaxDates();\n this._defineLocale(this.opts.language);\n this.nav._addButtonsIfNeed();\n this.nav._render();\n this.views[this.currentView]._render();\n\n if (this.elIsInput && !this.opts.inline) {\n this._setPositionClasses(this.opts.position);\n if (this.visible) {\n this.setPosition(this.opts.position);\n }\n }\n\n if (this.opts.classes) {\n this.$datepicker.addClass(this.opts.classes);\n }\n\n return this;\n },\n\n _syncWithMinMaxDates: function() {\n var curTime = this.date.getTime();\n\n this.silent = true;\n if (this.minTime > curTime) {\n this.date = this.minDate;\n }\n\n if (this.maxTime < curTime) {\n this.date = this.maxDate;\n }\n this.silent = false;\n },\n\n _isSelected: function(checkDate, cellType) {\n return this.selectedDates.some(function(date) {\n return datepicker.isSame(date, checkDate, cellType);\n });\n },\n\n _setInputValue: function() {\n var _this = this;\n var format = this.loc.dateFormat;\n var altFormat = this.opts.altFieldDateFormat;\n var value = this.selectedDates.map(function(date) {\n return _this.formatDate(format, date);\n });\n var altValues;\n\n if (this.$altField) {\n altValues = this.selectedDates.map(function(date) {\n return _this.formatDate(altFormat, date);\n });\n altValues = altValues.join(this.opts.multipleDatesSeparator);\n this.$altField.val(altValues);\n }\n\n value = value.join(this.opts.multipleDatesSeparator);\n\n this.$el.val(value);\n },\n\n /**\n * Check if date is between minDate and maxDate\n * @param date {object} - date object\n * @param type {string} - cell type\n * @returns {boolean}\n * @private\n */\n _isInRange: function(date, type) {\n var time = date.getTime();\n var d = datepicker.getParsedDate(date);\n var min = datepicker.getParsedDate(this.minDate);\n var max = datepicker.getParsedDate(this.maxDate);\n var dMinTime = new Date(d.year, d.month, min.date).getTime();\n var dMaxTime = new Date(d.year, d.month, max.date).getTime();\n var types = {\n day: time >= this.minTime && time <= this.maxTime,\n month: dMinTime >= this.minTime && dMaxTime <= this.maxTime,\n year: d.year >= min.year && d.year <= max.year\n };\n\n return type ? types[type] : types.day;\n },\n\n _getDimensions: function($el) {\n var offset = $el.offset();\n\n return {\n width: $el.outerWidth(),\n height: $el.outerHeight(),\n left: offset.left,\n top: offset.top\n };\n },\n\n _getDateFromCell: function(cell) {\n var curDate = this.parsedDate;\n var year = cell.data('year') || curDate.year;\n var month = cell.data('month') == undefined ? curDate.month : cell.data('month');\n var date = cell.data('date') || 1;\n\n return new Date(year, month, date);\n },\n\n _setPositionClasses: function(pos) {\n pos = pos.split(' ');\n var main = pos[0];\n var sec = pos[1];\n var classes = 'datepicker -' + main + '-' + sec + '- -from-' + main + '-';\n\n if (this.visible) classes += ' active';\n\n this.$datepicker\n .removeAttr('class')\n .addClass(classes);\n },\n\n setPosition: function(position) {\n position = position || this.opts.position;\n\n var dims = this._getDimensions(this.$el);\n var selfDims = this._getDimensions(this.$datepicker);\n var pos = position.split(' ');\n var top;\n var left;\n var offset = this.opts.offset;\n var main = pos[0];\n var secondary = pos[1];\n var pointerRight = 3;\n var bodyRect;\n var elRect;\n\n switch (main) {\n case 'top':\n top = dims.top - selfDims.height - offset;\n break;\n case 'right':\n left = dims.left + dims.width + offset;\n break;\n case 'bottom':\n top = dims.top + dims.height + offset;\n break;\n case 'left':\n left = dims.left - selfDims.width - offset;\n break;\n }\n\n switch (secondary) {\n case 'top':\n top = dims.top;\n break;\n case 'right':\n left = dims.left + dims.width - selfDims.width;\n break;\n case 'bottom':\n top = dims.top + dims.height - selfDims.height;\n break;\n case 'left':\n left = dims.left;\n break;\n case 'center':\n if (/left|right/.test(main)) {\n top = dims.top + dims.height / 2 - selfDims.height / 2;\n } else {\n left = dims.left + dims.width / 2 - selfDims.width / 2;\n }\n }\n\n bodyRect = $('body')[0].getBoundingClientRect();\n elRect = this.$el[0].getBoundingClientRect();\n\n if ((elRect.right + 15) < bodyRect.right) {\n left += 15;\n pointerRight += 15;\n }\n\n $(this.$datepicker[0].firstChild).css({\n right: pointerRight\n });\n this.$datepicker.css({\n left: left,\n top: top\n });\n },\n\n show: function() {\n this.setPosition(this.opts.position);\n this.$datepicker.addClass('active');\n this.visible = true;\n\n if ($('body').hasClass('scroll-disabled')) {\n this.$el.parents().on('scroll', this._onResize.bind(this));\n }\n },\n\n hide: function() {\n this.$datepicker\n .removeClass('active')\n .css({\n left: '-10000px'\n });\n\n this.focused = '';\n this.keys = [];\n\n this.inFocus = false;\n this.visible = false;\n this.$el.blur();\n\n if ($('body').hasClass('scroll-disabled')) {\n this.$el.parents().off('scroll', this._onResize.bind(this));\n }\n },\n\n down: function(date) {\n this._changeView(date, 'down');\n },\n\n up: function(date) {\n this._changeView(date, 'up');\n },\n\n _changeView: function(date, dir) {\n date = date || this.focused || this.date;\n\n var nextView = dir == 'up' ? this.viewIndex + 1 : this.viewIndex - 1;\n\n if (nextView > 2) nextView = 2;\n if (nextView < 0) nextView = 0;\n\n this.silent = true;\n this.date = new Date(date.getFullYear(), date.getMonth(), 1);\n this.silent = false;\n this.view = this.viewIndexes[nextView];\n },\n\n _handleHotKey: function(key) {\n var date = datepicker.getParsedDate(this._getFocusedDate());\n var focusedParsed;\n var o = this.opts;\n var newDate;\n var totalDaysInNextMonth;\n var monthChanged = false;\n var yearChanged = false;\n var decadeChanged = false;\n var y = date.year;\n var m = date.month;\n var d = date.date;\n\n switch (key) {\n case 'ctrlRight':\n case 'ctrlUp':\n m += 1;\n monthChanged = true;\n break;\n case 'ctrlLeft':\n case 'ctrlDown':\n m -= 1;\n monthChanged = true;\n break;\n case 'shiftRight':\n case 'shiftUp':\n yearChanged = true;\n y += 1;\n break;\n case 'shiftLeft':\n case 'shiftDown':\n yearChanged = true;\n y -= 1;\n break;\n case 'altRight':\n case 'altUp':\n decadeChanged = true;\n y += 10;\n break;\n case 'altLeft':\n case 'altDown':\n decadeChanged = true;\n y -= 10;\n break;\n case 'ctrlShiftUp':\n this.up();\n break;\n }\n\n totalDaysInNextMonth = datepicker.getDaysCount(new Date(y, m));\n newDate = new Date(y, m, d);\n\n // If next month has less days than current, set date to total days in that month\n if (totalDaysInNextMonth < d) d = totalDaysInNextMonth;\n\n // Check if newDate is in valid range\n if (newDate.getTime() < this.minTime) {\n newDate = this.minDate;\n } else if (newDate.getTime() > this.maxTime) {\n newDate = this.maxDate;\n }\n\n this.focused = newDate;\n\n focusedParsed = datepicker.getParsedDate(newDate);\n if (monthChanged && o.onChangeMonth) {\n o.onChangeMonth(focusedParsed.month, focusedParsed.year);\n }\n if (yearChanged && o.onChangeYear) {\n o.onChangeYear(focusedParsed.year);\n }\n if (decadeChanged && o.onChangeDecade) {\n o.onChangeDecade(this.curDecade);\n }\n },\n\n _registerKey: function(key) {\n var exists = this.keys.some(function(curKey) {\n return curKey == key;\n });\n\n if (!exists) {\n this.keys.push(key);\n }\n },\n\n _unRegisterKey: function(key) {\n var index = this.keys.indexOf(key);\n\n this.keys.splice(index, 1);\n },\n\n _isHotKeyPressed: function() {\n var currentHotKey;\n var found = false;\n var _this = this;\n var pressedKeys = this.keys.sort();\n\n for (var hotKey in hotKeys) {\n currentHotKey = hotKeys[hotKey];\n if (pressedKeys.length != currentHotKey.length) continue;\n\n if (currentHotKey.every(function(key, i) { return key == pressedKeys[i]; })) {\n _this._trigger('hotKey', hotKey);\n found = true;\n }\n }\n\n return found;\n },\n\n _trigger: function(event, args) {\n this.$el.trigger(event, args);\n },\n\n _focusNextCell: function(keyCode, type) {\n type = type || this.cellType;\n\n var date = datepicker.getParsedDate(this._getFocusedDate());\n var y = date.year;\n var m = date.month;\n var d = date.date;\n\n if (this._isHotKeyPressed()) {\n return;\n }\n\n switch (keyCode) {\n case 37:\n // left\n type == 'day' ? (d -= 1) : '';\n type == 'month' ? (m -= 1) : '';\n type == 'year' ? (y -= 1) : '';\n break;\n case 38:\n // up\n type == 'day' ? (d -= 7) : '';\n type == 'month' ? (m -= 3) : '';\n type == 'year' ? (y -= 4) : '';\n break;\n case 39:\n // right\n type == 'day' ? (d += 1) : '';\n type == 'month' ? (m += 1) : '';\n type == 'year' ? (y += 1) : '';\n break;\n case 40:\n // down\n type == 'day' ? (d += 7) : '';\n type == 'month' ? (m += 3) : '';\n type == 'year' ? (y += 4) : '';\n break;\n }\n\n var nd = new Date(y, m, d);\n\n if (nd.getTime() < this.minTime) {\n nd = this.minDate;\n } else if (nd.getTime() > this.maxTime) {\n nd = this.maxDate;\n }\n\n this.focused = nd;\n },\n\n _getFocusedDate: function() {\n var focused = this.focused || this.selectedDates[this.selectedDates.length - 1];\n var d = this.parsedDate;\n\n if (!focused) {\n switch (this.view) {\n case 'days':\n focused = new Date(d.year, d.month, new Date().getDate());\n break;\n case 'months':\n focused = new Date(d.year, d.month, 1);\n break;\n case 'years':\n focused = new Date(d.year, 0, 1);\n break;\n }\n }\n\n return focused;\n },\n\n _getCell: function(date, type) {\n type = type || this.cellType;\n\n var d = datepicker.getParsedDate(date);\n var selector = '.datepicker--cell[data-year=\"' + d.year + '\"]';\n var $cell;\n\n switch (type) {\n case 'month':\n selector = '[data-month=\"' + d.month + '\"]';\n break;\n case 'day':\n selector += '[data-month=\"' + d.month + '\"][data-date=\"' + d.date + '\"]';\n break;\n }\n $cell = this.views[this.currentView].$el.find(selector);\n\n return $cell.length ? $cell : '';\n },\n\n _onShowEvent: function() {\n if (!this.visible) {\n this.show();\n }\n },\n\n _onBlur: function() {\n if (!this.inFocus && this.visible) {\n this.hide();\n }\n },\n\n _onMouseDownDatepicker: function() {\n this.inFocus = true;\n },\n\n _onMouseUpDatepicker: function() {\n this.inFocus = false;\n this.$el.focus();\n },\n\n _onInput: function() {\n var val = this.$el.val();\n\n if (!val) {\n this.clear();\n }\n },\n\n _onResize: function() {\n if (this.visible) {\n this.setPosition();\n }\n },\n\n _onKeyDown: function(e) {\n var code = e.which;\n\n this._registerKey(code);\n\n // Arrows\n if (code >= 37 && code <= 40) {\n e.preventDefault();\n this._focusNextCell(code);\n }\n\n // Enter\n if (code == 13) {\n if (this.focused) {\n if (this._getCell(this.focused).hasClass('-disabled-')) return;\n if (this.view != this.opts.minView) {\n this.down();\n } else {\n var alreadySelected = this._isSelected(this.focused, this.cellType);\n\n if (!alreadySelected) {\n this.selectDate(this.focused);\n } else if (alreadySelected && this.opts.toggleSelected) {\n this.removeDate(this.focused);\n }\n }\n }\n }\n\n // Esc\n if (code == 27) {\n this.hide();\n }\n },\n\n _onKeyUp: function(e) {\n var code = e.which;\n\n this._unRegisterKey(code);\n },\n\n _onHotKey: function(e, hotKey) {\n this._handleHotKey(hotKey);\n },\n\n _onMouseEnterCell: function(e) {\n var $cell = $(e.target).closest('.datepicker--cell');\n var date = this._getDateFromCell($cell);\n\n // Prevent from unnecessary rendering and setting new currentDate\n this.silent = true;\n\n if (this.focused) {\n this.focused = '';\n }\n\n $cell.addClass('-focus-');\n\n this.focused = date;\n this.silent = false;\n\n if (this.opts.range && this.selectedDates.length == 1) {\n this.minRange = this.selectedDates[0];\n this.maxRange = '';\n if (datepicker.less(this.minRange, this.focused)) {\n this.maxRange = this.minRange;\n this.minRange = '';\n }\n this.views[this.currentView]._update();\n }\n },\n\n _onMouseLeaveCell: function(e) {\n var $cell = $(e.target).closest('.datepicker--cell');\n\n $cell.removeClass('-focus-');\n\n this.silent = true;\n this.focused = '';\n this.silent = false;\n },\n\n set focused(val) {\n if (!val && this.focused) {\n var $cell = this._getCell(this.focused);\n\n if ($cell.length) {\n $cell.removeClass('-focus-');\n }\n }\n this._focused = val;\n if (this.opts.range && this.selectedDates.length == 1) {\n this.minRange = this.selectedDates[0];\n this.maxRange = '';\n if (datepicker.less(this.minRange, this._focused)) {\n this.maxRange = this.minRange;\n this.minRange = '';\n }\n }\n if (this.silent) return;\n this.date = val;\n },\n\n get focused() {\n return this._focused;\n },\n\n get parsedDate() {\n return datepicker.getParsedDate(this.date);\n },\n\n set date(val) {\n if (!(val instanceof Date)) return;\n\n this.currentDate = val;\n\n if (this.inited && !this.silent) {\n this.views[this.view]._render();\n this.nav._render();\n if (this.visible && this.elIsInput) {\n this.setPosition();\n }\n }\n\n return val;\n },\n\n get date() {\n return this.currentDate;\n },\n\n set view(val) {\n this.viewIndex = this.viewIndexes.indexOf(val);\n\n if (this.viewIndex < 0) {\n return;\n }\n\n this.prevView = this.currentView;\n this.currentView = val;\n\n if (this.inited) {\n if (!this.views[val]) {\n this.views[val] = new Datepicker.Body(this, val, this.opts);\n } else {\n this.views[val]._render();\n }\n\n this.views[this.prevView].hide();\n this.views[val].show();\n this.nav._render();\n\n if (this.opts.onChangeView) {\n this.opts.onChangeView(val);\n }\n if (this.elIsInput && this.visible) this.setPosition();\n }\n\n return val;\n },\n\n get view() {\n return this.currentView;\n },\n\n get cellType() {\n return this.view.substring(0, this.view.length - 1);\n },\n\n get minTime() {\n var min = datepicker.getParsedDate(this.minDate);\n\n return new Date(min.year, min.month, min.date).getTime();\n },\n\n get maxTime() {\n var max = datepicker.getParsedDate(this.maxDate);\n\n return new Date(max.year, max.month, max.date).getTime();\n },\n\n get curDecade() {\n return datepicker.getDecade(this.date);\n }\n };\n\n // Utils\n // -------------------------------------------------\n\n datepicker.getDaysCount = function(date) {\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\n };\n\n datepicker.getParsedDate = function(date) {\n return {\n year: date.getFullYear(),\n month: date.getMonth(),\n // One based\n fullMonth: (date.getMonth() + 1) < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1,\n date: date.getDate(),\n fullDate: date.getDate() < 10 ? '0' + date.getDate() : date.getDate(),\n day: date.getDay()\n };\n };\n\n datepicker.getDecade = function(date) {\n var firstYear = Math.floor(date.getFullYear() / 10) * 10;\n\n return [firstYear, firstYear + 9];\n };\n\n datepicker.template = function(str, data) {\n return str.replace(/#\\{([\\w]+)\\}/g, function(source, match) {\n if (data[match] || data[match] === 0) {\n return data[match];\n }\n });\n };\n\n datepicker.isSame = function(date1, date2, type) {\n if (!date1 || !date2) return false;\n var d1 = datepicker.getParsedDate(date1);\n var d2 = datepicker.getParsedDate(date2);\n var _type = type ? type : 'day';\n var conditions = {\n day: d1.date == d2.date && d1.month == d2.month && d1.year == d2.year,\n month: d1.month == d2.month && d1.year == d2.year,\n year: d1.year == d2.year\n };\n\n return conditions[_type];\n };\n\n datepicker.less = function(dateCompareTo, date) {\n if (!dateCompareTo || !date) return false;\n\n return date.getTime() < dateCompareTo.getTime();\n };\n\n datepicker.bigger = function(dateCompareTo, date) {\n if (!dateCompareTo || !date) return false;\n\n return date.getTime() > dateCompareTo.getTime();\n };\n\n Datepicker.language = {\n et: {\n days: ['Pühapäev', 'Esmaspäev', 'Teisipäev', 'Kolmapäev', 'Neljapäev', 'Reede', 'Laupäev'],\n daysShort: ['P', 'E', 'T', 'K', 'N', 'R', 'L'],\n daysMin: ['P', 'E', 'T', 'K', 'N', 'R', 'L'],\n months: ['Jaanuar', 'Veebruar', 'Märts', 'Aprill', 'Mai', 'Juuni', 'Juuli', 'August', 'September', 'Oktoober', 'November', 'Detsember'],\n monthsShort: ['Jaan', 'Veebr', 'Märts', 'Apr', 'Mai', 'Juuni', 'Juuli', 'Aug', 'Sept', 'Okt', 'Nov', 'Dets'],\n today: 'Täna',\n clear: 'Tühjenda',\n dateFormat: 'dd.mm.yyyy',\n firstDay: 1\n }\n };\n\n $.fn[pluginName] = function(options) {\n return this.each(function() {\n if (!$.data(this, pluginName)) {\n $.data(this, pluginName,\n new Datepicker(this, options));\n } else {\n var _this = $.data(this, pluginName);\n\n _this.opts = $.extend(true, _this.opts, options);\n _this.update();\n }\n });\n };\n\n $(function() {\n $(autoInitSelector).datepicker();\n });\n})(window, jQuery);\n;(function() {\n var templates = {\n days: '' +\n '
' +\n '' +\n '' +\n '
',\n months: '' +\n '
' +\n '' +\n '
',\n years: '' +\n '
' +\n '' +\n '
'\n };\n var D = Datepicker;\n\n D.Body = function(d, type, opts) {\n this.d = d;\n this.type = type;\n this.opts = opts;\n\n this.init();\n };\n\n D.Body.prototype = {\n init: function() {\n this._buildBaseHtml();\n this._render();\n\n this._bindEvents();\n },\n\n _bindEvents: function() {\n this.$el.on('click', '.datepicker--cell', $.proxy(this._onClickCell, this));\n },\n\n _buildBaseHtml: function() {\n this.$el = $(templates[this.type]).appendTo(this.d.$content);\n this.$names = $('.datepicker--days-names', this.$el);\n this.$cells = $('.datepicker--cells', this.$el);\n },\n\n _getDayNamesHtml: function(firstDay, curDay, html, i) {\n curDay = curDay != undefined ? curDay : firstDay;\n html = html ? html : '';\n i = i != undefined ? i : 0;\n\n if (i > 7) return html;\n if (curDay == 7) return this._getDayNamesHtml(firstDay, 0, html, ++i);\n\n html += '
' + this.d.loc.daysMin[curDay] + '
';\n\n return this._getDayNamesHtml(firstDay, ++curDay, html, ++i);\n },\n\n _getCellContents: function(date, type) {\n var classes = 'datepicker--cell datepicker--cell-' + type;\n var currentDate = new Date();\n var parent = this.d;\n var opts = parent.opts;\n var d = D.getParsedDate(date);\n var render = {};\n var html = d.date;\n\n if (opts.onRenderCell) {\n render = opts.onRenderCell(date, type) || {};\n html = render.html ? render.html : html;\n classes += render.classes ? ' ' + render.classes : '';\n }\n\n switch (type) {\n case 'day':\n if (parent.isWeekend(d.day)) classes += ' -weekend-';\n if (d.month != this.d.parsedDate.month) {\n classes += ' -other-month-';\n if (!opts.selectOtherMonths) {\n classes += ' -disabled-';\n }\n if (!opts.showOtherMonths) html = '';\n }\n break;\n case 'month':\n html = parent.loc[parent.opts.monthsFiled][d.month];\n break;\n case 'year':\n var decade = parent.curDecade;\n\n if (d.year < decade[0] || d.year > decade[1]) {\n classes += ' -other-decade-';\n if (!opts.selectOtherYears) {\n classes += ' -disabled-';\n }\n if (!opts.showOtherYears) html = '';\n }\n html = d.year;\n break;\n }\n\n if (opts.onRenderCell) {\n render = opts.onRenderCell(date, type) || {};\n html = render.html ? render.html : html;\n classes += render.classes ? ' ' + render.classes : '';\n }\n\n if (opts.range) {\n if (D.isSame(parent.minRange, date, type)) classes += ' -range-from-';\n if (D.isSame(parent.maxRange, date, type)) classes += ' -range-to-';\n\n if (parent.selectedDates.length == 1 && parent.focused) {\n if (\n (D.bigger(parent.minRange, date) && D.less(parent.focused, date)) ||\n (D.less(parent.maxRange, date) && D.bigger(parent.focused, date))) {\n classes += ' -in-range-';\n }\n\n if (D.less(parent.maxRange, date) && D.isSame(parent.focused, date)) {\n classes += ' -range-from-';\n }\n if (D.bigger(parent.minRange, date) && D.isSame(parent.focused, date)) {\n classes += ' -range-to-';\n }\n } else if (parent.selectedDates.length == 2) {\n if (D.bigger(parent.minRange, date) && D.less(parent.maxRange, date)) {\n classes += ' -in-range-';\n }\n }\n }\n\n if (D.isSame(currentDate, date, type)) classes += ' -current-';\n if (parent.focused && D.isSame(date, parent.focused, type)) classes += ' -focus-';\n if (parent._isSelected(date, type)) classes += ' -selected-';\n if (!parent._isInRange(date, type) || render.disabled) classes += ' -disabled-';\n\n return {\n html: html,\n classes: classes\n };\n },\n\n /**\n * Calculates days number to render. Generates days html and returns it.\n * @param {object} date - Date object\n * @returns {string}\n * @private\n */\n _getDaysHtml: function(date) {\n var totalMonthDays = D.getDaysCount(date);\n var firstMonthDay = new Date(date.getFullYear(), date.getMonth(), 1).getDay();\n var lastMonthDay = new Date(date.getFullYear(), date.getMonth(), totalMonthDays).getDay();\n var daysFromPevMonth = firstMonthDay - this.d.loc.firstDay;\n var daysFromNextMonth = 6 - lastMonthDay + this.d.loc.firstDay;\n\n daysFromPevMonth = daysFromPevMonth < 0 ? daysFromPevMonth + 7 : daysFromPevMonth;\n daysFromNextMonth = daysFromNextMonth > 6 ? daysFromNextMonth - 7 : daysFromNextMonth;\n\n var startDayIndex = -daysFromPevMonth + 1;\n var m;\n var y;\n var html = '';\n\n for (var i = startDayIndex, max = totalMonthDays + daysFromNextMonth; i <= max; i++) {\n y = date.getFullYear();\n m = date.getMonth();\n\n html += this._getDayHtml(new Date(y, m, i));\n }\n\n return html;\n },\n\n _getDayHtml: function(date) {\n var content = this._getCellContents(date, 'day');\n\n return '
' + content.html + '
';\n },\n\n /**\n * Generates months html\n * @param {object} date - date instance\n * @returns {string}\n * @private\n */\n _getMonthsHtml: function(date) {\n var html = '';\n var d = D.getParsedDate(date);\n var i = 0;\n\n while (i < 12) {\n html += this._getMonthHtml(new Date(d.year, i));\n i++;\n }\n\n return html;\n },\n\n _getMonthHtml: function(date) {\n var content = this._getCellContents(date, 'month');\n\n return '
' + content.html + '
';\n },\n\n _getYearsHtml: function(date) {\n var decade = D.getDecade(date);\n var firstYear = decade[0] - 1;\n var html = '';\n var i = firstYear;\n\n for (i; i <= decade[1] + 1; i++) {\n html += this._getYearHtml(new Date(i, 0));\n }\n\n return html;\n },\n\n _getYearHtml: function(date) {\n var content = this._getCellContents(date, 'year');\n\n return '
' + content.html + '
';\n },\n\n _renderTypes: {\n days: function() {\n var dayNames = this._getDayNamesHtml(this.d.loc.firstDay);\n var days = this._getDaysHtml(this.d.currentDate);\n\n this.$cells.html(days);\n this.$names.html(dayNames);\n },\n months: function() {\n var html = this._getMonthsHtml(this.d.currentDate);\n\n this.$cells.html(html);\n },\n years: function() {\n var html = this._getYearsHtml(this.d.currentDate);\n\n this.$cells.html(html);\n }\n },\n\n _render: function() {\n this._renderTypes[this.type].bind(this)();\n },\n\n _update: function() {\n var $cells = $('.datepicker--cell', this.$cells);\n var _this = this;\n var classes;\n var $cell;\n var date;\n\n $cells.each(function() {\n $cell = $(this);\n date = _this.d._getDateFromCell($(this));\n classes = _this._getCellContents(date, _this.d.cellType);\n $cell.attr('class', classes.classes);\n });\n },\n\n show: function() {\n this.$el.addClass('active');\n this.acitve = true;\n },\n\n hide: function() {\n this.$el.removeClass('active');\n this.active = false;\n },\n\n // Events\n // -------------------------------------------------\n\n _handleClick: function(el) {\n var date = el.data('date') || 1;\n var month = el.data('month') || 0;\n var year = el.data('year') || this.d.parsedDate.year;\n // Change view if min view does not reach yet\n\n if (this.d.view != this.opts.minView) {\n this.d.down(new Date(year, month, date));\n\n return;\n }\n // Select date if min view is reached\n var selectedDate = new Date(year, month, date);\n var alreadySelected = this.d._isSelected(selectedDate, this.d.cellType);\n\n if (!alreadySelected) {\n this.d.selectDate(selectedDate);\n } else if (alreadySelected && this.opts.toggleSelected) {\n this.d.removeDate(selectedDate);\n }\n },\n\n _onClickCell: function(e) {\n var $el = $(e.target).closest('.datepicker--cell');\n\n if ($el.hasClass('-disabled-')) return;\n\n this._handleClick.bind(this)($el);\n }\n };\n})();\n\n;(function() {\n var template = '' +\n '
#{prevHtml}
' +\n '
#{title}
' +\n '
#{nextHtml}
';\n var buttonsContainerTemplate = '';\n var button = '#{label}';\n\n Datepicker.Navigation = function(d, opts) {\n this.d = d;\n this.opts = opts;\n\n this.$buttonsContainer = '';\n\n this.init();\n };\n\n Datepicker.Navigation.prototype = {\n init: function() {\n this._buildBaseHtml();\n this._bindEvents();\n },\n\n _bindEvents: function() {\n this.d.$nav.on('click', '.datepicker--nav-action', $.proxy(this._onClickNavButton, this));\n this.d.$nav.on('click', '.datepicker--nav-title', $.proxy(this._onClickNavTitle, this));\n this.d.$datepicker.on('click', '.datepicker--button', $.proxy(this._onClickNavButton, this));\n },\n\n _buildBaseHtml: function() {\n this._render();\n this._addButtonsIfNeed();\n },\n\n _addButtonsIfNeed: function() {\n if (this.opts.todayButton) {\n this._addButton('today');\n }\n if (this.opts.clearButton) {\n this._addButton('clear');\n }\n },\n\n _render: function() {\n var title = this._getTitle(this.d.currentDate);\n var html = Datepicker.template(template, $.extend({\n title: title\n }, this.opts));\n\n this.d.$nav.html(html);\n if (this.d.view == 'years') {\n $('.datepicker--nav-title', this.d.$nav).addClass('-disabled-');\n }\n this.setNavStatus();\n },\n\n _getTitle: function(date) {\n return this.d.formatDate(this.opts.navTitles[this.d.view], date);\n },\n\n _addButton: function(type) {\n if (!this.$buttonsContainer.length) {\n this._addButtonsContainer();\n }\n\n var data = {\n action: type,\n label: this.d.loc[type]\n };\n var html = Datepicker.template(button, data);\n\n if ($('[data-action=' + type + ']', this.$buttonsContainer).length) return;\n this.$buttonsContainer.append(html);\n },\n\n _addButtonsContainer: function() {\n this.d.$datepicker.append(buttonsContainerTemplate);\n this.$buttonsContainer = $('.datepicker--buttons', this.d.$datepicker);\n },\n\n setNavStatus: function() {\n if (!(this.opts.minDate || this.opts.maxDate) || !this.opts.disableNavWhenOutOfRange) return;\n\n var date = this.d.parsedDate;\n var m = date.month;\n var y = date.year;\n var d = date.date;\n\n switch (this.d.view) {\n case 'days':\n if (!this.d._isInRange(new Date(y, m - 1, d), 'month')) {\n this._disableNav('prev');\n }\n if (!this.d._isInRange(new Date(y, m + 1, d), 'month')) {\n this._disableNav('next');\n }\n break;\n case 'months':\n if (!this.d._isInRange(new Date(y - 1, m, d), 'year')) {\n this._disableNav('prev');\n }\n if (!this.d._isInRange(new Date(y + 1, m, d), 'year')) {\n this._disableNav('next');\n }\n break;\n case 'years':\n if (!this.d._isInRange(new Date(y - 10, m, d), 'year')) {\n this._disableNav('prev');\n }\n if (!this.d._isInRange(new Date(y + 10, m, d), 'year')) {\n this._disableNav('next');\n }\n break;\n }\n },\n\n _disableNav: function(nav) {\n $('[data-action=\"' + nav + '\"]', this.d.$nav).addClass('-disabled-');\n },\n\n _activateNav: function(nav) {\n $('[data-action=\"' + nav + '\"]', this.d.$nav).removeClass('-disabled-');\n },\n\n _onClickNavButton: function(e) {\n var $el = $(e.target).closest('[data-action]');\n var action = $el.data('action');\n\n this.d[action]();\n },\n\n _onClickNavTitle: function(e) {\n if ($(e.target).hasClass('-disabled-')) return;\n\n if (this.d.view == 'days') {\n return this.d.view = 'months';\n }\n\n this.d.view = 'years';\n }\n };\n})();\n\n//@import('i18n/datepicker.en.js');\n//@import('i18n/datepicker.ru.js');\n//@import('i18n/datepicker.fi.js');\n//@import('i18n/datepicker.da.js');\n","/* ========================================================================\n* Bootstrap: dropdown.js v3.3.6\n* http://getbootstrap.com/javascript/#dropdowns\n* ========================================================================\n* Copyright 2011-2015 Twitter, Inc.\n* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n* ======================================================================== */\n\n+function($) {\n 'use strict';\n\n // DROPDOWN CLASS DEFINITION\n // =========================\n\n var backdrop = '.dropdown__backdrop';\n var toggle = '[data-toggle=\"dropdown\"]';\n\n function Dropdown(element) {\n $(element).on('click.bs.dropdown', this.toggle);\n };\n\n Dropdown.VERSION = '3.3.6';\n\n function getParent($this) {\n var selector = $this.attr('data-target');\n\n if (!selector) {\n selector = $this.attr('href');\n // strip for ie7\n selector = selector && (/#[A-Za-z]/).test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '');\n }\n\n var $parent = selector && $(selector);\n\n return $parent && $parent.length ? $parent : $this.parent();\n }\n\n function clearMenus(e) {\n if (e && e.which === 3) return;\n $(backdrop).remove();\n $(toggle).each(function() {\n var $this = $(this);\n var $parent = getParent($this);\n var relatedTarget = {\n relatedTarget: this\n };\n\n if (!$parent.hasClass('open')) return;\n\n if (e && e.type == 'click' && (/input|textarea/i).test(e.target.tagName) && $.contains($parent[0], e.target)) return;\n\n $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget));\n\n if (e.isDefaultPrevented()) return;\n\n $this.attr('aria-expanded', 'false');\n $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget));\n });\n }\n\n Dropdown.prototype.toggle = function(e) {\n var $this = $(this);\n\n if ($this.is('.disabled, :disabled')) return;\n\n var $parent = getParent($this);\n var isActive = $parent.hasClass('open');\n\n clearMenus();\n\n if (!isActive) {\n if ('ontouchstart' in document.documentElement) {\n // if mobile we use a backdrop because click events don't delegate\n $(document.createElement('div'))\n .addClass('dropdown__backdrop')\n .insertAfter($(this))\n .on('click', clearMenus);\n }\n\n var relatedTarget = {\n relatedTarget: this\n };\n\n $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget));\n\n if (e.isDefaultPrevented()) return;\n\n $this\n .trigger('focus')\n .attr('aria-expanded', 'true');\n\n $parent\n .toggleClass('open')\n .trigger($.Event('shown.bs.dropdown', relatedTarget));\n }\n\n return false;\n };\n\n Dropdown.prototype.keydown = function(e) {\n if (!(/(38|40|27|32)/).test(e.which) || (/input|textarea/i).test(e.target.tagName)) return;\n\n var $this = $(this);\n\n e.preventDefault();\n e.stopPropagation();\n\n if ($this.is('.disabled, :disabled')) return;\n\n var $parent = getParent($this);\n var isActive = $parent.hasClass('open');\n\n if (!isActive && e.which != 27 || isActive && e.which == 27) {\n if (e.which == 27) $parent.find(toggle).trigger('focus');\n\n return $this.trigger('click');\n }\n\n var desc = ' li:not(.disabled):visible a';\n var $items = $parent.find('.dropdown__menu' + desc);\n\n if (!$items.length) return;\n\n var index = $items.index(e.target);\n\n // up\n if (e.which == 38 && index > 0) index--;\n // down\n if (e.which == 40 && index < $items.length - 1) index++;\n if (!~index) index = 0;\n\n $items.eq(index).trigger('focus');\n };\n\n // DROPDOWN PLUGIN DEFINITION\n // ==========================\n\n function Plugin(option) {\n return this.each(function() {\n var $this = $(this);\n var data = $this.data('bs.dropdown');\n\n if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)));\n if (typeof option == 'string') data[option].call($this);\n });\n }\n\n var old = $.fn.dropdown;\n\n $.fn.dropdown = Plugin;\n $.fn.dropdown.Constructor = Dropdown;\n\n // DROPDOWN NO CONFLICT\n // ====================\n\n $.fn.dropdown.noConflict = function() {\n $.fn.dropdown = old;\n\n return this;\n };\n\n // APPLY TO STANDARD DROPDOWN ELEMENTS\n // ===================================\n\n $(document)\n .on('click.bs.dropdown.data-api', clearMenus)\n .on('click.bs.dropdown.data-api', '.dropdown form', function(e) { e.stopPropagation(); })\n .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n .on('keydown.bs.dropdown.data-api', '.dropdown__menu', Dropdown.prototype.keydown);\n}(jQuery);\n","/* !\n * Bootstrap-select v1.10.0 (http://silviomoreto.github.io/bootstrap-select)\n *\n * Copyright 2013-2016 bootstrap-select\n * Licensed under MIT (https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE)\n */\n\n(function(factory) {\n factory(jQuery);\n}(function(jQuery) {\n (function($) {\n 'use strict';\n\n // \n if (!String.prototype.includes) {\n (function() {\n // needed to support `apply`/`call` with `undefined`/`null`\n 'use strict';\n\n var toString = {}.toString;\n var defineProperty = (function() {\n // IE 8 only supports `Object.defineProperty` on DOM elements\n try {\n var object = {};\n var $defineProperty = Object.defineProperty;\n var result = $defineProperty(object, object, object) && $defineProperty;\n } catch (error) {\n // continue regardless of error\n }\n\n return result;\n }());\n var indexOf = ''.indexOf;\n\n function includes(search) {\n if (this == null) {\n throw new TypeError();\n }\n var string = String(this);\n\n if (search && toString.call(search) == '[object RegExp]') {\n throw new TypeError();\n }\n var stringLength = string.length;\n var searchString = String(search);\n var searchLength = searchString.length;\n var position = arguments.length > 1 ? arguments[1] : undefined;\n // `ToInteger`\n var pos = position ? Number(position) : 0;\n // better `isNaN`\n\n if (pos != pos) {\n pos = 0;\n }\n var start = Math.min(Math.max(pos, 0), stringLength);\n // Avoid the `indexOf` call if no match is possible\n\n if (searchLength + start > stringLength) {\n return false;\n }\n\n return indexOf.call(string, searchString, pos) != -1;\n };\n if (defineProperty) {\n defineProperty(String.prototype, 'includes', {\n value: includes,\n configurable: true,\n writable: true\n });\n } else {\n String.prototype.includes = includes;\n }\n }());\n }\n\n if (!String.prototype.startsWith) {\n (function() {\n // needed to support `apply`/`call` with `undefined`/`null`\n 'use strict';\n\n var defineProperty = (function() {\n // IE 8 only supports `Object.defineProperty` on DOM elements\n try {\n var object = {};\n var $defineProperty = Object.defineProperty;\n var result = $defineProperty(object, object, object) && $defineProperty;\n } catch (error) {\n // continue regardless of error\n }\n\n return result;\n }());\n var toString = {}.toString;\n\n function startsWith(search) {\n if (this == null) {\n throw new TypeError();\n }\n var string = String(this);\n\n if (search && toString.call(search) == '[object RegExp]') {\n throw new TypeError();\n }\n var stringLength = string.length;\n var searchString = String(search);\n var searchLength = searchString.length;\n var position = arguments.length > 1 ? arguments[1] : undefined;\n // `ToInteger`\n var pos = position ? Number(position) : 0;\n // better `isNaN`\n\n if (pos != pos) {\n pos = 0;\n }\n var start = Math.min(Math.max(pos, 0), stringLength);\n // Avoid the `indexOf` call if no match is possible\n\n if (searchLength + start > stringLength) {\n return false;\n }\n var index = -1;\n\n while (++index < searchLength) {\n if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) {\n return false;\n }\n }\n\n return true;\n };\n if (defineProperty) {\n defineProperty(String.prototype, 'startsWith', {\n value: startsWith,\n configurable: true,\n writable: true\n });\n } else {\n String.prototype.startsWith = startsWith;\n }\n }());\n }\n\n if (!Object.keys) {\n // object, key, result\n Object.keys = function(o, k, r) {\n // initialize object and result\n r = [];\n // iterate over object keys\n for (k in o) {\n // fill result array with non-prototypical keys\n r.hasOwnProperty.call(o, k) && r.push(k);\n }\n\n // return result\n return r;\n };\n }\n\n $.fn.triggerNative = function(eventName) {\n var el = this[0];\n var event;\n\n if (el.dispatchEvent) {\n if (typeof Event === 'function') {\n // For modern browsers\n event = new Event(eventName, {\n bubbles: true\n });\n } else {\n // For IE since it doesn't support Event constructor\n event = document.createEvent('Event');\n event.initEvent(eventName, true, false);\n }\n\n el.dispatchEvent(event);\n } else {\n if (el.fireEvent) {\n event = document.createEventObject();\n event.eventType = eventName;\n el.fireEvent('on' + eventName, event);\n }\n\n this.trigger(eventName);\n }\n };\n // \n\n // Case insensitive contains search\n $.expr[':'].icontains = function(obj, index, meta) {\n var $obj = $(obj);\n var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();\n\n return haystack.includes(meta[3].toUpperCase());\n };\n\n // Case insensitive begins search\n $.expr[':'].ibegins = function(obj, index, meta) {\n var $obj = $(obj);\n var haystack = ($obj.data('tokens') || $obj.text()).toUpperCase();\n\n return haystack.startsWith(meta[3].toUpperCase());\n };\n\n // Case and accent insensitive contains search\n $.expr[':'].aicontains = function(obj, index, meta) {\n var $obj = $(obj);\n var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();\n\n return haystack.includes(meta[3].toUpperCase());\n };\n\n // Case and accent insensitive begins search\n $.expr[':'].aibegins = function(obj, index, meta) {\n var $obj = $(obj);\n var haystack = ($obj.data('tokens') || $obj.data('normalizedText') || $obj.text()).toUpperCase();\n\n return haystack.startsWith(meta[3].toUpperCase());\n };\n\n /**\n * Remove all diatrics from the given text.\n * @access private\n * @param {String} text\n * @returns {String}\n */\n function normalizeToBase(text) {\n var rExps = [\n {\n re: /[\\xC0-\\xC6]/g,\n ch: 'A'\n },\n {\n re: /[\\xE0-\\xE6]/g,\n ch: 'a'\n },\n {\n re: /[\\xC8-\\xCB]/g,\n ch: 'E'\n },\n {\n re: /[\\xE8-\\xEB]/g,\n ch: 'e'\n },\n {\n re: /[\\xCC-\\xCF]/g,\n ch: 'I'\n },\n {\n re: /[\\xEC-\\xEF]/g,\n ch: 'i'\n },\n {\n re: /[\\xD2-\\xD6]/g,\n ch: 'O'\n },\n {\n re: /[\\xF2-\\xF6]/g,\n ch: 'o'\n },\n {\n re: /[\\xD9-\\xDC]/g,\n ch: 'U'\n },\n {\n re: /[\\xF9-\\xFC]/g,\n ch: 'u'\n },\n {\n re: /[\\xC7-\\xE7]/g,\n ch: 'c'\n },\n {\n re: /[\\xD1]/g,\n ch: 'N'\n },\n {\n re: /[\\xF1]/g,\n ch: 'n'\n }\n ];\n\n $.each(rExps, function() {\n text = text.replace(this.re, this.ch);\n });\n\n return text;\n }\n\n function htmlEscape(html) {\n var escapeMap = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n '\\'': ''',\n '`': '`'\n };\n var source = '(?:' + Object.keys(escapeMap).join('|') + ')';\n var testRegexp = new RegExp(source);\n var replaceRegexp = new RegExp(source, 'g');\n var string = html == null ? '' : '' + html;\n\n return testRegexp.test(string) ? string.replace(replaceRegexp, function(match) {\n return escapeMap[match];\n }) : string;\n }\n\n function Selectpicker(element, options, e) {\n if (e) {\n e.stopPropagation();\n e.preventDefault();\n }\n\n this.element = element;\n this.$element = $(element);\n this.$newElement = null;\n this.$button = null;\n this.$menu = null;\n this.$lis = null;\n this.options = options;\n\n // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a\n // data-attribute)\n if (this.options.title === null) {\n this.options.title = this.$element.attr('title');\n }\n\n // Expose public methods\n this.val = Selectpicker.prototype.val;\n this.render = Selectpicker.prototype.render;\n this.refresh = Selectpicker.prototype.refresh;\n this.setStyle = Selectpicker.prototype.setStyle;\n this.selectAll = Selectpicker.prototype.selectAll;\n this.deselectAll = Selectpicker.prototype.deselectAll;\n this.destroy = Selectpicker.prototype.destroy;\n this.remove = Selectpicker.prototype.remove;\n this.show = Selectpicker.prototype.show;\n this.hide = Selectpicker.prototype.hide;\n\n this.init();\n };\n\n Selectpicker.VERSION = '1.10.0';\n\n // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both.\n Selectpicker.DEFAULTS = {\n noneSelectedText: 'Nothing selected',\n noneResultsText: 'No results matched {0}',\n countSelectedText: function(numSelected) {\n return (numSelected == 1) ? '{0} item selected' : '{0} items selected';\n },\n maxOptionsText: function(numAll, numGroup) {\n return [\n (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)',\n (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)'\n ];\n },\n selectAllText: 'Select All',\n deselectAllText: 'Deselect All',\n doneButton: false,\n doneButtonText: 'Close',\n multipleSeparator: ', ',\n styleBase: 'bootstrap-select__trigger',\n style: '',\n size: 10,\n title: null,\n selectedTextFormat: 'values',\n width: false,\n container: 'body',\n hideDisabled: false,\n showSubtext: false,\n showIcon: true,\n showContent: true,\n dropupAuto: false,\n header: false,\n liveSearch: false,\n liveSearchPlaceholder: null,\n liveSearchNormalize: false,\n liveSearchStyle: 'contains',\n actionsBox: false,\n iconBase: 'glyphicon',\n tickIcon: 'glyphicon-ok',\n showTick: false,\n template: {\n caret: ''\n },\n maxOptions: false,\n mobile: false,\n selectOnTab: false,\n dropdownAlignRight: false\n };\n\n Selectpicker.prototype = {\n\n constructor: Selectpicker,\n\n init: function() {\n var that = this;\n var id = this.$element.attr('id');\n\n this.$element.addClass('bs-select-hidden');\n\n // store originalIndex (key) and newIndex (value) in this.liObj for fast accessibility\n // allows us to do this.$lis.eq(that.liObj[index]) instead of this.$lis.filter('[data-original-index=\"' + index + '\"]')\n this.liObj = {};\n this.multiple = this.$element.prop('multiple');\n this.autofocus = this.$element.prop('autofocus');\n this.$newElement = this.createView();\n this.$element\n .after(this.$newElement)\n .appendTo(this.$newElement);\n this.$button = this.$newElement.children('button');\n this.$menu = this.$newElement.children('.dropdown__menu');\n this.$menuInner = this.$menu.children('.dropdown__inner');\n this.$searchbox = this.$menu.find('input');\n\n this.$element.removeClass('bs-select-hidden');\n\n if (this.options.dropdownAlignRight) this.$menu.addClass('dropdown-menu-right');\n\n if (typeof id !== 'undefined') {\n this.$button.attr('data-id', id);\n $('label[for=\"' + id + '\"]').click(function(e) {\n e.preventDefault();\n that.$button.focus();\n });\n }\n\n this.checkDisabled();\n this.clickListener();\n if (this.options.liveSearch) this.liveSearchListener();\n this.render();\n this.setStyle();\n this.setWidth();\n if (this.options.container) this.selectPosition();\n this.$menu.data('this', this);\n this.$newElement.data('this', this);\n if (this.options.mobile) this.mobile();\n\n this.$newElement.on({\n 'hide.bs.dropdown': function(e) {\n that.$element.trigger('hide.bs.select', e);\n },\n 'hidden.bs.dropdown': function(e) {\n that.$element.trigger('hidden.bs.select', e);\n },\n 'show.bs.dropdown': function(e) {\n that.$element.trigger('show.bs.select', e);\n },\n 'shown.bs.dropdown': function(e) {\n that.$element.trigger('shown.bs.select', e);\n }\n });\n\n if (that.$element[0].hasAttribute('required')) {\n this.$element.on('invalid', function() {\n that.$button\n .addClass('bs-invalid')\n .focus();\n\n that.$element.on({\n 'focus.bs.select': function() {\n that.$button.focus();\n that.$element.off('focus.bs.select');\n },\n 'shown.bs.select': function() {\n that.$element\n // set the value to hide the validation message in Chrome when menu is opened\n .val(that.$element.val())\n .off('shown.bs.select');\n },\n 'rendered.bs.select': function() {\n // if select is no longer invalid, remove the bs-invalid class\n if (this.validity.valid) that.$button.removeClass('bs-invalid');\n that.$element.off('rendered.bs.select');\n }\n });\n });\n }\n\n setTimeout(function() {\n that.$element.trigger('loaded.bs.select');\n });\n\n this.observer = this.createMutationObserver();\n },\n\n createMutationObserver: function() {\n var that = this;\n var watch = this.element;\n\n if (typeof window.MutationObserver == 'function') {\n var observer = new window.MutationObserver(function(mutations) {\n mutations.forEach(function(mutation) {\n if (mutation.type === 'childList') {\n that.refresh();\n }\n });\n });\n\n observer.observe(watch, {\n childList: true\n });\n\n return observer;\n } else {\n return false;\n }\n },\n\n createDropdown: function() {\n // Options\n // If we are multiple or showTick option is set, then add the show-tick class\n var showTick = (this.multiple || this.options.showTick) ? ' bootstrap-select--show-tick' : '';\n var inputGroup = this.$element.parent().hasClass('input-group') ? ' input-group-btn' : '';\n var autofocus = this.autofocus ? ' autofocus' : '';\n // Elements\n var header = this.options.header ? '
' + this.options.header + '
' : '';\n var searchbox = '';\n\n if (this.options.liveSearch) {\n searchbox = '
' +\n '' +\n '
';\n }\n\n var actionsbox = '';\n\n if (this.multiple && this.options.actionsBox) {\n actionsbox = '
' +\n '
' +\n '' +\n '' +\n '
' +\n '
';\n }\n\n var donebutton = '';\n\n if (this.multiple && this.options.doneButton) {\n donebutton = '
' +\n '
' +\n '' +\n '
' +\n '
';\n }\n var drop =\n '
' +\n '' +\n '
' +\n header +\n searchbox +\n actionsbox +\n '
' +\n '
' +\n donebutton +\n '
' +\n '
';\n\n return $(drop);\n },\n\n createView: function() {\n var $drop = this.createDropdown();\n var li = this.createLi();\n\n $drop.find('ul')[0].innerHTML = li;\n\n return $drop;\n },\n\n reloadLi: function() {\n // Remove all children.\n this.destroyLi();\n // Re build\n var li = this.createLi();\n\n this.$menuInner[0].innerHTML = li;\n },\n\n destroyLi: function() {\n this.$menu.find('li').remove();\n },\n\n createLi: function() {\n var that = this;\n var _li = [];\n var optID = 0;\n var titleOption = document.createElement('option');\n // increment liIndex whenever a new
element is created to ensure liObj is correct\n var liIndex = -1;\n\n // Helper functions\n /**\n * @param content\n * @param [index]\n * @param [classes]\n * @param [optgroup]\n * @returns {string}\n */\n function generateLI(content, index, classes, optgroup) {\n return '
' + content + '
';\n };\n\n /**\n * @param text\n * @param [classes]\n * @param [inline]\n * @param [tokens]\n * @returns {string}\n */\n function generateA(text, classes, inline, tokens) {\n return '' + text +\n '' +\n '';\n };\n\n if (this.options.title && !this.multiple) {\n // this option doesn't create a new
element, but does add a new option, so liIndex is decreased\n // since liObj is recalculated on every refresh, liIndex needs to be decreased even if the titleOption is already appended\n liIndex--;\n\n if (!this.$element.find('.bs-title-option').length) {\n // Use native JS to prepend option (faster)\n var element = this.$element[0];\n\n titleOption.className = 'bs-title-option';\n titleOption.appendChild(document.createTextNode(this.options.title));\n titleOption.value = '';\n element.insertBefore(titleOption, element.firstChild);\n // Check if selected attribute is already set on an option. If not, select the titleOption option.\n if ($(element.options[element.selectedIndex]).prop('selected') == false) titleOption.selected = true;\n }\n }\n\n this.$element.find('option').each(function(index) {\n var $this = $(this);\n\n liIndex++;\n\n if ($this.hasClass('bs-title-option')) return;\n\n // Get the class and text for the option\n var optionClass = this.className || '';\n var inline = this.style.cssText;\n var text = $this.data('content') ? $this.data('content') : $this.html();\n var tokens = $this.data('tokens') ? $this.data('tokens') : null;\n var subtext = typeof $this.data('subtext') !== 'undefined' ? '' + $this.data('subtext') + '' : '';\n var icon = typeof $this.data('icon') !== 'undefined' ? ' ' : '';\n var isOptgroup = this.parentNode.tagName === 'OPTGROUP';\n var isDisabled = this.disabled || (isOptgroup && this.parentNode.disabled);\n\n if (icon !== '' && isDisabled) {\n icon = '' + icon + '';\n }\n\n if (that.options.hideDisabled && isDisabled && !isOptgroup) {\n liIndex--;\n\n return;\n }\n\n if (!$this.data('content')) {\n // Prepend any icons and append any subtext to the main text.\n text = icon + '' + text + subtext + '';\n }\n\n if (isOptgroup && $this.data('divider') !== true) {\n var optGroupClass = ' ' + this.parentNode.className || '';\n\n // Is it the first option of the optgroup?\n if ($this.index() === 0) {\n optID += 1;\n\n // Get the opt group label\n var label = this.parentNode.label;\n var labelSubtext = typeof $this.parent().data('subtext') !== 'undefined' ? '' + $this.parent().data('subtext') + '' : '';\n var labelIcon = $this.parent().data('icon') ? ' ' : '';\n\n label = labelIcon + '' + label + labelSubtext + '';\n\n // Is it NOT the first option of the select && are there elements in the dropdown?\n if (index !== 0 && _li.length > 0) {\n liIndex++;\n _li.push(generateLI('', null, 'divider', optID + 'div'));\n }\n liIndex++;\n _li.push(generateLI(label, null, 'dropdown__header' + optGroupClass, optID));\n }\n\n if (that.options.hideDisabled && isDisabled) {\n liIndex--;\n\n return;\n }\n\n _li.push(generateLI(generateA(text, 'opt ' + optionClass + optGroupClass, inline, tokens), index, '', optID));\n } else if ($this.data('divider') === true) {\n _li.push(generateLI('', index, 'divider'));\n } else if ($this.data('hidden') === true) {\n _li.push(generateLI(generateA(text, optionClass, inline, tokens), index, 'hidden is-hidden'));\n } else {\n if (this.previousElementSibling && this.previousElementSibling.tagName === 'OPTGROUP') {\n liIndex++;\n _li.push(generateLI('', null, 'divider', optID + 'div'));\n }\n _li.push(generateLI(generateA(text, optionClass, inline, tokens), index));\n }\n\n that.liObj[index] = liIndex;\n });\n\n // If we are not multiple, we don't have a selected item, and we don't have a title, select the first element so something is set in the button\n if (!this.multiple && this.$element.find('option:selected').length === 0 && !this.options.title) {\n this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected');\n }\n\n return _li.join('');\n },\n\n findLis: function() {\n if (this.$lis == null) this.$lis = this.$menu.find('li');\n\n return this.$lis;\n },\n\n /**\n * @param [updateLi] defaults to true\n */\n render: function(updateLi) {\n var that = this;\n var notDisabled;\n\n // Update the LI to match the SELECT\n if (updateLi !== false) {\n this.$element.find('option').each(function(index) {\n var $lis = that.findLis().eq(that.liObj[index]);\n\n that.setDisabled(index, this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled, $lis);\n that.setSelected(index, this.selected, $lis);\n });\n }\n\n this.tabIndex();\n\n var selectedItems = this.$element.find('option').map(function() {\n if (this.selected) {\n if (that.options.hideDisabled && (this.disabled || this.parentNode.tagName === 'OPTGROUP' && this.parentNode.disabled)) return;\n\n var $this = $(this);\n var icon = $this.data('icon') && that.options.showIcon ? ' ' : '';\n var subtext;\n\n if (that.options.showSubtext && $this.data('subtext') && !that.multiple) {\n subtext = ' ' + $this.data('subtext') + '';\n } else {\n subtext = '';\n }\n if (typeof $this.attr('title') !== 'undefined') {\n return $this.attr('title');\n } else if ($this.data('content') && that.options.showContent) {\n return $this.data('content');\n } else {\n return icon + $this.html() + subtext;\n }\n }\n }).toArray();\n\n // Fixes issue in IE10 occurring when no default option is selected and at least one option is disabled\n // Convert all the values into a comma delimited string\n var title = !this.multiple ? selectedItems[0] : selectedItems.join(this.options.multipleSeparator);\n\n // If this is multi select, and the selectText type is count, the show 1 of 2 selected etc..\n if (this.multiple && this.options.selectedTextFormat.indexOf('count') > -1) {\n var max = this.options.selectedTextFormat.split('>');\n\n if ((max.length > 1 && selectedItems.length > max[1]) || (max.length == 1 && selectedItems.length >= 2)) {\n notDisabled = this.options.hideDisabled ? ', [disabled]' : '';\n var totalCount = this.$element.find('option').not('[data-divider=\"true\"], [data-hidden=\"true\"]' + notDisabled).length;\n var tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedItems.length, totalCount) : this.options.countSelectedText;\n\n title = tr8nText.replace('{0}', selectedItems.length.toString()).replace('{1}', totalCount.toString());\n }\n }\n\n if (this.options.title == undefined) {\n this.options.title = this.$element.attr('title');\n }\n\n if (this.options.selectedTextFormat == 'static') {\n title = this.options.title;\n }\n\n // If we dont have a title, then use the default, or if nothing is set at all, use the not selected text\n if (!title) {\n title = typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText;\n }\n\n // strip all html-tags and trim the result\n this.$button.attr('title', $.trim(title.replace(/<[^>]*>?/g, '')));\n this.$button.children('.bootstrap-select__selected').html(title);\n\n this.$element.trigger('rendered.bs.select');\n },\n\n /**\n * @param [style]\n * @param [status]\n */\n setStyle: function(style, status) {\n if (this.$element.attr('class')) {\n this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi, ''));\n }\n\n var buttonClass = style ? style : this.options.style;\n\n if (status == 'add') {\n this.$button.addClass(buttonClass);\n } else if (status == 'remove') {\n this.$button.removeClass(buttonClass);\n } else {\n this.$button.removeClass(this.options.style);\n this.$button.addClass(buttonClass);\n }\n },\n\n liHeight: function(refresh) {\n if (!refresh && (this.options.size === false || this.sizeInfo)) return;\n\n var newElement = document.createElement('div');\n var menu = document.createElement('div');\n var menuInner = document.createElement('ul');\n var divider = document.createElement('li');\n var li = document.createElement('li');\n var a = document.createElement('a');\n var text = document.createElement('span');\n var header = this.options.header && this.$menu.find('.popover-title').length > 0 ? this.$menu.find('.popover-title')[0].cloneNode(true) : null;\n var search = this.options.liveSearch ? document.createElement('div') : null;\n var actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null;\n var doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null;\n\n text.className = 'bootstrap-select__option';\n newElement.className = this.$menu[0].parentNode.className + ' open';\n menu.className = 'dropdown__menu open';\n menuInner.className = 'dropdown__inner';\n divider.className = 'divider';\n\n text.appendChild(document.createTextNode('Inner text'));\n a.appendChild(text);\n li.appendChild(a);\n menuInner.appendChild(li);\n menuInner.appendChild(divider);\n if (header) menu.appendChild(header);\n if (search) {\n // create a span instead of input as creating an input element is slower\n var input = document.createElement('span');\n\n search.className = 'bootstrap-select__searchbox';\n input.className = 'form-textfield__input';\n search.appendChild(input);\n menu.appendChild(search);\n }\n if (actions) menu.appendChild(actions);\n menu.appendChild(menuInner);\n if (doneButton) menu.appendChild(doneButton);\n newElement.appendChild(menu);\n\n document.body.appendChild(newElement);\n var liHeight = a.offsetHeight;\n var headerHeight = header ? header.offsetHeight : 0;\n // input height 32px, offset gives 6px\n var searchHeight = search ? 32 : 0;\n var actionsHeight = actions ? actions.offsetHeight : 0;\n var doneButtonHeight = doneButton ? doneButton.offsetHeight : 0;\n var dividerHeight = $(divider).outerHeight(true);\n // fall back to jQuery if getComputedStyle is not supported\n var menuStyle = typeof getComputedStyle === 'function' ? getComputedStyle(menu) : false;\n var $menu = menuStyle ? null : $(menu);\n var menuPadding = parseInt(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) +\n parseInt(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) +\n parseInt(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) +\n parseInt(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth'));\n var menuExtras = menuPadding +\n parseInt(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) +\n parseInt(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2;\n\n document.body.removeChild(newElement);\n\n this.sizeInfo = {\n liHeight: liHeight,\n headerHeight: headerHeight,\n searchHeight: searchHeight,\n actionsHeight: actionsHeight,\n doneButtonHeight: doneButtonHeight,\n dividerHeight: dividerHeight,\n menuPadding: menuPadding,\n menuExtras: menuExtras\n };\n },\n\n setSize: function() {\n this.findLis();\n this.liHeight();\n\n if (this.options.header) this.$menu.css('padding-top', 0);\n if (this.options.size === false) return;\n\n var that = this;\n var $menu = this.$menu;\n var $menuInner = this.$menuInner;\n var $window = $(window);\n var selectHeight = this.$newElement[0].offsetHeight;\n var liHeight = this.sizeInfo['liHeight'];\n var headerHeight = this.sizeInfo['headerHeight'];\n var searchHeight = this.sizeInfo['searchHeight'];\n var actionsHeight = this.sizeInfo['actionsHeight'];\n var doneButtonHeight = this.sizeInfo['doneButtonHeight'];\n var divHeight = this.sizeInfo['dividerHeight'];\n var menuPadding = this.sizeInfo['menuPadding'];\n var menuExtras = this.sizeInfo['menuExtras'];\n var notDisabled = this.options.hideDisabled ? '.disabled' : '';\n var menuHeight;\n var getHeight;\n var selectOffsetTop;\n var selectOffsetBot;\n\n function posVert() {\n selectOffsetTop = that.$newElement.offset().top - $window.scrollTop();\n selectOffsetBot = $window.height() - selectOffsetTop - selectHeight;\n };\n\n function getSize() {\n var minHeight;\n var lis = that.$menuInner[0].getElementsByTagName('li');\n var lisVisible = Array.prototype.filter ? Array.prototype.filter.call(lis, hasClass('hidden', false)) : that.$lis.not('.hidden');\n var optGroup = Array.prototype.filter ? Array.prototype.filter.call(lisVisible, hasClass('dropdown__header', true)) : lisVisible.filter('.dropdown__header');\n\n function hasClass(className, include) {\n return function(element) {\n if (include) {\n return (element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n } else {\n return !(element.classList ? element.classList.contains(className) : $(element).hasClass(className));\n }\n };\n }\n\n posVert();\n menuHeight = selectOffsetBot - menuExtras;\n\n if (that.options.container) {\n if (!$menu.data('height')) $menu.data('height', $menu.height());\n getHeight = $menu.data('height');\n } else {\n getHeight = $menu.height();\n }\n\n if (that.options.dropupAuto) {\n that.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);\n }\n if (that.$newElement.hasClass('dropup')) {\n menuHeight = selectOffsetTop - menuExtras;\n }\n\n if ((lisVisible.length + optGroup.length) > 3) {\n minHeight = liHeight * 3 + menuExtras - 2;\n } else {\n minHeight = 0;\n }\n\n menuHeight -= 40;\n $menu.css({\n 'max-height': menuHeight + 'px',\n overflow: 'hidden',\n 'min-height': minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px'\n });\n $menuInner.css({\n 'max-height': menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding + 'px',\n 'overflow-y': 'auto',\n 'min-height': Math.max(minHeight - menuPadding, 0) + 'px'\n });\n }\n\n posVert();\n\n if (this.options.size === 'auto') {\n getSize();\n this.$searchbox.off('input.getSize propertychange.getSize').on('input.getSize propertychange.getSize', getSize);\n $window.off('resize.getSize scroll.getSize').on('resize.getSize scroll.getSize', getSize);\n } else if (this.options.size && this.options.size != 'auto' && this.$lis.not(notDisabled).length > this.options.size) {\n var optIndex = this.$lis.not('.divider').not(notDisabled).children().slice(0, this.options.size).last().parent().index();\n var divLength = this.$lis.slice(0, optIndex + 1).filter('.divider').length;\n\n menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding;\n\n if (that.options.container) {\n if (!$menu.data('height')) $menu.data('height', $menu.height());\n getHeight = $menu.data('height');\n } else {\n getHeight = $menu.height();\n }\n\n if (that.options.dropupAuto) {\n // noinspection JSUnusedAssignment\n this.$newElement.toggleClass('dropup', selectOffsetTop > selectOffsetBot && (menuHeight - menuExtras) < getHeight);\n }\n $menu.css({\n 'max-height': menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight + 'px',\n overflow: 'hidden',\n 'min-height': ''\n });\n $menuInner.css({\n 'max-height': menuHeight - menuPadding + 'px',\n 'overflow-y': 'auto',\n 'min-height': ''\n });\n }\n },\n\n setWidth: function() {\n if (this.options.width === 'auto') {\n this.$menu.css('min-width', '0');\n\n // Get correct width if element is hidden\n var $selectClone = this.$menu.parent().clone().appendTo('body');\n var $selectClone2 = this.options.container ? this.$newElement.clone().appendTo('body') : $selectClone;\n var ulWidth = $selectClone.children('.dropdown__menu').outerWidth();\n var btnWidth = $selectClone2.css('width', 'auto').children('button').outerWidth();\n\n $selectClone.remove();\n $selectClone2.remove();\n\n // Set width to whatever's larger, button title or longest option\n this.$newElement.css('width', Math.max(ulWidth, btnWidth) + 'px');\n } else if (this.options.width === 'fit') {\n // Remove inline min-width so width can be changed from 'auto'\n this.$menu.css('min-width', '');\n this.$newElement.css('width', '').addClass('fit-width');\n } else if (this.options.width) {\n // Remove inline min-width so width can be changed from 'auto'\n this.$menu.css('min-width', '');\n this.$newElement.css('width', this.options.width);\n } else {\n // Remove inline min-width/width so width can be changed\n this.$menu.css('min-width', '');\n this.$newElement.css('width', '');\n }\n // Remove fit-width class if width is changed programmatically\n if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') {\n this.$newElement.removeClass('fit-width');\n }\n },\n\n selectPosition: function() {\n this.$bsContainer = $('');\n\n var that = this;\n var pos;\n\n function getPlacement($element) {\n that.$bsContainer.addClass($element.attr('class').replace(/form-textfield__input|fit-width/gi, '')).toggleClass('dropup', $element.hasClass('dropup'));\n pos = $element.offset();\n that.$bsContainer.css({\n top: pos.top,\n left: pos.left,\n width: $element[0].offsetWidth\n });\n };\n\n this.$button.on('click', function() {\n var $this = $(this);\n\n if (that.isDisabled()) {\n return;\n }\n\n getPlacement(that.$newElement);\n\n that.$bsContainer\n .appendTo(that.options.container)\n .toggleClass('open', !$this.hasClass('open'))\n .append(that.$menu);\n });\n\n $(window).on('resize scroll', function() {\n getPlacement(that.$newElement);\n });\n\n this.$element.on('hide.bs.select', function() {\n that.$menu.data('height', that.$menu.height());\n that.$bsContainer.detach();\n });\n },\n\n setSelected: function(index, selected, $lis) {\n if (!$lis) {\n $lis = this.findLis().eq(this.liObj[index]);\n }\n\n $lis.toggleClass('selected', selected);\n },\n\n setDisabled: function(index, disabled, $lis) {\n if (!$lis) {\n $lis = this.findLis().eq(this.liObj[index]);\n }\n\n if (disabled) {\n $lis.addClass('disabled').children('a').attr('href', '#').attr('tabindex', -1);\n } else {\n $lis.removeClass('disabled').children('a').removeAttr('href').attr('tabindex', 0);\n }\n },\n\n isDisabled: function() {\n return this.$element[0].disabled;\n },\n\n checkDisabled: function() {\n var that = this;\n\n if (this.isDisabled()) {\n this.$newElement.addClass('disabled');\n this.$button.addClass('disabled').attr('tabindex', -1);\n } else {\n if (this.$button.hasClass('disabled')) {\n this.$newElement.removeClass('disabled');\n this.$button.removeClass('disabled');\n }\n\n if (this.$button.attr('tabindex') == -1 && !this.$element.data('tabindex')) {\n this.$button.removeAttr('tabindex');\n }\n }\n\n this.$button.click(function() {\n return !that.isDisabled();\n });\n },\n\n tabIndex: function() {\n if (this.$element.data('tabindex') !== this.$element.attr('tabindex') &&\n (this.$element.attr('tabindex') !== -98 && this.$element.attr('tabindex') !== '-98')) {\n this.$element.data('tabindex', this.$element.attr('tabindex'));\n this.$button.attr('tabindex', this.$element.data('tabindex'));\n }\n\n this.$element.attr('tabindex', -98);\n },\n\n clickListener: function() {\n var that = this;\n var $document = $(document);\n\n this.$newElement.on('touchstart.dropdown', '.dropdown__menu', function(e) {\n e.stopPropagation();\n });\n\n $document.data('spaceSelect', false);\n\n this.$button.on('keyup', function(e) {\n if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) {\n e.preventDefault();\n $document.data('spaceSelect', false);\n }\n });\n\n this.$button.on('click', function() {\n that.setSize();\n });\n\n this.$element.on('shown.bs.select', function() {\n if (!that.options.liveSearch && !that.multiple) {\n that.$menuInner.find('.selected a').focus();\n } else if (!that.multiple) {\n var selectedIndex = that.liObj[that.$element[0].selectedIndex];\n\n if (typeof selectedIndex !== 'number' || that.options.size === false) return;\n\n // scroll to selected option\n var offset = that.$lis.eq(selectedIndex)[0].offsetTop - that.$menuInner[0].offsetTop;\n\n offset = offset - that.$menuInner[0].offsetHeight / 2 + that.sizeInfo.liHeight / 2;\n that.$menuInner[0].scrollTop = offset;\n }\n });\n\n this.$menuInner.on('click', 'li a', function(e) {\n var $this = $(this);\n var clickedIndex = $this.parent().data('originalIndex');\n var prevValue = that.$element.val();\n var prevIndex = that.$element.prop('selectedIndex');\n\n // Don't close on multi choice menu\n if (that.multiple) {\n e.stopPropagation();\n }\n\n e.preventDefault();\n\n // Don't run if we have been disabled\n if (!that.isDisabled() && !$this.parent().hasClass('disabled')) {\n var $options = that.$element.find('option');\n var $option = $options.eq(clickedIndex);\n var state = $option.prop('selected');\n var $optgroup = $option.parent('optgroup');\n var maxOptions = that.options.maxOptions;\n var maxOptionsGrp = $optgroup.data('maxOptions') || false;\n\n // Deselect all others if not multi select box\n if (!that.multiple) {\n $options.prop('selected', false);\n $option.prop('selected', true);\n that.$menuInner.find('.selected').removeClass('selected');\n that.setSelected(clickedIndex, true);\n // Toggle the one we have chosen if we are multi select.\n } else {\n $option.prop('selected', !state);\n that.setSelected(clickedIndex, !state);\n $this.blur();\n\n if (maxOptions !== false || maxOptionsGrp !== false) {\n var maxReached = maxOptions < $options.filter(':selected').length;\n var maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length;\n\n if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) {\n if (maxOptions && maxOptions == 1) {\n $options.prop('selected', false);\n $option.prop('selected', true);\n that.$menuInner.find('.selected').removeClass('selected');\n that.setSelected(clickedIndex, true);\n } else if (maxOptionsGrp && maxOptionsGrp == 1) {\n $optgroup.find('option:selected').prop('selected', false);\n $option.prop('selected', true);\n var optgroupID = $this.parent().data('optgroup');\n\n that.$menuInner.find('[data-optgroup=\"' + optgroupID + '\"]').removeClass('selected');\n that.setSelected(clickedIndex, true);\n } else {\n var maxOptionsArr = that.options.maxOptionsText;\n\n if (typeof that.options.maxOptionsText === 'function') {\n maxOptionsArr = that.options.maxOptionsText(maxOptions, maxOptionsGrp);\n }\n var maxTxt = maxOptionsArr[0].replace('{n}', maxOptions);\n var maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp);\n var $notify = $('');\n // If {var} is set in array, replace it\n /** @deprecated */\n\n if (maxOptionsArr[2]) {\n maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]);\n maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]);\n }\n\n $option.prop('selected', false);\n\n that.$menu.append($notify);\n\n if (maxOptions && maxReached) {\n $notify.append($('
' + maxTxt + '
'));\n that.$element.trigger('maxReached.bs.select');\n }\n\n if (maxOptionsGrp && maxReachedGrp) {\n $notify.append($('
' + maxTxtGrp + '
'));\n that.$element.trigger('maxReachedGrp.bs.select');\n }\n\n setTimeout(function() {\n that.setSelected(clickedIndex, false);\n }, 10);\n\n $notify.delay(750).fadeOut(300, function() {\n $(this).remove();\n });\n }\n }\n }\n }\n\n if (!that.multiple) {\n that.$button.focus();\n } else if (that.options.liveSearch) {\n that.$searchbox.focus();\n }\n\n // Trigger select 'change'\n if ((prevValue != that.$element.val() && that.multiple) || (prevIndex != that.$element.prop('selectedIndex') && !that.multiple)) {\n // $option.prop('selected') is current option state (selected/unselected). state is previous option state.\n that.$element\n .trigger('changed.bs.select', [clickedIndex, $option.prop('selected'), state])\n .triggerNative('change');\n }\n }\n });\n\n this.$menu.on('click', 'li.disabled a, .popover-title, .popover-title :not(.close)', function(e) {\n if (e.currentTarget == this) {\n e.preventDefault();\n e.stopPropagation();\n if (that.options.liveSearch && !$(e.target).hasClass('close')) {\n that.$searchbox.focus();\n } else {\n that.$button.focus();\n }\n }\n });\n\n this.$menuInner.on('click', '.divider, .dropdown__header', function(e) {\n e.preventDefault();\n e.stopPropagation();\n if (that.options.liveSearch) {\n that.$searchbox.focus();\n } else {\n that.$button.focus();\n }\n });\n\n this.$menu.on('click', '.popover-title .close', function() {\n that.$button.click();\n });\n\n this.$searchbox.on('click', function(e) {\n e.stopPropagation();\n });\n\n this.$menu.on('click', '.actions-btn', function(e) {\n if (that.options.liveSearch) {\n that.$searchbox.focus();\n } else {\n that.$button.focus();\n }\n\n e.preventDefault();\n e.stopPropagation();\n\n if ($(this).hasClass('bs-select-all')) {\n that.selectAll();\n } else {\n that.deselectAll();\n }\n });\n\n this.$element.change(function() {\n that.render(false);\n });\n },\n\n liveSearchListener: function() {\n var that = this;\n var $noResults = $('
');\n\n this.$button.on('click.dropdown.data-api touchstart.dropdown.data-api', function() {\n that.$menuInner.find('.is-active').removeClass('is-active');\n if (that.$searchbox.val()) {\n that.$searchbox.val('');\n that.$lis.not('.is-hidden').removeClass('hidden');\n if ($noResults.parent().length) $noResults.remove();\n }\n if (!that.multiple) that.$menuInner.find('.selected').addClass('is-active');\n setTimeout(function() {\n that.$searchbox.focus();\n }, 10);\n });\n\n this.$searchbox.on('click.dropdown.data-api focus.dropdown.data-api touchend.dropdown.data-api', function(e) {\n e.stopPropagation();\n });\n\n this.$searchbox.on('input propertychange', function() {\n if (that.$searchbox.val()) {\n var $searchBase = that.$lis.not('.is-hidden').removeClass('hidden').children('a');\n\n if (that.options.liveSearchNormalize) {\n $searchBase = $searchBase.not(':a' + that._searchStyle() + '(\"' + normalizeToBase(that.$searchbox.val()) + '\")');\n } else {\n $searchBase = $searchBase.not(':' + that._searchStyle() + '(\"' + that.$searchbox.val() + '\")');\n }\n $searchBase.parent().addClass('hidden');\n\n that.$lis.filter('.dropdown__header').each(function() {\n var $this = $(this);\n var optgroup = $this.data('optgroup');\n\n if (that.$lis.filter('[data-optgroup=' + optgroup + ']').not($this).not('.hidden').length === 0) {\n $this.addClass('hidden');\n that.$lis.filter('[data-optgroup=' + optgroup + 'div]').addClass('hidden');\n }\n });\n\n var $lisVisible = that.$lis.not('.hidden');\n\n // hide divider if first or last visible, or if followed by another divider\n $lisVisible.each(function(index) {\n var $this = $(this);\n\n if ($this.hasClass('divider') && (\n $this.index() === $lisVisible.first().index() ||\n $this.index() === $lisVisible.last().index() ||\n $lisVisible.eq(index + 1).hasClass('divider'))) {\n $this.addClass('hidden');\n }\n });\n\n if (!that.$lis.not('.hidden, .bootstrap-select__no-results').length) {\n if ($noResults.parent().length) {\n $noResults.remove();\n }\n $noResults.html(that.options.noneResultsText.replace('{0}', '\"' + htmlEscape(that.$searchbox.val()) + '\"')).show();\n that.$menuInner.append($noResults);\n } else if ($noResults.parent().length) {\n $noResults.remove();\n }\n } else {\n that.$lis.not('.is-hidden').removeClass('hidden');\n if ($noResults.parent().length) {\n $noResults.remove();\n }\n }\n\n that.$lis.filter('.is-active').removeClass('is-active');\n if (that.$searchbox.val()) that.$lis.not('.hidden, .divider, .dropdown__header').eq(0).addClass('is-active').children('a').focus();\n $(this).focus();\n });\n },\n\n _searchStyle: function() {\n var styles = {\n begins: 'ibegins',\n startsWith: 'ibegins'\n };\n\n return styles[this.options.liveSearchStyle] || 'icontains';\n },\n\n val: function(value) {\n if (typeof value !== 'undefined') {\n this.$element.val(value);\n this.render();\n\n return this.$element;\n } else {\n return this.$element.val();\n }\n },\n\n changeAll: function(status) {\n if (typeof status === 'undefined') status = true;\n\n this.findLis();\n\n var $options = this.$element.find('option');\n var $lisVisible = this.$lis.not('.divider, .dropdown__header, .disabled, .hidden').toggleClass('selected', status);\n var lisVisLen = $lisVisible.length;\n var selectedOptions = [];\n\n for (var i = 0; i < lisVisLen; i++) {\n var origIndex = $lisVisible[i].getAttribute('data-original-index');\n\n selectedOptions[selectedOptions.length] = $options.eq(origIndex)[0];\n }\n\n $(selectedOptions).prop('selected', status);\n\n this.render(false);\n\n this.$element\n .trigger('changed.bs.select')\n .triggerNative('change');\n },\n\n selectAll: function() {\n return this.changeAll(true);\n },\n\n deselectAll: function() {\n return this.changeAll(false);\n },\n\n toggle: function(e) {\n e = e || window.event;\n\n if (e) e.stopPropagation();\n\n this.$button.trigger('click');\n },\n\n keydown: function(e) {\n var $this = $(this);\n var $parent = $this.is('input') ? $this.parent().parent() : $this.parent();\n var $items;\n var that = $parent.data('this');\n var index;\n var next;\n var first;\n var last;\n var prev;\n var nextPrev;\n var prevIndex;\n var isActive;\n var selector = ':not(.disabled, .hidden, .dropdown__header, .divider)';\n var keyCodeMap = {\n 32: ' ',\n 48: '0',\n 49: '1',\n 50: '2',\n 51: '3',\n 52: '4',\n 53: '5',\n 54: '6',\n 55: '7',\n 56: '8',\n 57: '9',\n 59: ';',\n 65: 'a',\n 66: 'b',\n 67: 'c',\n 68: 'd',\n 69: 'e',\n 70: 'f',\n 71: 'g',\n 72: 'h',\n 73: 'i',\n 74: 'j',\n 75: 'k',\n 76: 'l',\n 77: 'm',\n 78: 'n',\n 79: 'o',\n 80: 'p',\n 81: 'q',\n 82: 'r',\n 83: 's',\n 84: 't',\n 85: 'u',\n 86: 'v',\n 87: 'w',\n 88: 'x',\n 89: 'y',\n 90: 'z',\n 96: '0',\n 97: '1',\n 98: '2',\n 99: '3',\n 100: '4',\n 101: '5',\n 102: '6',\n 103: '7',\n 104: '8',\n 105: '9'\n };\n\n if (that.options.liveSearch) $parent = $this.parent().parent();\n\n if (that.options.container) $parent = that.$menu;\n\n $items = $('[role=menu] li', $parent);\n\n isActive = that.$newElement.hasClass('open');\n\n if (!isActive && (e.keyCode >= 48 && e.keyCode <= 57 || e.keyCode >= 96 && e.keyCode <= 105 || e.keyCode >= 65 && e.keyCode <= 90)) {\n if (!that.options.container) {\n that.setSize();\n that.$menu.parent().addClass('open');\n isActive = true;\n } else {\n that.$button.trigger('click');\n }\n that.$searchbox.focus();\n }\n\n if (that.options.liveSearch) {\n if (/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && that.$menu.find('.is-active').length === 0) {\n e.preventDefault();\n that.$menu.parent().removeClass('open');\n if (that.options.container) that.$newElement.removeClass('open');\n that.$button.focus();\n }\n // $items contains li elements when liveSearch is enabled\n $items = $('[role=menu] li' + selector, $parent);\n if (!$this.val() && !(/(38|40)/).test(e.keyCode.toString(10))) {\n if ($items.filter('.is-active').length === 0) {\n $items = that.$menuInner.find('li');\n if (that.options.liveSearchNormalize) {\n $items = $items.filter(':a' + that._searchStyle() + '(' + normalizeToBase(keyCodeMap[e.keyCode]) + ')');\n } else {\n $items = $items.filter(':' + that._searchStyle() + '(' + keyCodeMap[e.keyCode] + ')');\n }\n }\n }\n }\n\n if (!$items.length) return;\n\n if (/(38|40)/.test(e.keyCode.toString(10))) {\n index = $items.index($items.find('a').filter(':focus').parent());\n first = $items.filter(selector).first().index();\n last = $items.filter(selector).last().index();\n next = $items.eq(index).nextAll(selector).eq(0).index();\n prev = $items.eq(index).prevAll(selector).eq(0).index();\n nextPrev = $items.eq(next).prevAll(selector).eq(0).index();\n\n if (that.options.liveSearch) {\n $items.each(function(i) {\n if (!$(this).hasClass('disabled')) {\n $(this).data('index', i);\n }\n });\n index = $items.index($items.filter('.is-active'));\n first = $items.first().data('index');\n last = $items.last().data('index');\n next = $items.eq(index).nextAll().eq(0).data('index');\n prev = $items.eq(index).prevAll().eq(0).data('index');\n nextPrev = $items.eq(next).prevAll().eq(0).data('index');\n }\n\n prevIndex = $this.data('prevIndex');\n\n if (e.keyCode == 38) {\n if (that.options.liveSearch) index--;\n if (index != nextPrev && index > prev) index = prev;\n if (index < first) index = first;\n if (index == prevIndex) index = last;\n } else if (e.keyCode == 40) {\n if (that.options.liveSearch) index++;\n if (index == -1) index = 0;\n if (index != nextPrev && index < next) index = next;\n if (index > last) index = last;\n if (index == prevIndex) index = first;\n }\n\n $this.data('prevIndex', index);\n\n if (!that.options.liveSearch) {\n $items.eq(index).children('a').focus();\n } else {\n e.preventDefault();\n if (!$this.hasClass('dropdown-toggle')) {\n $items.removeClass('is-active').eq(index).addClass('is-active').children('a').focus();\n $this.focus();\n }\n }\n } else if (!$this.is('input')) {\n var keyIndex = [];\n var count;\n var prevKey;\n\n $items.each(function() {\n if (!$(this).hasClass('disabled')) {\n if ($.trim($(this).children('a').text().toLowerCase()).substring(0, 1) == keyCodeMap[e.keyCode]) {\n keyIndex.push($(this).index());\n }\n }\n });\n\n count = $(document).data('keycount');\n count++;\n $(document).data('keycount', count);\n\n prevKey = $.trim($(':focus').text().toLowerCase()).substring(0, 1);\n\n if (prevKey != keyCodeMap[e.keyCode]) {\n count = 1;\n $(document).data('keycount', count);\n } else if (count >= keyIndex.length) {\n $(document).data('keycount', 0);\n if (count > keyIndex.length) count = 1;\n }\n\n $items.eq(keyIndex[count - 1]).children('a').focus();\n }\n\n // Select focused option if \"Enter\", \"Spacebar\" or \"Tab\" (when selectOnTab is true) are pressed inside the menu.\n if ((/(13|32)/.test(e.keyCode.toString(10)) || (/(^9$)/.test(e.keyCode.toString(10)) && that.options.selectOnTab)) && isActive) {\n if (!(/(32)/).test(e.keyCode.toString(10))) e.preventDefault();\n if (!that.options.liveSearch) {\n var elem = $(':focus');\n\n elem.click();\n // Bring back focus for multiselects\n elem.focus();\n // Prevent screen from scrolling if the user hit the spacebar\n e.preventDefault();\n // Fixes spacebar selection of dropdown items in FF & IE\n $(document).data('spaceSelect', true);\n } else if (!(/(32)/).test(e.keyCode.toString(10))) {\n that.$menuInner.find('.is-active a').click();\n $this.focus();\n }\n $(document).data('keycount', 0);\n }\n\n if ((/(^9$|27)/.test(e.keyCode.toString(10)) && isActive && (that.multiple || that.options.liveSearch)) || (/(27)/.test(e.keyCode.toString(10)) && !isActive)) {\n that.$menu.parent().removeClass('open');\n if (that.options.container) that.$newElement.removeClass('open');\n that.$button.focus();\n }\n },\n\n mobile: function() {\n this.$element.addClass('mobile-device');\n },\n\n refresh: function() {\n this.$lis = null;\n this.liObj = {};\n this.reloadLi();\n this.render();\n this.checkDisabled();\n this.liHeight(true);\n this.setStyle();\n this.setWidth();\n if (this.$lis) this.$searchbox.trigger('propertychange');\n\n this.$element.trigger('refreshed.bs.select');\n },\n\n hide: function() {\n this.$newElement.hide();\n },\n\n show: function() {\n this.$newElement.show();\n },\n\n remove: function() {\n this.$newElement.remove();\n this.$element.remove();\n },\n\n destroy: function() {\n this.$newElement.before(this.$element).remove();\n\n if (this.$bsContainer) {\n this.$bsContainer.remove();\n } else {\n this.$menu.remove();\n }\n\n if (this.observer) {\n this.observer.disconnect();\n }\n\n this.$element\n .off('.bs.select')\n .removeData('selectpicker')\n .removeClass('bs-select-hidden selectpicker');\n }\n };\n\n // SELECTPICKER PLUGIN DEFINITION\n // ==============================\n function Plugin(option, event) {\n // get the args of the outer function..\n var args = arguments;\n // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them\n // to get lost/corrupted in android 2.3 and IE9 #715 #775\n var _option = option;\n var _event = event;\n\n [].shift.apply(args);\n\n var value;\n var chain = this.each(function() {\n var $this = $(this);\n\n if ($this.is('select')) {\n var data = $this.data('selectpicker');\n var options = typeof _option == 'object' && _option;\n\n if (!data) {\n var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, $this.data(), options);\n\n config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), $this.data().template, options.template);\n $this.data('selectpicker', (data = new Selectpicker(this, config, _event)));\n } else if (options) {\n for (var i in options) {\n if (options.hasOwnProperty(i)) {\n data.options[i] = options[i];\n }\n }\n }\n\n if (typeof _option == 'string') {\n if (data[_option] instanceof Function) {\n value = data[_option].apply(data, args);\n } else {\n value = data.options[_option];\n }\n }\n }\n });\n\n if (typeof value !== 'undefined') {\n // noinspection JSUnusedAssignment\n return value;\n } else {\n return chain;\n }\n }\n\n var old = $.fn.selectpicker;\n\n $.fn.selectpicker = Plugin;\n $.fn.selectpicker.Constructor = Selectpicker;\n\n // SELECTPICKER NO CONFLICT\n // ========================\n $.fn.selectpicker.noConflict = function() {\n $.fn.selectpicker = old;\n\n return this;\n };\n\n $(document)\n .data('keycount', 0)\n .on('keydown.bs.select', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"menu\"], .bootstrap-select__searchbox input', Selectpicker.prototype.keydown)\n .on('focusin.modal', '.bootstrap-select [data-toggle=dropdown], .bootstrap-select [role=\"menu\"], .bootstrap-select__searchbox input', function(e) {\n e.stopPropagation();\n });\n\n // SELECTPICKER DATA-API\n // =====================\n $(window).on('load.bs.select.data-api', function() {\n $('.selectpicker').each(function() {\n var $selectpicker = $(this);\n\n Plugin.call($selectpicker, $selectpicker.data());\n });\n });\n\n $(document).on('enhance.form.select', function(event) {\n $(event.target).find('.form-select select').each(function() {\n var $this = $(this);\n\n if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent) && !$this.data('live-search')) {\n $this.selectpicker('mobile');\n } else {\n $this.selectpicker();\n }\n });\n });\n\n $(document).trigger('enhance.form.select');\n })(jQuery);\n}));\n","(function($) {\n $.fn.elinaTextfield = function() {\n var focusClass = 'is-focused';\n var dirtyClass = 'is-dirty';\n\n return this.each(function() {\n var self = $(this);\n var input = self.find('.form-textfield__input:not(.bootstrap-select)');\n var label = self.find('.form-textfield__label');\n\n function checkValue() {\n if (!input.val() || input.val() == '') {\n self.removeClass(dirtyClass);\n } else {\n self.addClass(dirtyClass);\n }\n }\n\n function resizeHeight() {\n input.css('min-height', 0);\n input.css('min-height', (input.prop('scrollHeight') + 1));\n }\n\n if (self.data('focus-text') && self.data('blur-text') && self.hasClass('is-dirty')) {\n label.text(self.data('focus-text'));\n }\n input.on('focus', function() {\n self.addClass(focusClass);\n if (self.data('focus-text') && self.data('blur-text')) {\n setTimeout(function() {\n label.text(self.data('focus-text'));\n }, 100);\n }\n });\n input.on('blur', function() {\n setTimeout(function() {\n self.removeClass(focusClass);\n }, 100);\n\n if (self.data('focus-text') && self.data('blur-text') && input.val() == '') {\n setTimeout(function() {\n label.text(self.data('blur-text'));\n }, 100);\n }\n });\n input.on('change', function() {\n checkValue();\n });\n\n if (input.is('textarea')) {\n resizeHeight();\n\n input.on('input', function() {\n resizeHeight();\n });\n }\n\n checkValue();\n\n $(window).on('load', function() {\n checkValue();\n\n setTimeout(function() {\n checkValue();\n }, 500);\n });\n\n $(window).on('resize', function() {\n if (input.is('textarea')) {\n resizeHeight();\n }\n });\n });\n };\n}(jQuery));\n",";(function($) {\n 'use strict';\n\n /**\n * Declare variables\n */\n // Plugin Class\n var Validetta = {};\n // Current fields/fields\n var FIELDS = {};\n // RegExp for input validate rules\n var RRULE = new RegExp(/^(minChecked|maxChecked|minSelected|maxSelected|minLength|maxLength|equalTo|different|regExp|remote|callback)\\[(\\w{1,15})\\]/i);\n // RegExp for mail control method\n // @from ( http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29 )\n var RMAIL = new RegExp(/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/);\n // RegExp for input number control method\n var RNUMBER = new RegExp(/^[\\-\\+]?(\\d+|\\d+\\.?\\d+)$/);\n\n /**\n * Form validate error messages\n */\n var messages = {\n required: 'This field is required. Please be sure to check.',\n email: 'Your E-mail address appears to be invalid. Please be sure to check.',\n number: 'You can enter only numbers in this field.',\n maxLength: 'Maximum {count} characters allowed!',\n minLength: 'Minimum {count} characters allowed!',\n maxChecked: 'Maximum {count} options allowed. Please be sure to check.',\n minChecked: 'Please select minimum {count} options.',\n maxSelected: 'Maximum {count} selection allowed. Please be sure to check.',\n minSelected: 'Minimum {count} selection allowed. Please be sure to check.',\n notEqual: 'Fields do not match. Please be sure to check.',\n different: 'Fields cannot be the same as each other',\n creditCard: 'Invalid credit card number. Please be sure to check.'\n };\n\n /**\n * Plugin defaults\n */\n var defaults = {\n // If you dont want to display error messages set this options false\n showErrorMessages: true,\n // Class of the element that would receive error message\n errorTemplateClass: 'form-error',\n // Class that would be added on every failing validation field\n errorClass: 'is-invalid',\n // Same for valid validation\n validClass: 'is-valid',\n validIconClass: 'form-textfield__icon--valid',\n // To enable real-time form control, set this option true.\n realTime: false,\n onValid: function() {\n // This function to be called when the user submits the form and there is no error.\n $(this.form).trigger('valid.telia.validation');\n },\n onError: function() {\n // This function to be called when the user submits the form and there are some errors\n $(this.form).trigger('error.telia.validation');\n },\n validators: {\n regExp: {\n date: {\n pattern: /^(?:(?:31(\\.)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\.)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\.)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\.)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$/,\n errorMessage: 'You have not entered a correctly formatted date.'\n },\n number: {\n pattern: /^[\\-\\+]?(\\d+|\\d+[,.]?\\d+)$/,\n errorMessage: 'You can enter only numbers in this field.'\n }\n }\n }\n };\n\n /**\n * Clears the left and right spaces of given parameter.\n * This is the function for string parameter !\n * If parameter is an array, function will return the parameter without trimed\n *\n * @param {string} value\n * @return {mixed}\n */\n function trim(value) {\n return typeof value === 'string' ? value.replace(/^\\s+|\\s+$/g, '') : value;\n };\n\n /**\n * Validator\n * {count} which used below is the specified maximum or minimum value\n * e.g if method is minLength and rule is 2 ( minLength[2] )\n * Output error windows text will be : 'Please select minimum 2 options.'\n *\n * @namespace\n * @param {object} tmp = this.tmp Tmp object for store current field and its value\n * @param {String} val : field value\n */\n var Validator = {\n required: function(tmp, self) {\n switch (tmp.el.type) {\n case 'checkbox' : return tmp.el.checked || messages.required;\n case 'radio' : return this.radio.call(self, tmp.el) || messages.required;\n case 'select-multiple' : return tmp.val.length > 0 || messages.required;\n default : return tmp.val !== '' || messages.required;\n }\n },\n // Mail check - it checks the value if it's a valid email address or not\n email: function(tmp) {\n return RMAIL.test(tmp.val) || messages.email;\n },\n // Number check\n number: function(tmp) {\n return RNUMBER.test(tmp.val) || messages.number;\n },\n // Minimum length check\n minLength: function(tmp) {\n var _length = tmp.val.length;\n\n return _length === 0 || _length >= tmp.arg || messages.minLength.replace('{count}', tmp.arg);\n },\n // Maximum lenght check\n maxLength: function(tmp) {\n return tmp.val.length <= tmp.arg || messages.maxLength.replace('{count}', tmp.arg);\n },\n // equalTo check\n equalTo: function(tmp, self) {\n return self.form.querySelector('input[name=\"' + tmp.arg + '\"]').value === tmp.val || messages.notEqual;\n },\n different: function(tmp, self) {\n return self.form.querySelector('input[name=\"' + tmp.arg + '\"]').value !== tmp.val || messages.different;\n },\n\n /**\n * Credit Card Control\n * @from : http://af-design.com/blog/2010/08/18/validating-credit-card-numbers\n */\n creditCard: function(tmp) {\n // allow empty because empty check does by required metheod\n if (tmp.val === '') return true;\n var reg;\n var cardNumber;\n var pos;\n var digit;\n var i;\n var subTotal;\n var sum = 0;\n var strlen;\n\n reg = new RegExp(/[^0-9]+/g);\n cardNumber = tmp.val.replace(reg, '');\n strlen = cardNumber.length;\n if (strlen < 16) return messages.creditCard;\n for (i = 0; i < strlen; i++) {\n pos = strlen - i;\n digit = parseInt(cardNumber.substring(pos - 1, pos), 10);\n if (i % 2 === 1) {\n subTotal = digit * 2;\n if (subTotal > 9) {\n subTotal = 1 + (subTotal - 10);\n }\n } else {\n subTotal = digit;\n }\n sum += subTotal;\n }\n if (sum > 0 && sum % 10 === 0) return true;\n\n return messages.creditCard;\n },\n // Checkbox check\n maxChecked: function(tmp, self) {\n var cont = $(self.form.querySelectorAll('input[type=checkbox][name=\"' + tmp.el.name + '\"]'));\n // we dont want to open an error window for all checkboxes which have same \"name\"\n\n if (cont.index(tmp.el) !== 0) return;\n var count = cont.filter(':checked').length;\n\n if (count === 0) return;\n\n return count <= tmp.arg || messages.maxChecked.replace('{count}', tmp.arg);\n },\n minChecked: function(tmp, self) {\n var cont = $(self.form.querySelectorAll('input[type=checkbox][name=\"' + tmp.el.name + '\"]'));\n // same as above\n\n if (cont.index(tmp.el) !== 0) return;\n var count = cont.filter(':checked').length;\n\n return count >= tmp.arg || messages.minChecked.replace('{count}', tmp.arg);\n },\n // Selectbox check\n maxSelected: function(tmp) {\n if (tmp.val === null) return;\n\n return tmp.val.length <= tmp.arg || messages.maxSelected.replace('{count}', tmp.arg);\n },\n minSelected: function(tmp) {\n return (tmp.val !== null && tmp.val.length >= tmp.arg) || messages.minSelected.replace('{count}', tmp.arg);\n },\n // Radio\n radio: function(el) {\n var count = this.form.querySelectorAll('input[type=radio][name=\"' + el.name + '\"]:checked').length;\n\n return count === 1;\n },\n // Custom reg check\n regExp: function(tmp, self) {\n var _arg = self.options.validators.regExp[tmp.arg];\n var _reg = new RegExp(_arg.pattern);\n\n return _reg.test(tmp.val) || _arg.errorMessage;\n },\n // Remote\n remote: function(tmp) {\n tmp.remote = tmp.arg;\n\n return;\n },\n // Callback\n callback: function(tmp, self) {\n var _cb = self.options.validators.callback[tmp.arg];\n\n return _cb.callback(tmp.el, tmp.val) || _cb.errorMessage;\n }\n };\n\n /**\n * Plugin Class\n *\n * @constructor\n * @param {object} form :