scratch

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 133  →  ?path2? @ 134
/bower_components/bootstrap-tokenfield/dist/bootstrap-tokenfield.js
@@ -0,0 +1,1029 @@
/*!
* bootstrap-tokenfield
* https://github.com/sliptree/bootstrap-tokenfield
* Copyright 2013-2014 Sliptree and other contributors; Licensed MIT
*/
 
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// For CommonJS and CommonJS-like environments where a window with jQuery
// is present, execute the factory with the jQuery instance from the window object
// For environments that do not inherently posses a window with a document
// (such as Node.js), expose a Tokenfield-making factory as module.exports
// This accentuates the need for the creation of a real window or passing in a jQuery instance
// e.g. require("bootstrap-tokenfield")(window); or require("bootstrap-tokenfield")($);
module.exports = global.window && global.window.$ ?
factory( global.window.$ ) :
function( input ) {
if ( !input.$ && !input.fn ) {
throw new Error( "Tokenfield requires a window object with jQuery or a jQuery instance" );
}
return factory( input.$ || input );
};
} else {
// Browser globals
factory(jQuery, window);
}
}(function ($, window) {
 
"use strict"; // jshint ;_;
 
/* TOKENFIELD PUBLIC CLASS DEFINITION
* ============================== */
 
var Tokenfield = function (element, options) {
var _self = this
 
this.$element = $(element)
this.textDirection = this.$element.css('direction');
 
// Extend options
this.options = $.extend(true, {}, $.fn.tokenfield.defaults, { tokens: this.$element.val() }, this.$element.data(), options)
 
// Setup delimiters and trigger keys
this._delimiters = (typeof this.options.delimiter === 'string') ? [this.options.delimiter] : this.options.delimiter
this._triggerKeys = $.map(this._delimiters, function (delimiter) {
return delimiter.charCodeAt(0);
});
this._firstDelimiter = this._delimiters[0];
 
// Check for whitespace, dash and special characters
var whitespace = $.inArray(' ', this._delimiters)
, dash = $.inArray('-', this._delimiters)
 
if (whitespace >= 0)
this._delimiters[whitespace] = '\\s'
 
if (dash >= 0) {
delete this._delimiters[dash]
this._delimiters.unshift('-')
}
 
var specialCharacters = ['\\', '$', '[', '{', '^', '.', '|', '?', '*', '+', '(', ')']
$.each(this._delimiters, function (index, character) {
var pos = $.inArray(character, specialCharacters)
if (pos >= 0) _self._delimiters[index] = '\\' + character;
});
 
// Store original input width
var elRules = (window && typeof window.getMatchedCSSRules === 'function') ? window.getMatchedCSSRules( element ) : null
, elStyleWidth = element.style.width
, elCSSWidth
, elWidth = this.$element.width()
 
if (elRules) {
$.each( elRules, function (i, rule) {
if (rule.style.width) {
elCSSWidth = rule.style.width;
}
});
}
 
// Move original input out of the way
var hidingPosition = $('body').css('direction') === 'rtl' ? 'right' : 'left',
originalStyles = { position: this.$element.css('position') };
originalStyles[hidingPosition] = this.$element.css(hidingPosition);
 
this.$element
.data('original-styles', originalStyles)
.data('original-tabindex', this.$element.prop('tabindex'))
.css('position', 'absolute')
.css(hidingPosition, '-10000px')
.prop('tabindex', -1)
 
// Create a wrapper
this.$wrapper = $('<div class="tokenfield form-control" />')
if (this.$element.hasClass('input-lg')) this.$wrapper.addClass('input-lg')
if (this.$element.hasClass('input-sm')) this.$wrapper.addClass('input-sm')
if (this.textDirection === 'rtl') this.$wrapper.addClass('rtl')
 
// Create a new input
var id = this.$element.prop('id') || new Date().getTime() + '' + Math.floor((1 + Math.random()) * 100)
this.$input = $('<input type="'+this.options.inputType+'" class="token-input" autocomplete="off" />')
.appendTo( this.$wrapper )
.prop( 'placeholder', this.$element.prop('placeholder') )
.prop( 'id', id + '-tokenfield' )
.prop( 'tabindex', this.$element.data('original-tabindex') )
 
// Re-route original input label to new input
var $label = $( 'label[for="' + this.$element.prop('id') + '"]' )
if ( $label.length ) {
$label.prop( 'for', this.$input.prop('id') )
}
 
// Set up a copy helper to handle copy & paste
this.$copyHelper = $('<input type="text" />').css('position', 'absolute').css(hidingPosition, '-10000px').prop('tabindex', -1).prependTo( this.$wrapper )
 
// Set wrapper width
if (elStyleWidth) {
this.$wrapper.css('width', elStyleWidth);
}
else if (elCSSWidth) {
this.$wrapper.css('width', elCSSWidth);
}
// If input is inside inline-form with no width set, set fixed width
else if (this.$element.parents('.form-inline').length) {
this.$wrapper.width( elWidth )
}
 
// Set tokenfield disabled, if original or fieldset input is disabled
if (this.$element.prop('disabled') || this.$element.parents('fieldset[disabled]').length) {
this.disable();
}
 
// Set tokenfield readonly, if original input is readonly
if (this.$element.prop('readonly')) {
this.readonly();
}
 
// Set up mirror for input auto-sizing
this.$mirror = $('<span style="position:absolute; top:-999px; left:0; white-space:pre;"/>');
this.$input.css('min-width', this.options.minWidth + 'px')
$.each([
'fontFamily',
'fontSize',
'fontWeight',
'fontStyle',
'letterSpacing',
'textTransform',
'wordSpacing',
'textIndent'
], function (i, val) {
_self.$mirror[0].style[val] = _self.$input.css(val);
});
this.$mirror.appendTo( 'body' )
 
// Insert tokenfield to HTML
this.$wrapper.insertBefore( this.$element )
this.$element.prependTo( this.$wrapper )
 
// Calculate inner input width
this.update()
 
// Create initial tokens, if any
this.setTokens(this.options.tokens, false, ! this.$element.val() && this.options.tokens )
 
// Start listening to events
this.listen()
 
// Initialize autocomplete, if necessary
if ( ! $.isEmptyObject( this.options.autocomplete ) ) {
var side = this.textDirection === 'rtl' ? 'right' : 'left'
, autocompleteOptions = $.extend({
minLength: this.options.showAutocompleteOnFocus ? 0 : null,
position: { my: side + " top", at: side + " bottom", of: this.$wrapper }
}, this.options.autocomplete )
 
this.$input.autocomplete( autocompleteOptions )
}
 
// Initialize typeahead, if necessary
if ( ! $.isEmptyObject( this.options.typeahead ) ) {
 
var typeaheadOptions = this.options.typeahead
, defaults = {
minLength: this.options.showAutocompleteOnFocus ? 0 : null
}
, args = $.isArray( typeaheadOptions ) ? typeaheadOptions : [typeaheadOptions, typeaheadOptions]
 
args[0] = $.extend( {}, defaults, args[0] )
 
this.$input.typeahead.apply( this.$input, args )
this.typeahead = true
}
}
 
Tokenfield.prototype = {
 
constructor: Tokenfield
 
, createToken: function (attrs, triggerChange) {
var _self = this
 
if (typeof attrs === 'string') {
attrs = { value: attrs, label: attrs }
} else {
// Copy objects to prevent contamination of data sources.
attrs = $.extend( {}, attrs )
}
 
if (typeof triggerChange === 'undefined') {
triggerChange = true
}
 
// Normalize label and value
attrs.value = $.trim(attrs.value.toString());
attrs.label = attrs.label && attrs.label.length ? $.trim(attrs.label) : attrs.value
 
// Bail out if has no value or label, or label is too short
if (!attrs.value.length || !attrs.label.length || attrs.label.length <= this.options.minLength) return
 
// Bail out if maximum number of tokens is reached
if (this.options.limit && this.getTokens().length >= this.options.limit) return
 
// Allow changing token data before creating it
var createEvent = $.Event('tokenfield:createtoken', { attrs: attrs })
this.$element.trigger(createEvent)
 
// Bail out if there if attributes are empty or event was defaultPrevented
if (!createEvent.attrs || createEvent.isDefaultPrevented()) return
 
var $token = $('<div class="token" />')
.append('<span class="token-label" />')
.append('<a href="#" class="close" tabindex="-1">&times;</a>')
.data('attrs', attrs)
 
// Insert token into HTML
if (this.$input.hasClass('tt-input')) {
// If the input has typeahead enabled, insert token before it's parent
this.$input.parent().before( $token )
} else {
this.$input.before( $token )
}
 
// Temporarily set input width to minimum
this.$input.css('width', this.options.minWidth + 'px')
 
var $tokenLabel = $token.find('.token-label')
, $closeButton = $token.find('.close')
 
// Determine maximum possible token label width
if (!this.maxTokenWidth) {
this.maxTokenWidth =
this.$wrapper.width() - $closeButton.outerWidth() -
parseInt($closeButton.css('margin-left'), 10) -
parseInt($closeButton.css('margin-right'), 10) -
parseInt($token.css('border-left-width'), 10) -
parseInt($token.css('border-right-width'), 10) -
parseInt($token.css('padding-left'), 10) -
parseInt($token.css('padding-right'), 10)
parseInt($tokenLabel.css('border-left-width'), 10) -
parseInt($tokenLabel.css('border-right-width'), 10) -
parseInt($tokenLabel.css('padding-left'), 10) -
parseInt($tokenLabel.css('padding-right'), 10)
parseInt($tokenLabel.css('margin-left'), 10) -
parseInt($tokenLabel.css('margin-right'), 10)
}
 
$tokenLabel
.text(attrs.label)
.css('max-width', this.maxTokenWidth)
 
// Listen to events on token
$token
.on('mousedown', function (e) {
if (_self._disabled || _self._readonly) return false
_self.preventDeactivation = true
})
.on('click', function (e) {
if (_self._disabled || _self._readonly) return false
_self.preventDeactivation = false
 
if (e.ctrlKey || e.metaKey) {
e.preventDefault()
return _self.toggle( $token )
}
 
_self.activate( $token, e.shiftKey, e.shiftKey )
})
.on('dblclick', function (e) {
if (_self._disabled || _self._readonly || !_self.options.allowEditing ) return false
_self.edit( $token )
})
 
$closeButton
.on('click', $.proxy(this.remove, this))
 
// Trigger createdtoken event on the original field
// indicating that the token is now in the DOM
this.$element.trigger($.Event('tokenfield:createdtoken', {
attrs: attrs,
relatedTarget: $token.get(0)
}))
 
// Trigger change event on the original field
if (triggerChange) {
this.$element.val( this.getTokensList() ).trigger( $.Event('change', { initiator: 'tokenfield' }) )
}
 
// Update tokenfield dimensions
this.update()
 
// Return original element
return this.$element.get(0)
}
 
, setTokens: function (tokens, add, triggerChange) {
if (!tokens) return
 
if (!add) this.$wrapper.find('.token').remove()
 
if (typeof triggerChange === 'undefined') {
triggerChange = true
}
 
if (typeof tokens === 'string') {
if (this._delimiters.length) {
// Split based on delimiters
tokens = tokens.split( new RegExp( '[' + this._delimiters.join('') + ']' ) )
} else {
tokens = [tokens];
}
}
 
var _self = this
$.each(tokens, function (i, attrs) {
_self.createToken(attrs, triggerChange)
})
 
return this.$element.get(0)
}
 
, getTokenData: function($token) {
var data = $token.map(function() {
var $token = $(this);
return $token.data('attrs')
}).get();
 
if (data.length == 1) {
data = data[0];
}
 
return data;
}
 
, getTokens: function(active) {
var self = this
, tokens = []
, activeClass = active ? '.active' : '' // get active tokens only
this.$wrapper.find( '.token' + activeClass ).each( function() {
tokens.push( self.getTokenData( $(this) ) )
})
return tokens
}
 
, getTokensList: function(delimiter, beautify, active) {
delimiter = delimiter || this._firstDelimiter
beautify = ( typeof beautify !== 'undefined' && beautify !== null ) ? beautify : this.options.beautify
 
var separator = delimiter + ( beautify && delimiter !== ' ' ? ' ' : '')
return $.map( this.getTokens(active), function (token) {
return token.value
}).join(separator)
}
 
, getInput: function() {
return this.$input.val()
}
 
, listen: function () {
var _self = this
 
this.$element
.on('change', $.proxy(this.change, this))
 
this.$wrapper
.on('mousedown',$.proxy(this.focusInput, this))
 
this.$input
.on('focus', $.proxy(this.focus, this))
.on('blur', $.proxy(this.blur, this))
.on('paste', $.proxy(this.paste, this))
.on('keydown', $.proxy(this.keydown, this))
.on('keypress', $.proxy(this.keypress, this))
.on('keyup', $.proxy(this.keyup, this))
 
this.$copyHelper
.on('focus', $.proxy(this.focus, this))
.on('blur', $.proxy(this.blur, this))
.on('keydown', $.proxy(this.keydown, this))
.on('keyup', $.proxy(this.keyup, this))
 
// Secondary listeners for input width calculation
this.$input
.on('keypress', $.proxy(this.update, this))
.on('keyup', $.proxy(this.update, this))
 
this.$input
.on('autocompletecreate', function() {
// Set minimum autocomplete menu width
var $_menuElement = $(this).data('ui-autocomplete').menu.element
 
var minWidth = _self.$wrapper.outerWidth() -
parseInt( $_menuElement.css('border-left-width'), 10 ) -
parseInt( $_menuElement.css('border-right-width'), 10 )
 
$_menuElement.css( 'min-width', minWidth + 'px' )
})
.on('autocompleteselect', function (e, ui) {
if (_self.createToken( ui.item )) {
_self.$input.val('')
if (_self.$input.data( 'edit' )) {
_self.unedit(true)
}
}
return false
})
.on('typeahead:selected typeahead:autocompleted', function (e, datum, dataset) {
// Create token
if (_self.createToken( datum )) {
_self.$input.typeahead('val', '')
if (_self.$input.data( 'edit' )) {
_self.unedit(true)
}
}
})
 
// Listen to window resize
$(window).on('resize', $.proxy(this.update, this ))
 
}
 
, keydown: function (e) {
 
if (!this.focused) return
 
var _self = this
 
switch(e.keyCode) {
case 8: // backspace
if (!this.$input.is(document.activeElement)) break
this.lastInputValue = this.$input.val()
break
 
case 37: // left arrow
leftRight( this.textDirection === 'rtl' ? 'next': 'prev' )
break
 
case 38: // up arrow
upDown('prev')
break
 
case 39: // right arrow
leftRight( this.textDirection === 'rtl' ? 'prev': 'next' )
break
 
case 40: // down arrow
upDown('next')
break
 
case 65: // a (to handle ctrl + a)
if (this.$input.val().length > 0 || !(e.ctrlKey || e.metaKey)) break
this.activateAll()
e.preventDefault()
break
 
case 9: // tab
case 13: // enter
 
// We will handle creating tokens from autocomplete in autocomplete events
if (this.$input.data('ui-autocomplete') && this.$input.data('ui-autocomplete').menu.element.find("li:has(a.ui-state-focus), li.ui-state-focus").length) break
 
// We will handle creating tokens from typeahead in typeahead events
if (this.$input.hasClass('tt-input') && this.$wrapper.find('.tt-cursor').length ) break
if (this.$input.hasClass('tt-input') && this.$wrapper.find('.tt-hint').val() && this.$wrapper.find('.tt-hint').val().length) break
 
// Create token
if (this.$input.is(document.activeElement) && this.$input.val().length || this.$input.data('edit')) {
return this.createTokensFromInput(e, this.$input.data('edit'));
}
 
// Edit token
if (e.keyCode === 13) {
if (!this.$copyHelper.is(document.activeElement) || this.$wrapper.find('.token.active').length !== 1) break
if (!_self.options.allowEditing) break
this.edit( this.$wrapper.find('.token.active') )
}
}
 
function leftRight(direction) {
if (_self.$input.is(document.activeElement)) {
if (_self.$input.val().length > 0) return
 
direction += 'All'
var $token = _self.$input.hasClass('tt-input') ? _self.$input.parent()[direction]('.token:first') : _self.$input[direction]('.token:first')
if (!$token.length) return
 
_self.preventInputFocus = true
_self.preventDeactivation = true
 
_self.activate( $token )
e.preventDefault()
 
} else {
_self[direction]( e.shiftKey )
e.preventDefault()
}
}
 
function upDown(direction) {
if (!e.shiftKey) return
 
if (_self.$input.is(document.activeElement)) {
if (_self.$input.val().length > 0) return
 
var $token = _self.$input.hasClass('tt-input') ? _self.$input.parent()[direction + 'All']('.token:first') : _self.$input[direction + 'All']('.token:first')
if (!$token.length) return
 
_self.activate( $token )
}
 
var opposite = direction === 'prev' ? 'next' : 'prev'
, position = direction === 'prev' ? 'first' : 'last'
 
_self.$firstActiveToken[opposite + 'All']('.token').each(function() {
_self.deactivate( $(this) )
})
 
_self.activate( _self.$wrapper.find('.token:' + position), true, true )
e.preventDefault()
}
 
this.lastKeyDown = e.keyCode
}
 
, keypress: function(e) {
 
// Comma
if ($.inArray( e.which, this._triggerKeys) !== -1 && this.$input.is(document.activeElement)) {
if (this.$input.val()) {
this.createTokensFromInput(e)
}
return false;
}
}
 
, keyup: function (e) {
this.preventInputFocus = false
 
if (!this.focused) return
 
switch(e.keyCode) {
case 8: // backspace
if (this.$input.is(document.activeElement)) {
if (this.$input.val().length || this.lastInputValue.length && this.lastKeyDown === 8) break
 
this.preventDeactivation = true
var $prevToken = this.$input.hasClass('tt-input') ? this.$input.parent().prevAll('.token:first') : this.$input.prevAll('.token:first')
 
if (!$prevToken.length) break
 
this.activate( $prevToken )
} else {
this.remove(e)
}
break
 
case 46: // delete
this.remove(e, 'next')
break
}
this.lastKeyUp = e.keyCode
}
 
, focus: function (e) {
this.focused = true
this.$wrapper.addClass('focus')
 
if (this.$input.is(document.activeElement)) {
this.$wrapper.find('.active').removeClass('active')
this.$firstActiveToken = null
 
if (this.options.showAutocompleteOnFocus) {
this.search()
}
}
}
 
, blur: function (e) {
 
this.focused = false
this.$wrapper.removeClass('focus')
 
if (!this.preventDeactivation && !this.$element.is(document.activeElement)) {
this.$wrapper.find('.active').removeClass('active')
this.$firstActiveToken = null
}
 
if (!this.preventCreateTokens && (this.$input.data('edit') && !this.$input.is(document.activeElement) || this.options.createTokensOnBlur )) {
this.createTokensFromInput(e)
}
 
this.preventDeactivation = false
this.preventCreateTokens = false
}
 
, paste: function (e) {
var _self = this
 
// Add tokens to existing ones
if (_self.options.allowPasting) {
setTimeout(function () {
_self.createTokensFromInput(e)
}, 1)
}
}
 
, change: function (e) {
if ( e.initiator === 'tokenfield' ) return // Prevent loops
 
this.setTokens( this.$element.val() )
}
 
, createTokensFromInput: function (e, focus) {
if (this.$input.val().length < this.options.minLength)
return // No input, simply return
 
var tokensBefore = this.getTokensList()
this.setTokens( this.$input.val(), true )
 
if (tokensBefore == this.getTokensList() && this.$input.val().length)
return false // No tokens were added, do nothing (prevent form submit)
 
if (this.$input.hasClass('tt-input')) {
// Typeahead acts weird when simply setting input value to empty,
// so we set the query to empty instead
this.$input.typeahead('val', '')
} else {
this.$input.val('')
}
 
if (this.$input.data( 'edit' )) {
this.unedit(focus)
}
 
return false // Prevent form being submitted
}
 
, next: function (add) {
if (add) {
var $firstActiveToken = this.$wrapper.find('.active:first')
, deactivate = $firstActiveToken && this.$firstActiveToken ? $firstActiveToken.index() < this.$firstActiveToken.index() : false
 
if (deactivate) return this.deactivate( $firstActiveToken )
}
 
var $lastActiveToken = this.$wrapper.find('.active:last')
, $nextToken = $lastActiveToken.nextAll('.token:first')
 
if (!$nextToken.length) {
this.$input.focus()
return
}
 
this.activate($nextToken, add)
}
 
, prev: function (add) {
 
if (add) {
var $lastActiveToken = this.$wrapper.find('.active:last')
, deactivate = $lastActiveToken && this.$firstActiveToken ? $lastActiveToken.index() > this.$firstActiveToken.index() : false
 
if (deactivate) return this.deactivate( $lastActiveToken )
}
 
var $firstActiveToken = this.$wrapper.find('.active:first')
, $prevToken = $firstActiveToken.prevAll('.token:first')
 
if (!$prevToken.length) {
$prevToken = this.$wrapper.find('.token:first')
}
 
if (!$prevToken.length && !add) {
this.$input.focus()
return
}
 
this.activate( $prevToken, add )
}
 
, activate: function ($token, add, multi, remember) {
 
if (!$token) return
 
if (typeof remember === 'undefined') var remember = true
 
if (multi) var add = true
 
this.$copyHelper.focus()
 
if (!add) {
this.$wrapper.find('.active').removeClass('active')
if (remember) {
this.$firstActiveToken = $token
} else {
delete this.$firstActiveToken
}
}
 
if (multi && this.$firstActiveToken) {
// Determine first active token and the current tokens indicies
// Account for the 1 hidden textarea by subtracting 1 from both
var i = this.$firstActiveToken.index() - 2
, a = $token.index() - 2
, _self = this
 
this.$wrapper.find('.token').slice( Math.min(i, a) + 1, Math.max(i, a) ).each( function() {
_self.activate( $(this), true )
})
}
 
$token.addClass('active')
this.$copyHelper.val( this.getTokensList( null, null, true ) ).select()
}
 
, activateAll: function() {
var _self = this
 
this.$wrapper.find('.token').each( function (i) {
_self.activate($(this), i !== 0, false, false)
})
}
 
, deactivate: function($token) {
if (!$token) return
 
$token.removeClass('active')
this.$copyHelper.val( this.getTokensList( null, null, true ) ).select()
}
 
, toggle: function($token) {
if (!$token) return
 
$token.toggleClass('active')
this.$copyHelper.val( this.getTokensList( null, null, true ) ).select()
}
 
, edit: function ($token) {
if (!$token) return
 
var attrs = $token.data('attrs')
 
// Allow changing input value before editing
var options = { attrs: attrs, relatedTarget: $token.get(0) }
var editEvent = $.Event('tokenfield:edittoken', options)
this.$element.trigger( editEvent )
 
// Edit event can be cancelled if default is prevented
if (editEvent.isDefaultPrevented()) return
 
$token.find('.token-label').text(attrs.value)
var tokenWidth = $token.outerWidth()
 
var $_input = this.$input.hasClass('tt-input') ? this.$input.parent() : this.$input
 
$token.replaceWith( $_input )
 
this.preventCreateTokens = true
 
this.$input.val( attrs.value )
.select()
.data( 'edit', true )
.width( tokenWidth )
 
this.update();
 
// Indicate that token is now being edited, and is replaced with an input field in the DOM
this.$element.trigger($.Event('tokenfield:editedtoken', options ))
}
 
, unedit: function (focus) {
var $_input = this.$input.hasClass('tt-input') ? this.$input.parent() : this.$input
$_input.appendTo( this.$wrapper )
 
this.$input.data('edit', false)
this.$mirror.text('')
 
this.update()
 
// Because moving the input element around in DOM
// will cause it to lose focus, we provide an option
// to re-focus the input after appending it to the wrapper
if (focus) {
var _self = this
setTimeout(function () {
_self.$input.focus()
}, 1)
}
}
 
, remove: function (e, direction) {
if (this.$input.is(document.activeElement) || this._disabled || this._readonly) return
 
var $token = (e.type === 'click') ? $(e.target).closest('.token') : this.$wrapper.find('.token.active')
 
if (e.type !== 'click') {
if (!direction) var direction = 'prev'
this[direction]()
 
// Was it the first token?
if (direction === 'prev') var firstToken = $token.first().prevAll('.token:first').length === 0
}
 
// Prepare events and their options
var options = { attrs: this.getTokenData( $token ), relatedTarget: $token.get(0) }
, removeEvent = $.Event('tokenfield:removetoken', options)
 
this.$element.trigger(removeEvent);
 
// Remove event can be intercepted and cancelled
if (removeEvent.isDefaultPrevented()) return
 
var removedEvent = $.Event('tokenfield:removedtoken', options)
, changeEvent = $.Event('change', { initiator: 'tokenfield' })
 
// Remove token from DOM
$token.remove()
 
// Trigger events
this.$element.val( this.getTokensList() ).trigger( removedEvent ).trigger( changeEvent )
 
// Focus, when necessary:
// When there are no more tokens, or if this was the first token
// and it was removed with backspace or it was clicked on
if (!this.$wrapper.find('.token').length || e.type === 'click' || firstToken) this.$input.focus()
 
// Adjust input width
this.$input.css('width', this.options.minWidth + 'px')
this.update()
 
// Cancel original event handlers
e.preventDefault()
e.stopPropagation()
}
 
/**
* Update tokenfield dimensions
*/
, update: function (e) {
var value = this.$input.val()
, inputPaddingLeft = parseInt(this.$input.css('padding-left'), 10)
, inputPaddingRight = parseInt(this.$input.css('padding-right'), 10)
, inputPadding = inputPaddingLeft + inputPaddingRight
 
if (this.$input.data('edit')) {
 
if (!value) {
value = this.$input.prop("placeholder")
}
if (value === this.$mirror.text()) return
 
this.$mirror.text(value)
 
var mirrorWidth = this.$mirror.width() + 10;
if ( mirrorWidth > this.$wrapper.width() ) {
return this.$input.width( this.$wrapper.width() )
}
 
this.$input.width( mirrorWidth )
}
else {
var w = (this.textDirection === 'rtl')
? this.$input.offset().left + this.$input.outerWidth() - this.$wrapper.offset().left - parseInt(this.$wrapper.css('padding-left'), 10) - inputPadding - 1
: this.$wrapper.offset().left + this.$wrapper.width() + parseInt(this.$wrapper.css('padding-left'), 10) - this.$input.offset().left - inputPadding;
//
// some usecases pre-render widget before attaching to DOM,
// dimensions returned by jquery will be NaN -> we default to 100%
// so placeholder won't be cut off.
isNaN(w) ? this.$input.width('100%') : this.$input.width(w);
}
}
 
, focusInput: function (e) {
if ( $(e.target).closest('.token').length || $(e.target).closest('.token-input').length || $(e.target).closest('.tt-dropdown-menu').length ) return
// Focus only after the current call stack has cleared,
// otherwise has no effect.
// Reason: mousedown is too early - input will lose focus
// after mousedown. However, since the input may be moved
// in DOM, there may be no click or mouseup event triggered.
var _self = this
setTimeout(function() {
_self.$input.focus()
}, 0)
}
 
, search: function () {
if ( this.$input.data('ui-autocomplete') ) {
this.$input.autocomplete('search')
}
}
 
, disable: function () {
this.setProperty('disabled', true);
}
 
, enable: function () {
this.setProperty('disabled', false);
}
 
, readonly: function () {
this.setProperty('readonly', true);
}
 
, writeable: function () {
this.setProperty('readonly', false);
}
 
, setProperty: function(property, value) {
this['_' + property] = value;
this.$input.prop(property, value);
this.$element.prop(property, value);
this.$wrapper[ value ? 'addClass' : 'removeClass' ](property);
}
 
, destroy: function() {
// Set field value
this.$element.val( this.getTokensList() );
// Restore styles and properties
this.$element.css( this.$element.data('original-styles') );
this.$element.prop( 'tabindex', this.$element.data('original-tabindex') );
 
// Re-route tokenfield label to original input
var $label = $( 'label[for="' + this.$input.prop('id') + '"]' )
if ( $label.length ) {
$label.prop( 'for', this.$element.prop('id') )
}
 
// Move original element outside of tokenfield wrapper
this.$element.insertBefore( this.$wrapper );
 
// Remove tokenfield-related data
this.$element.removeData('original-styles')
.removeData('original-tabindex')
.removeData('bs.tokenfield');
 
// Remove tokenfield from DOM
this.$wrapper.remove();
this.$mirror.remove();
 
var $_element = this.$element;
 
return $_element;
}
 
}
 
 
/* TOKENFIELD PLUGIN DEFINITION
* ======================== */
 
var old = $.fn.tokenfield
 
$.fn.tokenfield = function (option, param) {
var value
, args = []
 
Array.prototype.push.apply( args, arguments );
 
var elements = this.each(function () {
var $this = $(this)
, data = $this.data('bs.tokenfield')
, options = typeof option == 'object' && option
 
if (typeof option === 'string' && data && data[option]) {
args.shift()
value = data[option].apply(data, args)
} else {
if (!data && typeof option !== 'string' && !param) {
$this.data('bs.tokenfield', (data = new Tokenfield(this, options)))
$this.trigger('tokenfield:initialize')
}
}
})
 
return typeof value !== 'undefined' ? value : elements;
}
 
$.fn.tokenfield.defaults = {
minWidth: 60,
minLength: 0,
allowEditing: true,
allowPasting: true,
limit: 0,
autocomplete: {},
typeahead: {},
showAutocompleteOnFocus: false,
createTokensOnBlur: false,
delimiter: ',',
beautify: true,
inputType: 'text'
}
 
$.fn.tokenfield.Constructor = Tokenfield
 
 
/* TOKENFIELD NO CONFLICT
* ================== */
 
$.fn.tokenfield.noConflict = function () {
$.fn.tokenfield = old
return this
}
 
return Tokenfield;
 
}));
/bower_components/bootstrap-tokenfield/dist/bootstrap-tokenfield.min.js
@@ -0,0 +1,7 @@
/*!
* bootstrap-tokenfield 0.12.1
* https://github.com/sliptree/bootstrap-tokenfield
* Copyright 2013-2014 Sliptree and other contributors; Licensed MIT
*/
 
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=global.window&&global.window.$?a(global.window.$):function(b){if(!b.$&&!b.fn)throw new Error("Tokenfield requires a window object with jQuery or a jQuery instance");return a(b.$||b)}:a(jQuery,window)}(function(a,b){"use strict";var c=function(c,d){var e=this;this.$element=a(c),this.textDirection=this.$element.css("direction"),this.options=a.extend(!0,{},a.fn.tokenfield.defaults,{tokens:this.$element.val()},this.$element.data(),d),this._delimiters="string"==typeof this.options.delimiter?[this.options.delimiter]:this.options.delimiter,this._triggerKeys=a.map(this._delimiters,function(a){return a.charCodeAt(0)}),this._firstDelimiter=this._delimiters[0];var f=a.inArray(" ",this._delimiters),g=a.inArray("-",this._delimiters);f>=0&&(this._delimiters[f]="\\s"),g>=0&&(delete this._delimiters[g],this._delimiters.unshift("-"));var h=["\\","$","[","{","^",".","|","?","*","+","(",")"];a.each(this._delimiters,function(b,c){var d=a.inArray(c,h);d>=0&&(e._delimiters[b]="\\"+c)});var i,j=b&&"function"==typeof b.getMatchedCSSRules?b.getMatchedCSSRules(c):null,k=c.style.width,l=this.$element.width();j&&a.each(j,function(a,b){b.style.width&&(i=b.style.width)});var m="rtl"===a("body").css("direction")?"right":"left",n={position:this.$element.css("position")};n[m]=this.$element.css(m),this.$element.data("original-styles",n).data("original-tabindex",this.$element.prop("tabindex")).css("position","absolute").css(m,"-10000px").prop("tabindex",-1),this.$wrapper=a('<div class="tokenfield form-control" />'),this.$element.hasClass("input-lg")&&this.$wrapper.addClass("input-lg"),this.$element.hasClass("input-sm")&&this.$wrapper.addClass("input-sm"),"rtl"===this.textDirection&&this.$wrapper.addClass("rtl");var o=this.$element.prop("id")||(new Date).getTime()+""+Math.floor(100*(1+Math.random()));this.$input=a('<input type="'+this.options.inputType+'" class="token-input" autocomplete="off" />').appendTo(this.$wrapper).prop("placeholder",this.$element.prop("placeholder")).prop("id",o+"-tokenfield").prop("tabindex",this.$element.data("original-tabindex"));var p=a('label[for="'+this.$element.prop("id")+'"]');if(p.length&&p.prop("for",this.$input.prop("id")),this.$copyHelper=a('<input type="text" />').css("position","absolute").css(m,"-10000px").prop("tabindex",-1).prependTo(this.$wrapper),k?this.$wrapper.css("width",k):i?this.$wrapper.css("width",i):this.$element.parents(".form-inline").length&&this.$wrapper.width(l),(this.$element.prop("disabled")||this.$element.parents("fieldset[disabled]").length)&&this.disable(),this.$element.prop("readonly")&&this.readonly(),this.$mirror=a('<span style="position:absolute; top:-999px; left:0; white-space:pre;"/>'),this.$input.css("min-width",this.options.minWidth+"px"),a.each(["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing","textIndent"],function(a,b){e.$mirror[0].style[b]=e.$input.css(b)}),this.$mirror.appendTo("body"),this.$wrapper.insertBefore(this.$element),this.$element.prependTo(this.$wrapper),this.update(),this.setTokens(this.options.tokens,!1,!this.$element.val()&&this.options.tokens),this.listen(),!a.isEmptyObject(this.options.autocomplete)){var q="rtl"===this.textDirection?"right":"left",r=a.extend({minLength:this.options.showAutocompleteOnFocus?0:null,position:{my:q+" top",at:q+" bottom",of:this.$wrapper}},this.options.autocomplete);this.$input.autocomplete(r)}if(!a.isEmptyObject(this.options.typeahead)){var s=this.options.typeahead,t={minLength:this.options.showAutocompleteOnFocus?0:null},u=a.isArray(s)?s:[s,s];u[0]=a.extend({},t,u[0]),this.$input.typeahead.apply(this.$input,u),this.typeahead=!0}};c.prototype={constructor:c,createToken:function(b,c){var d=this;if(b="string"==typeof b?{value:b,label:b}:a.extend({},b),"undefined"==typeof c&&(c=!0),b.value=a.trim(b.value.toString()),b.label=b.label&&b.label.length?a.trim(b.label):b.value,!(!b.value.length||!b.label.length||b.label.length<=this.options.minLength||this.options.limit&&this.getTokens().length>=this.options.limit)){var e=a.Event("tokenfield:createtoken",{attrs:b});if(this.$element.trigger(e),e.attrs&&!e.isDefaultPrevented()){var f=a('<div class="token" />').append('<span class="token-label" />').append('<a href="#" class="close" tabindex="-1">&times;</a>').data("attrs",b);this.$input.hasClass("tt-input")?this.$input.parent().before(f):this.$input.before(f),this.$input.css("width",this.options.minWidth+"px");var g=f.find(".token-label"),h=f.find(".close");return this.maxTokenWidth||(this.maxTokenWidth=this.$wrapper.width()-h.outerWidth()-parseInt(h.css("margin-left"),10)-parseInt(h.css("margin-right"),10)-parseInt(f.css("border-left-width"),10)-parseInt(f.css("border-right-width"),10)-parseInt(f.css("padding-left"),10)-parseInt(f.css("padding-right"),10),parseInt(g.css("border-left-width"),10)-parseInt(g.css("border-right-width"),10)-parseInt(g.css("padding-left"),10)-parseInt(g.css("padding-right"),10),parseInt(g.css("margin-left"),10)-parseInt(g.css("margin-right"),10)),g.text(b.label).css("max-width",this.maxTokenWidth),f.on("mousedown",function(){return d._disabled||d._readonly?!1:(d.preventDeactivation=!0,void 0)}).on("click",function(a){return d._disabled||d._readonly?!1:(d.preventDeactivation=!1,a.ctrlKey||a.metaKey?(a.preventDefault(),d.toggle(f)):(d.activate(f,a.shiftKey,a.shiftKey),void 0))}).on("dblclick",function(){return d._disabled||d._readonly||!d.options.allowEditing?!1:(d.edit(f),void 0)}),h.on("click",a.proxy(this.remove,this)),this.$element.trigger(a.Event("tokenfield:createdtoken",{attrs:b,relatedTarget:f.get(0)})),c&&this.$element.val(this.getTokensList()).trigger(a.Event("change",{initiator:"tokenfield"})),this.update(),this.$element.get(0)}}},setTokens:function(b,c,d){if(b){c||this.$wrapper.find(".token").remove(),"undefined"==typeof d&&(d=!0),"string"==typeof b&&(b=this._delimiters.length?b.split(new RegExp("["+this._delimiters.join("")+"]")):[b]);var e=this;return a.each(b,function(a,b){e.createToken(b,d)}),this.$element.get(0)}},getTokenData:function(b){var c=b.map(function(){var b=a(this);return b.data("attrs")}).get();return 1==c.length&&(c=c[0]),c},getTokens:function(b){var c=this,d=[],e=b?".active":"";return this.$wrapper.find(".token"+e).each(function(){d.push(c.getTokenData(a(this)))}),d},getTokensList:function(b,c,d){b=b||this._firstDelimiter,c="undefined"!=typeof c&&null!==c?c:this.options.beautify;var e=b+(c&&" "!==b?" ":"");return a.map(this.getTokens(d),function(a){return a.value}).join(e)},getInput:function(){return this.$input.val()},listen:function(){var c=this;this.$element.on("change",a.proxy(this.change,this)),this.$wrapper.on("mousedown",a.proxy(this.focusInput,this)),this.$input.on("focus",a.proxy(this.focus,this)).on("blur",a.proxy(this.blur,this)).on("paste",a.proxy(this.paste,this)).on("keydown",a.proxy(this.keydown,this)).on("keypress",a.proxy(this.keypress,this)).on("keyup",a.proxy(this.keyup,this)),this.$copyHelper.on("focus",a.proxy(this.focus,this)).on("blur",a.proxy(this.blur,this)).on("keydown",a.proxy(this.keydown,this)).on("keyup",a.proxy(this.keyup,this)),this.$input.on("keypress",a.proxy(this.update,this)).on("keyup",a.proxy(this.update,this)),this.$input.on("autocompletecreate",function(){var b=a(this).data("ui-autocomplete").menu.element,d=c.$wrapper.outerWidth()-parseInt(b.css("border-left-width"),10)-parseInt(b.css("border-right-width"),10);b.css("min-width",d+"px")}).on("autocompleteselect",function(a,b){return c.createToken(b.item)&&(c.$input.val(""),c.$input.data("edit")&&c.unedit(!0)),!1}).on("typeahead:selected typeahead:autocompleted",function(a,b){c.createToken(b)&&(c.$input.typeahead("val",""),c.$input.data("edit")&&c.unedit(!0))}),a(b).on("resize",a.proxy(this.update,this))},keydown:function(b){function c(a){if(e.$input.is(document.activeElement)){if(e.$input.val().length>0)return;a+="All";var c=e.$input.hasClass("tt-input")?e.$input.parent()[a](".token:first"):e.$input[a](".token:first");if(!c.length)return;e.preventInputFocus=!0,e.preventDeactivation=!0,e.activate(c),b.preventDefault()}else e[a](b.shiftKey),b.preventDefault()}function d(c){if(b.shiftKey){if(e.$input.is(document.activeElement)){if(e.$input.val().length>0)return;var d=e.$input.hasClass("tt-input")?e.$input.parent()[c+"All"](".token:first"):e.$input[c+"All"](".token:first");if(!d.length)return;e.activate(d)}var f="prev"===c?"next":"prev",g="prev"===c?"first":"last";e.$firstActiveToken[f+"All"](".token").each(function(){e.deactivate(a(this))}),e.activate(e.$wrapper.find(".token:"+g),!0,!0),b.preventDefault()}}if(this.focused){var e=this;switch(b.keyCode){case 8:if(!this.$input.is(document.activeElement))break;this.lastInputValue=this.$input.val();break;case 37:c("rtl"===this.textDirection?"next":"prev");break;case 38:d("prev");break;case 39:c("rtl"===this.textDirection?"prev":"next");break;case 40:d("next");break;case 65:if(this.$input.val().length>0||!b.ctrlKey&&!b.metaKey)break;this.activateAll(),b.preventDefault();break;case 9:case 13:if(this.$input.data("ui-autocomplete")&&this.$input.data("ui-autocomplete").menu.element.find("li:has(a.ui-state-focus), li.ui-state-focus").length)break;if(this.$input.hasClass("tt-input")&&this.$wrapper.find(".tt-cursor").length)break;if(this.$input.hasClass("tt-input")&&this.$wrapper.find(".tt-hint").val()&&this.$wrapper.find(".tt-hint").val().length)break;if(this.$input.is(document.activeElement)&&this.$input.val().length||this.$input.data("edit"))return this.createTokensFromInput(b,this.$input.data("edit"));if(13===b.keyCode){if(!this.$copyHelper.is(document.activeElement)||1!==this.$wrapper.find(".token.active").length)break;if(!e.options.allowEditing)break;this.edit(this.$wrapper.find(".token.active"))}}this.lastKeyDown=b.keyCode}},keypress:function(b){return-1!==a.inArray(b.which,this._triggerKeys)&&this.$input.is(document.activeElement)?(this.$input.val()&&this.createTokensFromInput(b),!1):void 0},keyup:function(a){if(this.preventInputFocus=!1,this.focused){switch(a.keyCode){case 8:if(this.$input.is(document.activeElement)){if(this.$input.val().length||this.lastInputValue.length&&8===this.lastKeyDown)break;this.preventDeactivation=!0;var b=this.$input.hasClass("tt-input")?this.$input.parent().prevAll(".token:first"):this.$input.prevAll(".token:first");if(!b.length)break;this.activate(b)}else this.remove(a);break;case 46:this.remove(a,"next")}this.lastKeyUp=a.keyCode}},focus:function(){this.focused=!0,this.$wrapper.addClass("focus"),this.$input.is(document.activeElement)&&(this.$wrapper.find(".active").removeClass("active"),this.$firstActiveToken=null,this.options.showAutocompleteOnFocus&&this.search())},blur:function(a){this.focused=!1,this.$wrapper.removeClass("focus"),this.preventDeactivation||this.$element.is(document.activeElement)||(this.$wrapper.find(".active").removeClass("active"),this.$firstActiveToken=null),!this.preventCreateTokens&&(this.$input.data("edit")&&!this.$input.is(document.activeElement)||this.options.createTokensOnBlur)&&this.createTokensFromInput(a),this.preventDeactivation=!1,this.preventCreateTokens=!1},paste:function(a){var b=this;b.options.allowPasting&&setTimeout(function(){b.createTokensFromInput(a)},1)},change:function(a){"tokenfield"!==a.initiator&&this.setTokens(this.$element.val())},createTokensFromInput:function(a,b){if(!(this.$input.val().length<this.options.minLength)){var c=this.getTokensList();return this.setTokens(this.$input.val(),!0),c==this.getTokensList()&&this.$input.val().length?!1:(this.$input.hasClass("tt-input")?this.$input.typeahead("val",""):this.$input.val(""),this.$input.data("edit")&&this.unedit(b),!1)}},next:function(a){if(a){var b=this.$wrapper.find(".active:first"),c=b&&this.$firstActiveToken?b.index()<this.$firstActiveToken.index():!1;if(c)return this.deactivate(b)}var d=this.$wrapper.find(".active:last"),e=d.nextAll(".token:first");return e.length?(this.activate(e,a),void 0):(this.$input.focus(),void 0)},prev:function(a){if(a){var b=this.$wrapper.find(".active:last"),c=b&&this.$firstActiveToken?b.index()>this.$firstActiveToken.index():!1;if(c)return this.deactivate(b)}var d=this.$wrapper.find(".active:first"),e=d.prevAll(".token:first");return e.length||(e=this.$wrapper.find(".token:first")),e.length||a?(this.activate(e,a),void 0):(this.$input.focus(),void 0)},activate:function(b,c,d,e){if(b){if("undefined"==typeof e)var e=!0;if(d)var c=!0;if(this.$copyHelper.focus(),c||(this.$wrapper.find(".active").removeClass("active"),e?this.$firstActiveToken=b:delete this.$firstActiveToken),d&&this.$firstActiveToken){var f=this.$firstActiveToken.index()-2,g=b.index()-2,h=this;this.$wrapper.find(".token").slice(Math.min(f,g)+1,Math.max(f,g)).each(function(){h.activate(a(this),!0)})}b.addClass("active"),this.$copyHelper.val(this.getTokensList(null,null,!0)).select()}},activateAll:function(){var b=this;this.$wrapper.find(".token").each(function(c){b.activate(a(this),0!==c,!1,!1)})},deactivate:function(a){a&&(a.removeClass("active"),this.$copyHelper.val(this.getTokensList(null,null,!0)).select())},toggle:function(a){a&&(a.toggleClass("active"),this.$copyHelper.val(this.getTokensList(null,null,!0)).select())},edit:function(b){if(b){var c=b.data("attrs"),d={attrs:c,relatedTarget:b.get(0)},e=a.Event("tokenfield:edittoken",d);if(this.$element.trigger(e),!e.isDefaultPrevented()){b.find(".token-label").text(c.value);var f=b.outerWidth(),g=this.$input.hasClass("tt-input")?this.$input.parent():this.$input;b.replaceWith(g),this.preventCreateTokens=!0,this.$input.val(c.value).select().data("edit",!0).width(f),this.update(),this.$element.trigger(a.Event("tokenfield:editedtoken",d))}}},unedit:function(a){var b=this.$input.hasClass("tt-input")?this.$input.parent():this.$input;if(b.appendTo(this.$wrapper),this.$input.data("edit",!1),this.$mirror.text(""),this.update(),a){var c=this;setTimeout(function(){c.$input.focus()},1)}},remove:function(b,c){if(!(this.$input.is(document.activeElement)||this._disabled||this._readonly)){var d="click"===b.type?a(b.target).closest(".token"):this.$wrapper.find(".token.active");if("click"!==b.type){if(!c)var c="prev";if(this[c](),"prev"===c)var e=0===d.first().prevAll(".token:first").length}var f={attrs:this.getTokenData(d),relatedTarget:d.get(0)},g=a.Event("tokenfield:removetoken",f);if(this.$element.trigger(g),!g.isDefaultPrevented()){var h=a.Event("tokenfield:removedtoken",f),i=a.Event("change",{initiator:"tokenfield"});d.remove(),this.$element.val(this.getTokensList()).trigger(h).trigger(i),(!this.$wrapper.find(".token").length||"click"===b.type||e)&&this.$input.focus(),this.$input.css("width",this.options.minWidth+"px"),this.update(),b.preventDefault(),b.stopPropagation()}}},update:function(){var a=this.$input.val(),b=parseInt(this.$input.css("padding-left"),10),c=parseInt(this.$input.css("padding-right"),10),d=b+c;if(this.$input.data("edit")){if(a||(a=this.$input.prop("placeholder")),a===this.$mirror.text())return;this.$mirror.text(a);var e=this.$mirror.width()+10;if(e>this.$wrapper.width())return this.$input.width(this.$wrapper.width());this.$input.width(e)}else{var f="rtl"===this.textDirection?this.$input.offset().left+this.$input.outerWidth()-this.$wrapper.offset().left-parseInt(this.$wrapper.css("padding-left"),10)-d-1:this.$wrapper.offset().left+this.$wrapper.width()+parseInt(this.$wrapper.css("padding-left"),10)-this.$input.offset().left-d;isNaN(f)?this.$input.width("100%"):this.$input.width(f)}},focusInput:function(b){if(!(a(b.target).closest(".token").length||a(b.target).closest(".token-input").length||a(b.target).closest(".tt-dropdown-menu").length)){var c=this;setTimeout(function(){c.$input.focus()},0)}},search:function(){this.$input.data("ui-autocomplete")&&this.$input.autocomplete("search")},disable:function(){this.setProperty("disabled",!0)},enable:function(){this.setProperty("disabled",!1)},readonly:function(){this.setProperty("readonly",!0)},writeable:function(){this.setProperty("readonly",!1)},setProperty:function(a,b){this["_"+a]=b,this.$input.prop(a,b),this.$element.prop(a,b),this.$wrapper[b?"addClass":"removeClass"](a)},destroy:function(){this.$element.val(this.getTokensList()),this.$element.css(this.$element.data("original-styles")),this.$element.prop("tabindex",this.$element.data("original-tabindex"));var b=a('label[for="'+this.$input.prop("id")+'"]');b.length&&b.prop("for",this.$element.prop("id")),this.$element.insertBefore(this.$wrapper),this.$element.removeData("original-styles").removeData("original-tabindex").removeData("bs.tokenfield"),this.$wrapper.remove(),this.$mirror.remove();var c=this.$element;return c}};var d=a.fn.tokenfield;return a.fn.tokenfield=function(b,d){var e,f=[];Array.prototype.push.apply(f,arguments);var g=this.each(function(){var g=a(this),h=g.data("bs.tokenfield"),i="object"==typeof b&&b;"string"==typeof b&&h&&h[b]?(f.shift(),e=h[b].apply(h,f)):h||"string"==typeof b||d||(g.data("bs.tokenfield",h=new c(this,i)),g.trigger("tokenfield:initialize"))});return"undefined"!=typeof e?e:g},a.fn.tokenfield.defaults={minWidth:60,minLength:0,allowEditing:!0,allowPasting:!0,limit:0,autocomplete:{},typeahead:{},showAutocompleteOnFocus:!1,createTokensOnBlur:!1,delimiter:",",beautify:!0,inputType:"text"},a.fn.tokenfield.Constructor=c,a.fn.tokenfield.noConflict=function(){return a.fn.tokenfield=d,this},c});
/bower_components/bootstrap-tokenfield/dist/css/bootstrap-tokenfield.css
@@ -0,0 +1,209 @@
/*!
* bootstrap-tokenfield
* https://github.com/sliptree/bootstrap-tokenfield
* Copyright 2013-2014 Sliptree and other contributors; Licensed MIT
*/
@-webkit-keyframes blink {
0% {
border-color: #ededed;
}
100% {
border-color: #b94a48;
}
}
@-moz-keyframes blink {
0% {
border-color: #ededed;
}
100% {
border-color: #b94a48;
}
}
@keyframes blink {
0% {
border-color: #ededed;
}
100% {
border-color: #b94a48;
}
}
.tokenfield {
height: auto;
min-height: 34px;
padding-bottom: 0px;
}
.tokenfield.focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.tokenfield .token {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
display: inline-block;
border: 1px solid #d9d9d9;
background-color: #ededed;
white-space: nowrap;
margin: -1px 5px 5px 0;
height: 22px;
vertical-align: top;
cursor: default;
}
.tokenfield .token:hover {
border-color: #b9b9b9;
}
.tokenfield .token.active {
border-color: #52a8ec;
border-color: rgba(82, 168, 236, 0.8);
}
.tokenfield .token.duplicate {
border-color: #ebccd1;
-webkit-animation-name: blink;
animation-name: blink;
-webkit-animation-duration: 0.1s;
animation-duration: 0.1s;
-webkit-animation-direction: normal;
animation-direction: normal;
-webkit-animation-timing-function: ease;
animation-timing-function: ease;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
.tokenfield .token.invalid {
background: none;
border: 1px solid transparent;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
border-bottom: 1px dotted #d9534f;
}
.tokenfield .token.invalid.active {
background: #ededed;
border: 1px solid #ededed;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.tokenfield .token .token-label {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 4px;
vertical-align: top;
}
.tokenfield .token .close {
font-family: Arial;
display: inline-block;
line-height: 100%;
font-size: 1.1em;
line-height: 1.49em;
margin-left: 5px;
float: none;
height: 100%;
vertical-align: top;
padding-right: 4px;
}
.tokenfield .token-input {
background: none;
width: 60px;
min-width: 60px;
border: 0;
height: 20px;
padding: 0;
margin-bottom: 6px;
-webkit-box-shadow: none;
box-shadow: none;
}
.tokenfield .token-input:focus {
border-color: transparent;
outline: 0;
/* IE6-9 */
-webkit-box-shadow: none;
box-shadow: none;
}
.tokenfield.disabled {
cursor: not-allowed;
background-color: #eeeeee;
}
.tokenfield.disabled .token-input {
cursor: not-allowed;
}
.tokenfield.disabled .token:hover {
cursor: not-allowed;
border-color: #d9d9d9;
}
.tokenfield.disabled .token:hover .close {
cursor: not-allowed;
opacity: 0.2;
filter: alpha(opacity=20);
}
.has-warning .tokenfield.focus {
border-color: #66512c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
}
.has-error .tokenfield.focus {
border-color: #843534;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
}
.has-success .tokenfield.focus {
border-color: #2b542c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
}
.tokenfield.input-sm,
.input-group-sm .tokenfield {
min-height: 30px;
padding-bottom: 0px;
}
.input-group-sm .token,
.tokenfield.input-sm .token {
height: 20px;
margin-bottom: 4px;
}
.input-group-sm .token-input,
.tokenfield.input-sm .token-input {
height: 18px;
margin-bottom: 5px;
}
.tokenfield.input-lg,
.input-group-lg .tokenfield {
min-height: 45px;
padding-bottom: 4px;
}
.input-group-lg .token,
.tokenfield.input-lg .token {
height: 25px;
}
.input-group-lg .token-label,
.tokenfield.input-lg .token-label {
line-height: 23px;
}
.input-group-lg .token .close,
.tokenfield.input-lg .token .close {
line-height: 1.3em;
}
.input-group-lg .token-input,
.tokenfield.input-lg .token-input {
height: 23px;
line-height: 23px;
margin-bottom: 6px;
vertical-align: top;
}
.tokenfield.rtl {
direction: rtl;
text-align: right;
}
.tokenfield.rtl .token {
margin: -1px 0 5px 5px;
}
.tokenfield.rtl .token .token-label {
padding-left: 0px;
padding-right: 4px;
}
/bower_components/bootstrap-tokenfield/dist/css/bootstrap-tokenfield.min.css
@@ -0,0 +1,5 @@
/*!
* bootstrap-tokenfield
* https://github.com/sliptree/bootstrap-tokenfield
* Copyright 2013-2014 Sliptree and other contributors; Licensed MIT
*/@-webkit-keyframes blink{0%{border-color:#ededed}100%{border-color:#b94a48}}@-moz-keyframes blink{0%{border-color:#ededed}100%{border-color:#b94a48}}@keyframes blink{0%{border-color:#ededed}100%{border-color:#b94a48}}.tokenfield{height:auto;min-height:34px;padding-bottom:0}.tokenfield.focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.tokenfield .token{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;display:inline-block;border:1px solid #d9d9d9;background-color:#ededed;white-space:nowrap;margin:-1px 5px 5px 0;height:22px;vertical-align:top;cursor:default}.tokenfield .token:hover{border-color:#b9b9b9}.tokenfield .token.active{border-color:#52a8ec;border-color:rgba(82,168,236,.8)}.tokenfield .token.duplicate{border-color:#ebccd1;-webkit-animation-name:blink;animation-name:blink;-webkit-animation-duration:.1s;animation-duration:.1s;-webkit-animation-direction:normal;animation-direction:normal;-webkit-animation-timing-function:ease;animation-timing-function:ease;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.tokenfield .token.invalid{background:0 0;border:1px solid transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border-bottom:1px dotted #d9534f}.tokenfield .token.invalid.active{background:#ededed;border:1px solid #ededed;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.tokenfield .token .token-label{display:inline-block;overflow:hidden;text-overflow:ellipsis;padding-left:4px;vertical-align:top}.tokenfield .token .close{font-family:Arial;display:inline-block;line-height:100%;font-size:1.1em;line-height:1.49em;margin-left:5px;float:none;height:100%;vertical-align:top;padding-right:4px}.tokenfield .token-input{background:0 0;width:60px;min-width:60px;border:0;height:20px;padding:0;margin-bottom:6px;-webkit-box-shadow:none;box-shadow:none}.tokenfield .token-input:focus{border-color:transparent;outline:0;-webkit-box-shadow:none;box-shadow:none}.tokenfield.disabled{cursor:not-allowed;background-color:#eee}.tokenfield.disabled .token-input{cursor:not-allowed}.tokenfield.disabled .token:hover{cursor:not-allowed;border-color:#d9d9d9}.tokenfield.disabled .token:hover .close{cursor:not-allowed;opacity:.2;filter:alpha(opacity=20)}.has-warning .tokenfield.focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-error .tokenfield.focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-success .tokenfield.focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.tokenfield.input-sm,.input-group-sm .tokenfield{min-height:30px;padding-bottom:0}.input-group-sm .token,.tokenfield.input-sm .token{height:20px;margin-bottom:4px}.input-group-sm .token-input,.tokenfield.input-sm .token-input{height:18px;margin-bottom:5px}.tokenfield.input-lg,.input-group-lg .tokenfield{min-height:45px;padding-bottom:4px}.input-group-lg .token,.tokenfield.input-lg .token{height:25px}.input-group-lg .token-label,.tokenfield.input-lg .token-label{line-height:23px}.input-group-lg .token .close,.tokenfield.input-lg .token .close{line-height:1.3em}.input-group-lg .token-input,.tokenfield.input-lg .token-input{height:23px;line-height:23px;margin-bottom:6px;vertical-align:top}.tokenfield.rtl{direction:rtl;text-align:right}.tokenfield.rtl .token{margin:-1px 0 5px 5px}.tokenfield.rtl .token .token-label{padding-left:0;padding-right:4px}
/bower_components/bootstrap-tokenfield/dist/css/tokenfield-typeahead.css
@@ -0,0 +1,141 @@
/*!
* bootstrap-tokenfield
* https://github.com/sliptree/bootstrap-tokenfield
* Copyright 2013-2014 Sliptree and other contributors; Licensed MIT
*/
/* General Typeahead styling, from http://jsfiddle.net/ragulka/Dy9au/1/ */
.twitter-typeahead {
width: 100%;
position: relative;
vertical-align: top;
}
.twitter-typeahead .tt-input,
.twitter-typeahead .tt-hint {
margin: 0;
width: 100%;
vertical-align: middle;
background-color: #ffffff;
}
.twitter-typeahead .tt-hint {
color: #999999;
z-index: 1;
border: 1px solid transparent;
}
.twitter-typeahead .tt-input {
color: #555555;
z-index: 2;
}
.twitter-typeahead .tt-input,
.twitter-typeahead .tt-hint {
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.428571429;
}
.twitter-typeahead .input-sm.tt-input,
.twitter-typeahead .hint-sm.tt-hint {
border-radius: 3px;
}
.twitter-typeahead .input-lg.tt-input,
.twitter-typeahead .hint-lg.tt-hint {
border-radius: 6px;
}
.input-group .twitter-typeahead:first-child .tt-input,
.input-group .twitter-typeahead:first-child .tt-hint {
border-radius: 4px 0 0 4px !important;
}
.input-group .twitter-typeahead:last-child .tt-input,
.input-group .twitter-typeahead:last-child .tt-hint {
border-radius: 0 4px 4px 0 !important;
}
.input-group.input-group-sm .twitter-typeahead:first-child .tt-input,
.input-group.input-group-sm .twitter-typeahead:first-child .tt-hint {
border-radius: 3px 0 0 3px !important;
}
.input-group.input-group-sm .twitter-typeahead:last-child .tt-input,
.input-group.input-group-sm .twitter-typeahead:last-child .tt-hint {
border-radius: 0 3px 3px 0 !important;
}
.input-sm.tt-input,
.hint-sm.tt-hint,
.input-group.input-group-sm .tt-input,
.input-group.input-group-sm .tt-hint {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
}
.input-group.input-group-lg .twitter-typeahead:first-child .tt-input,
.input-group.input-group-lg .twitter-typeahead:first-child .tt-hint {
border-radius: 6px 0 0 6px !important;
}
.input-group.input-group-lg .twitter-typeahead:last-child .tt-input,
.input-group.input-group-lg .twitter-typeahead:last-child .tt-hint {
border-radius: 0 6px 6px 0 !important;
}
.input-lg.tt-input,
.hint-lg.tt-hint,
.input-group.input-group-lg .tt-input,
.input-group.input-group-lg .tt-hint {
height: 45px;
padding: 10px 16px;
font-size: 18px;
line-height: 1.33;
}
.tt-dropdown-menu {
width: 100%;
min-width: 160px;
margin-top: 2px;
padding: 5px 0;
background-color: #ffffff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.15);
*border-right-width: 2px;
*border-bottom-width: 2px;
border-radius: 6px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
}
.tt-suggestion {
display: block;
padding: 3px 20px;
}
.tt-suggestion.tt-cursor {
color: #262626;
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
}
.tt-suggestion.tt-cursor a {
color: #ffffff;
}
.tt-suggestion p {
margin: 0;
}
/* Tokenfield-specific Typeahead styling */
.tokenfield .twitter-typeahead {
width: auto;
}
.tokenfield .twitter-typeahead .tt-hint {
padding: 0;
height: 20px;
}
.tokenfield.input-sm .twitter-typeahead .tt-input,
.tokenfield.input-sm .twitter-typeahead .tt-hint {
height: 18px;
font-size: 12px;
line-height: 1.5;
}
.tokenfield.input-lg .twitter-typeahead .tt-input,
.tokenfield.input-lg .twitter-typeahead .tt-hint {
height: 23px;
font-size: 18px;
line-height: 1.33;
}
.tokenfield .twitter-typeahead .tt-suggestions {
font-size: 14px;
}
/bower_components/bootstrap-tokenfield/dist/css/tokenfield-typeahead.min.css
@@ -0,0 +1,5 @@
/*!
* bootstrap-tokenfield
* https://github.com/sliptree/bootstrap-tokenfield
* Copyright 2013-2014 Sliptree and other contributors; Licensed MIT
*/.twitter-typeahead{width:100%;position:relative;vertical-align:top}.twitter-typeahead .tt-input,.twitter-typeahead .tt-hint{margin:0;width:100%;vertical-align:middle;background-color:#fff}.twitter-typeahead .tt-hint{color:#999;z-index:1;border:1px solid transparent}.twitter-typeahead .tt-input{color:#555;z-index:2}.twitter-typeahead .tt-input,.twitter-typeahead .tt-hint{height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429}.twitter-typeahead .input-sm.tt-input,.twitter-typeahead .hint-sm.tt-hint{border-radius:3px}.twitter-typeahead .input-lg.tt-input,.twitter-typeahead .hint-lg.tt-hint{border-radius:6px}.input-group .twitter-typeahead:first-child .tt-input,.input-group .twitter-typeahead:first-child .tt-hint{border-radius:4px 0 0 4px!important}.input-group .twitter-typeahead:last-child .tt-input,.input-group .twitter-typeahead:last-child .tt-hint{border-radius:0 4px 4px 0!important}.input-group.input-group-sm .twitter-typeahead:first-child .tt-input,.input-group.input-group-sm .twitter-typeahead:first-child .tt-hint{border-radius:3px 0 0 3px!important}.input-group.input-group-sm .twitter-typeahead:last-child .tt-input,.input-group.input-group-sm .twitter-typeahead:last-child .tt-hint{border-radius:0 3px 3px 0!important}.input-sm.tt-input,.hint-sm.tt-hint,.input-group.input-group-sm .tt-input,.input-group.input-group-sm .tt-hint{height:30px;padding:5px 10px;font-size:12px;line-height:1.5}.input-group.input-group-lg .twitter-typeahead:first-child .tt-input,.input-group.input-group-lg .twitter-typeahead:first-child .tt-hint{border-radius:6px 0 0 6px!important}.input-group.input-group-lg .twitter-typeahead:last-child .tt-input,.input-group.input-group-lg .twitter-typeahead:last-child .tt-hint{border-radius:0 6px 6px 0!important}.input-lg.tt-input,.hint-lg.tt-hint,.input-group.input-group-lg .tt-input,.input-group.input-group-lg .tt-hint{height:45px;padding:10px 16px;font-size:18px;line-height:1.33}.tt-dropdown-menu{width:100%;min-width:160px;margin-top:2px;padding:5px 0;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);*border-right-width:2px;*border-bottom-width:2px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.tt-suggestion{display:block;padding:3px 20px}.tt-suggestion.tt-cursor{color:#262626;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.tt-suggestion.tt-cursor a{color:#fff}.tt-suggestion p{margin:0}.tokenfield .twitter-typeahead{width:auto}.tokenfield .twitter-typeahead .tt-hint{padding:0;height:20px}.tokenfield.input-sm .twitter-typeahead .tt-input,.tokenfield.input-sm .twitter-typeahead .tt-hint{height:18px;font-size:12px;line-height:1.5}.tokenfield.input-lg .twitter-typeahead .tt-input,.tokenfield.input-lg .twitter-typeahead .tt-hint{height:23px;font-size:18px;line-height:1.33}.tokenfield .twitter-typeahead .tt-suggestions{font-size:14px}