Last active
October 19, 2016 10:10
-
-
Save kleem/cd47dc25657a59ae19c7e59187d3c5b7 to your computer and use it in GitHub Desktop.
DIITET matrix mvc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global class AppView extends View | |
constructor: (conf) -> | |
super(conf) | |
b = new Bigraph | |
n = new SelectionControls | |
bigraph: b | |
parent: this | |
m = new Matrix | |
bigraph: b | |
parent: this | |
b.load() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.AppView { | |
display: flex; | |
flex-direction: row; | |
} | |
.AppView > .SelectionControls { | |
background: #DDD; | |
border-right: 1px solid gray; | |
} | |
.AppView > .Matrix { | |
flex-grow: 1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.10.0 | |
(function() { | |
var AppView, | |
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, | |
hasProp = {}.hasOwnProperty; | |
global(AppView = (function(superClass) { | |
extend(AppView, superClass); | |
function AppView(conf) { | |
var b, m, n; | |
AppView.__super__.constructor.call(this, conf); | |
b = new Bigraph; | |
n = new SelectionControls({ | |
bigraph: b, | |
parent: this | |
}); | |
m = new Matrix({ | |
bigraph: b, | |
parent: this | |
}); | |
b.load(); | |
} | |
return AppView; | |
})(View)); | |
}).call(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global class Bigraph extends EventSource | |
constructor: (conf) -> | |
super | |
events: ['ready','select'] | |
@selected = | |
as: {} | |
bs: {} | |
load: () -> | |
d3.csv 'tema.csv', (data_a) => | |
@data_a = data_a | |
@data_a.sort (a,b) -> d3.ascending(a.area_progettuale_id, b.area_progettuale_id) | |
@areas = d3.nest() | |
.key (d) -> d.area_progettuale_id | |
.entries @data_a | |
@data_a.forEach (d) -> d.label = d.tema | |
d3.csv 'istituto.csv', (data_b) => | |
@data_b = data_b | |
@data_b.sort (a,b) -> d3.ascending(a.dipartimento_id, b.dipartimento_id) | |
@departments = d3.nest() | |
.key (d) -> d.dipartimento_id | |
.entries @data_b | |
@data_b.forEach (d) -> d.label = d.ist_sigla | |
d3.csv 'istituto_tema.csv', (data_cells) => | |
@data_cells = data_cells | |
@data_cells.forEach (d) -> | |
d.a_id = d.tema_id | |
d.b_id = d.istituto_id | |
# objectify the matrix | |
@data_a_index = {} | |
@data_a.forEach (d) => @data_a_index[d.id] = d | |
@data_b_index = {} | |
@data_b.forEach (d) => @data_b_index[d.id] = d | |
@data_cells.forEach (d) => | |
d.a = @data_a_index[d.a_id] | |
d.b = @data_b_index[d.b_id] | |
@update_selection() | |
@trigger 'ready' | |
select: (data, abs) -> | |
data.forEach (d) => | |
@selected[abs][d.id] = d | |
@update_selection() | |
@trigger 'select' | |
toggle: (d, abs) -> | |
if d.id of @selected[abs] | |
delete @selected[abs][d.id] | |
else | |
@selected[abs][d.id] = d | |
@update_selection() | |
@trigger 'select' | |
set_selected_as: (as) -> | |
@selected.as = {} | |
as.forEach (id) => @selected.as[id] = @data_a_index[id] | |
@update_selection() | |
@trigger 'select' | |
set_selected_bs: (bs) -> | |
@selected.bs = {} | |
bs.forEach (id) => @selected.bs[id] = @data_b_index[id] | |
@update_selection() | |
@trigger 'select' | |
update_selection: () -> | |
@data_a.forEach (d) => d.selected = d.id of @selected.as or Object.keys(@selected.as).length is 0 | |
@data_b.forEach (d) => d.selected = d.id of @selected.bs or Object.keys(@selected.bs).length is 0 | |
@data_cells.forEach (d) -> d.selected = d.a.selected and d.b.selected |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.10.0 | |
(function() { | |
var Bigraph, | |
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, | |
hasProp = {}.hasOwnProperty; | |
global(Bigraph = (function(superClass) { | |
extend(Bigraph, superClass); | |
function Bigraph(conf) { | |
Bigraph.__super__.constructor.call(this, { | |
events: ['ready', 'select'] | |
}); | |
this.selected = { | |
as: {}, | |
bs: {} | |
}; | |
} | |
Bigraph.prototype.load = function() { | |
return d3.csv('tema.csv', (function(_this) { | |
return function(data_a) { | |
_this.data_a = data_a; | |
_this.data_a.sort(function(a, b) { | |
return d3.ascending(a.area_progettuale_id, b.area_progettuale_id); | |
}); | |
_this.areas = d3.nest().key(function(d) { | |
return d.area_progettuale_id; | |
}).entries(_this.data_a); | |
_this.data_a.forEach(function(d) { | |
return d.label = d.tema; | |
}); | |
return d3.csv('istituto.csv', function(data_b) { | |
_this.data_b = data_b; | |
_this.data_b.sort(function(a, b) { | |
return d3.ascending(a.dipartimento_id, b.dipartimento_id); | |
}); | |
_this.departments = d3.nest().key(function(d) { | |
return d.dipartimento_id; | |
}).entries(_this.data_b); | |
_this.data_b.forEach(function(d) { | |
return d.label = d.ist_sigla; | |
}); | |
return d3.csv('istituto_tema.csv', function(data_cells) { | |
_this.data_cells = data_cells; | |
_this.data_cells.forEach(function(d) { | |
d.a_id = d.tema_id; | |
return d.b_id = d.istituto_id; | |
}); | |
_this.data_a_index = {}; | |
_this.data_a.forEach(function(d) { | |
return _this.data_a_index[d.id] = d; | |
}); | |
_this.data_b_index = {}; | |
_this.data_b.forEach(function(d) { | |
return _this.data_b_index[d.id] = d; | |
}); | |
_this.data_cells.forEach(function(d) { | |
d.a = _this.data_a_index[d.a_id]; | |
return d.b = _this.data_b_index[d.b_id]; | |
}); | |
_this.update_selection(); | |
return _this.trigger('ready'); | |
}); | |
}); | |
}; | |
})(this)); | |
}; | |
Bigraph.prototype.select = function(data, abs) { | |
data.forEach((function(_this) { | |
return function(d) { | |
return _this.selected[abs][d.id] = d; | |
}; | |
})(this)); | |
this.update_selection(); | |
return this.trigger('select'); | |
}; | |
Bigraph.prototype.toggle = function(d, abs) { | |
if (d.id in this.selected[abs]) { | |
delete this.selected[abs][d.id]; | |
} else { | |
this.selected[abs][d.id] = d; | |
} | |
this.update_selection(); | |
return this.trigger('select'); | |
}; | |
Bigraph.prototype.set_selected_as = function(as) { | |
this.selected.as = {}; | |
as.forEach((function(_this) { | |
return function(id) { | |
return _this.selected.as[id] = _this.data_a_index[id]; | |
}; | |
})(this)); | |
this.update_selection(); | |
return this.trigger('select'); | |
}; | |
Bigraph.prototype.set_selected_bs = function(bs) { | |
this.selected.bs = {}; | |
bs.forEach((function(_this) { | |
return function(id) { | |
return _this.selected.bs[id] = _this.data_b_index[id]; | |
}; | |
})(this)); | |
this.update_selection(); | |
return this.trigger('select'); | |
}; | |
Bigraph.prototype.update_selection = function() { | |
this.data_a.forEach((function(_this) { | |
return function(d) { | |
return d.selected = d.id in _this.selected.as || Object.keys(_this.selected.as).length === 0; | |
}; | |
})(this)); | |
this.data_b.forEach((function(_this) { | |
return function(d) { | |
return d.selected = d.id in _this.selected.bs || Object.keys(_this.selected.bs).length === 0; | |
}; | |
})(this)); | |
return this.data_cells.forEach(function(d) { | |
return d.selected = d.a.selected && d.b.selected; | |
}); | |
}; | |
return Bigraph; | |
})(EventSource)); | |
}).call(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
span.hide-native-select{position:relative}span.hide-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px 3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Bootstrap Multiselect (https://github.com/davidstutz/bootstrap-multiselect) | |
* | |
* Apache License, Version 2.0: | |
* Copyright (c) 2012 - 2015 David Stutz | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |
* use this file except in compliance with the License. You may obtain a | |
* copy of the License at http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
* License for the specific language governing permissions and limitations | |
* under the License. | |
* | |
* BSD 3-Clause License: | |
* Copyright (c) 2012 - 2015 David Stutz | |
* All rights reserved. | |
* | |
* Redistribution and use in source and binary forms, with or without | |
* modification, are permitted provided that the following conditions are met: | |
* - Redistributions of source code must retain the above copyright notice, | |
* this list of conditions and the following disclaimer. | |
* - Redistributions in binary form must reproduce the above copyright notice, | |
* this list of conditions and the following disclaimer in the documentation | |
* and/or other materials provided with the distribution. | |
* - Neither the name of David Stutz nor the names of its contributors may be | |
* used to endorse or promote products derived from this software without | |
* specific prior written permission. | |
* | |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | |
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | |
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
*/ | |
!function ($) { | |
"use strict";// jshint ;_; | |
if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) { | |
ko.bindingHandlers.multiselect = { | |
after: ['options', 'value', 'selectedOptions', 'enable', 'disable'], | |
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { | |
var $element = $(element); | |
var config = ko.toJS(valueAccessor()); | |
$element.multiselect(config); | |
if (allBindings.has('options')) { | |
var options = allBindings.get('options'); | |
if (ko.isObservable(options)) { | |
ko.computed({ | |
read: function() { | |
options(); | |
setTimeout(function() { | |
var ms = $element.data('multiselect'); | |
if (ms) | |
ms.updateOriginalOptions();//Not sure how beneficial this is. | |
$element.multiselect('rebuild'); | |
}, 1); | |
}, | |
disposeWhenNodeIsRemoved: element | |
}); | |
} | |
} | |
//value and selectedOptions are two-way, so these will be triggered even by our own actions. | |
//It needs some way to tell if they are triggered because of us or because of outside change. | |
//It doesn't loop but it's a waste of processing. | |
if (allBindings.has('value')) { | |
var value = allBindings.get('value'); | |
if (ko.isObservable(value)) { | |
ko.computed({ | |
read: function() { | |
value(); | |
setTimeout(function() { | |
$element.multiselect('refresh'); | |
}, 1); | |
}, | |
disposeWhenNodeIsRemoved: element | |
}).extend({ rateLimit: 100, notifyWhenChangesStop: true }); | |
} | |
} | |
//Switched from arrayChange subscription to general subscription using 'refresh'. | |
//Not sure performance is any better using 'select' and 'deselect'. | |
if (allBindings.has('selectedOptions')) { | |
var selectedOptions = allBindings.get('selectedOptions'); | |
if (ko.isObservable(selectedOptions)) { | |
ko.computed({ | |
read: function() { | |
selectedOptions(); | |
setTimeout(function() { | |
$element.multiselect('refresh'); | |
}, 1); | |
}, | |
disposeWhenNodeIsRemoved: element | |
}).extend({ rateLimit: 100, notifyWhenChangesStop: true }); | |
} | |
} | |
var setEnabled = function (enable) { | |
setTimeout(function () { | |
if (enable) | |
$element.multiselect('enable'); | |
else | |
$element.multiselect('disable'); | |
}); | |
}; | |
if (allBindings.has('enable')) { | |
var enable = allBindings.get('enable'); | |
if (ko.isObservable(enable)) { | |
ko.computed({ | |
read: function () { | |
setEnabled(enable()); | |
}, | |
disposeWhenNodeIsRemoved: element | |
}).extend({ rateLimit: 100, notifyWhenChangesStop: true }); | |
} else { | |
setEnabled(enable); | |
} | |
} | |
if (allBindings.has('disable')) { | |
var disable = allBindings.get('disable'); | |
if (ko.isObservable(disable)) { | |
ko.computed({ | |
read: function () { | |
setEnabled(!disable()); | |
}, | |
disposeWhenNodeIsRemoved: element | |
}).extend({ rateLimit: 100, notifyWhenChangesStop: true }); | |
} else { | |
setEnabled(!disable); | |
} | |
} | |
ko.utils.domNodeDisposal.addDisposeCallback(element, function() { | |
$element.multiselect('destroy'); | |
}); | |
}, | |
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { | |
var $element = $(element); | |
var config = ko.toJS(valueAccessor()); | |
$element.multiselect('setOptions', config); | |
$element.multiselect('rebuild'); | |
} | |
}; | |
} | |
function forEach(array, callback) { | |
for (var index = 0; index < array.length; ++index) { | |
callback(array[index], index); | |
} | |
} | |
/** | |
* Constructor to create a new multiselect using the given select. | |
* | |
* @param {jQuery} select | |
* @param {Object} options | |
* @returns {Multiselect} | |
*/ | |
function Multiselect(select, options) { | |
this.$select = $(select); | |
// Placeholder via data attributes | |
if (this.$select.attr("data-placeholder")) { | |
options.nonSelectedText = this.$select.data("placeholder"); | |
} | |
this.options = this.mergeOptions($.extend({}, options, this.$select.data())); | |
// Initialization. | |
// We have to clone to create a new reference. | |
this.originalOptions = this.$select.clone()[0].options; | |
this.query = ''; | |
this.searchTimeout = null; | |
this.lastToggledInput = null; | |
this.options.multiple = this.$select.attr('multiple') === "multiple"; | |
this.options.onChange = $.proxy(this.options.onChange, this); | |
this.options.onSelectAll = $.proxy(this.options.onSelectAll, this); | |
this.options.onDeselectAll = $.proxy(this.options.onDeselectAll, this); | |
this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this); | |
this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this); | |
this.options.onDropdownShown = $.proxy(this.options.onDropdownShown, this); | |
this.options.onDropdownHidden = $.proxy(this.options.onDropdownHidden, this); | |
this.options.onInitialized = $.proxy(this.options.onInitialized, this); | |
this.options.onFiltering = $.proxy(this.options.onFiltering, this); | |
// Build select all if enabled. | |
this.buildContainer(); | |
this.buildButton(); | |
this.buildDropdown(); | |
this.buildSelectAll(); | |
this.buildDropdownOptions(); | |
this.buildFilter(); | |
this.updateButtonText(); | |
this.updateSelectAll(true); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) { | |
this.disable(); | |
} | |
this.$select.wrap('<span class="hide-native-select">').after(this.$container); | |
this.options.onInitialized(this.$select, this.$container); | |
} | |
Multiselect.prototype = { | |
defaults: { | |
/** | |
* Default text function will either print 'None selected' in case no | |
* option is selected or a list of the selected options up to a length | |
* of 3 selected options. | |
* | |
* @param {jQuery} options | |
* @param {jQuery} select | |
* @returns {String} | |
*/ | |
buttonText: function(options, select) { | |
if (this.disabledText.length > 0 | |
&& (select.prop('disabled') || (options.length == 0 && this.disableIfEmpty))) { | |
return this.disabledText; | |
} | |
else if (options.length === 0) { | |
return this.nonSelectedText; | |
} | |
else if (this.allSelectedText | |
&& options.length === $('option', $(select)).length | |
&& $('option', $(select)).length !== 1 | |
&& this.multiple) { | |
if (this.selectAllNumber) { | |
return this.allSelectedText + ' (' + options.length + ')'; | |
} | |
else { | |
return this.allSelectedText; | |
} | |
} | |
else if (options.length > this.numberDisplayed) { | |
return options.length + ' ' + this.nSelectedText; | |
} | |
else { | |
var selected = ''; | |
var delimiter = this.delimiterText; | |
options.each(function() { | |
var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text(); | |
selected += label + delimiter; | |
}); | |
return selected.substr(0, selected.length - this.delimiterText.length); | |
} | |
}, | |
/** | |
* Updates the title of the button similar to the buttonText function. | |
* | |
* @param {jQuery} options | |
* @param {jQuery} select | |
* @returns {@exp;selected@call;substr} | |
*/ | |
buttonTitle: function(options, select) { | |
if (options.length === 0) { | |
return this.nonSelectedText; | |
} | |
else { | |
var selected = ''; | |
var delimiter = this.delimiterText; | |
options.each(function () { | |
var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).text(); | |
selected += label + delimiter; | |
}); | |
return selected.substr(0, selected.length - this.delimiterText.length); | |
} | |
}, | |
checkboxName: function(option) { | |
return false; // no checkbox name | |
}, | |
/** | |
* Create a label. | |
* | |
* @param {jQuery} element | |
* @returns {String} | |
*/ | |
optionLabel: function(element){ | |
return $(element).attr('label') || $(element).text(); | |
}, | |
/** | |
* Create a class. | |
* | |
* @param {jQuery} element | |
* @returns {String} | |
*/ | |
optionClass: function(element) { | |
return $(element).attr('class') || ''; | |
}, | |
/** | |
* Triggered on change of the multiselect. | |
* | |
* Not triggered when selecting/deselecting options manually. | |
* | |
* @param {jQuery} option | |
* @param {Boolean} checked | |
*/ | |
onChange : function(option, checked) { | |
}, | |
/** | |
* Triggered when the dropdown is shown. | |
* | |
* @param {jQuery} event | |
*/ | |
onDropdownShow: function(event) { | |
}, | |
/** | |
* Triggered when the dropdown is hidden. | |
* | |
* @param {jQuery} event | |
*/ | |
onDropdownHide: function(event) { | |
}, | |
/** | |
* Triggered after the dropdown is shown. | |
* | |
* @param {jQuery} event | |
*/ | |
onDropdownShown: function(event) { | |
}, | |
/** | |
* Triggered after the dropdown is hidden. | |
* | |
* @param {jQuery} event | |
*/ | |
onDropdownHidden: function(event) { | |
}, | |
/** | |
* Triggered on select all. | |
*/ | |
onSelectAll: function() { | |
}, | |
/** | |
* Triggered on deselect all. | |
*/ | |
onDeselectAll: function() { | |
}, | |
/** | |
* Triggered after initializing. | |
* | |
* @param {jQuery} $select | |
* @param {jQuery} $container | |
*/ | |
onInitialized: function($select, $container) { | |
}, | |
/** | |
* Triggered on filtering. | |
* | |
* @param {jQuery} $filter | |
*/ | |
onFiltering: function($filter) { | |
}, | |
enableHTML: false, | |
buttonClass: 'btn btn-default', | |
inheritClass: false, | |
buttonWidth: 'auto', | |
buttonContainer: '<div class="btn-group" />', | |
dropRight: false, | |
dropUp: false, | |
selectedClass: 'active', | |
// Maximum height of the dropdown menu. | |
// If maximum height is exceeded a scrollbar will be displayed. | |
maxHeight: false, | |
includeSelectAllOption: false, | |
includeSelectAllIfMoreThan: 0, | |
selectAllText: ' Select all', | |
selectAllValue: 'multiselect-all', | |
selectAllName: false, | |
selectAllNumber: true, | |
selectAllJustVisible: true, | |
enableFiltering: false, | |
enableCaseInsensitiveFiltering: false, | |
enableFullValueFiltering: false, | |
enableClickableOptGroups: false, | |
enableCollapsibleOptGroups: false, | |
filterPlaceholder: 'Search', | |
// possible options: 'text', 'value', 'both' | |
filterBehavior: 'text', | |
includeFilterClearBtn: true, | |
preventInputChangeEvent: false, | |
nonSelectedText: 'None selected', | |
nSelectedText: 'selected', | |
allSelectedText: 'All selected', | |
numberDisplayed: 3, | |
disableIfEmpty: false, | |
disabledText: '', | |
delimiterText: ', ', | |
templates: { | |
button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"><span class="multiselect-selected-text"></span> <b class="caret"></b></button>', | |
ul: '<ul class="multiselect-container dropdown-menu"></ul>', | |
filter: '<li class="multiselect-item multiselect-filter"><div class="input-group"><span class="input-group-addon"><i class="glyphicon glyphicon-search"></i></span><input class="form-control multiselect-search" type="text"></div></li>', | |
filterClearBtn: '<span class="input-group-btn"><button class="btn btn-default multiselect-clear-filter" type="button"><i class="glyphicon glyphicon-remove-circle"></i></button></span>', | |
li: '<li><a tabindex="0"><label></label></a></li>', | |
divider: '<li class="multiselect-item divider"></li>', | |
liGroup: '<li class="multiselect-item multiselect-group"><label></label></li>' | |
} | |
}, | |
constructor: Multiselect, | |
/** | |
* Builds the container of the multiselect. | |
*/ | |
buildContainer: function() { | |
this.$container = $(this.options.buttonContainer); | |
this.$container.on('show.bs.dropdown', this.options.onDropdownShow); | |
this.$container.on('hide.bs.dropdown', this.options.onDropdownHide); | |
this.$container.on('shown.bs.dropdown', this.options.onDropdownShown); | |
this.$container.on('hidden.bs.dropdown', this.options.onDropdownHidden); | |
}, | |
/** | |
* Builds the button of the multiselect. | |
*/ | |
buildButton: function() { | |
this.$button = $(this.options.templates.button).addClass(this.options.buttonClass); | |
if (this.$select.attr('class') && this.options.inheritClass) { | |
this.$button.addClass(this.$select.attr('class')); | |
} | |
// Adopt active state. | |
if (this.$select.prop('disabled')) { | |
this.disable(); | |
} | |
else { | |
this.enable(); | |
} | |
// Manually add button width if set. | |
if (this.options.buttonWidth && this.options.buttonWidth !== 'auto') { | |
this.$button.css({ | |
'width' : '100%', //this.options.buttonWidth, | |
'overflow' : 'hidden', | |
'text-overflow' : 'ellipsis' | |
}); | |
this.$container.css({ | |
'width': this.options.buttonWidth | |
}); | |
} | |
// Keep the tab index from the select. | |
var tabindex = this.$select.attr('tabindex'); | |
if (tabindex) { | |
this.$button.attr('tabindex', tabindex); | |
} | |
this.$container.prepend(this.$button); | |
}, | |
/** | |
* Builds the ul representing the dropdown menu. | |
*/ | |
buildDropdown: function() { | |
// Build ul. | |
this.$ul = $(this.options.templates.ul); | |
if (this.options.dropRight) { | |
this.$ul.addClass('pull-right'); | |
} | |
// Set max height of dropdown menu to activate auto scrollbar. | |
if (this.options.maxHeight) { | |
// TODO: Add a class for this option to move the css declarations. | |
this.$ul.css({ | |
'max-height': this.options.maxHeight + 'px', | |
'overflow-y': 'auto', | |
'overflow-x': 'hidden' | |
}); | |
} | |
if (this.options.dropUp) { | |
var height = Math.min(this.options.maxHeight, $('option[data-role!="divider"]', this.$select).length*26 + $('option[data-role="divider"]', this.$select).length*19 + (this.options.includeSelectAllOption ? 26 : 0) + (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering ? 44 : 0)); | |
var moveCalc = height + 34; | |
this.$ul.css({ | |
'max-height': height + 'px', | |
'overflow-y': 'auto', | |
'overflow-x': 'hidden', | |
'margin-top': "-" + moveCalc + 'px' | |
}); | |
} | |
this.$container.append(this.$ul); | |
}, | |
/** | |
* Build the dropdown options and binds all necessary events. | |
* | |
* Uses createDivider and createOptionValue to create the necessary options. | |
*/ | |
buildDropdownOptions: function() { | |
this.$select.children().each($.proxy(function(index, element) { | |
var $element = $(element); | |
// Support optgroups and options without a group simultaneously. | |
var tag = $element.prop('tagName') | |
.toLowerCase(); | |
if ($element.prop('value') === this.options.selectAllValue) { | |
return; | |
} | |
if (tag === 'optgroup') { | |
this.createOptgroup(element); | |
} | |
else if (tag === 'option') { | |
if ($element.data('role') === 'divider') { | |
this.createDivider(); | |
} | |
else { | |
this.createOptionValue(element); | |
} | |
} | |
// Other illegal tags will be ignored. | |
}, this)); | |
// Bind the change event on the dropdown elements. | |
$('li:not(.multiselect-group) input', this.$ul).on('change', $.proxy(function(event) { | |
var $target = $(event.target); | |
var checked = $target.prop('checked') || false; | |
var isSelectAllOption = $target.val() === this.options.selectAllValue; | |
// Apply or unapply the configured selected class. | |
if (this.options.selectedClass) { | |
if (checked) { | |
$target.closest('li') | |
.addClass(this.options.selectedClass); | |
} | |
else { | |
$target.closest('li') | |
.removeClass(this.options.selectedClass); | |
} | |
} | |
// Get the corresponding option. | |
var value = $target.val(); | |
var $option = this.getOptionByValue(value); | |
var $optionsNotThis = $('option', this.$select).not($option); | |
var $checkboxesNotThis = $('input', this.$container).not($target); | |
if (isSelectAllOption) { | |
if (checked) { | |
this.selectAll(this.options.selectAllJustVisible); | |
} | |
else { | |
this.deselectAll(this.options.selectAllJustVisible); | |
} | |
} | |
else { | |
if (checked) { | |
$option.prop('selected', true); | |
if (this.options.multiple) { | |
// Simply select additional option. | |
$option.prop('selected', true); | |
} | |
else { | |
// Unselect all other options and corresponding checkboxes. | |
if (this.options.selectedClass) { | |
$($checkboxesNotThis).closest('li').removeClass(this.options.selectedClass); | |
} | |
$($checkboxesNotThis).prop('checked', false); | |
$optionsNotThis.prop('selected', false); | |
// It's a single selection, so close. | |
this.$button.click(); | |
} | |
if (this.options.selectedClass === "active") { | |
$optionsNotThis.closest("a").css("outline", ""); | |
} | |
} | |
else { | |
// Unselect option. | |
$option.prop('selected', false); | |
} | |
// To prevent select all from firing onChange: #575 | |
this.options.onChange($option, checked); | |
// Do not update select all or optgroups on select all change! | |
this.updateSelectAll(); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
} | |
this.$select.change(); | |
this.updateButtonText(); | |
if(this.options.preventInputChangeEvent) { | |
return false; | |
} | |
}, this)); | |
$('li a', this.$ul).on('mousedown', function(e) { | |
if (e.shiftKey) { | |
// Prevent selecting text by Shift+click | |
return false; | |
} | |
}); | |
$('li a', this.$ul).on('touchstart click', $.proxy(function(event) { | |
event.stopPropagation(); | |
var $target = $(event.target); | |
if (event.shiftKey && this.options.multiple) { | |
if($target.is("label")){ // Handles checkbox selection manually (see https://github.com/davidstutz/bootstrap-multiselect/issues/431) | |
event.preventDefault(); | |
$target = $target.find("input"); | |
$target.prop("checked", !$target.prop("checked")); | |
} | |
var checked = $target.prop('checked') || false; | |
if (this.lastToggledInput !== null && this.lastToggledInput !== $target) { // Make sure we actually have a range | |
var from = $target.closest("li").index(); | |
var to = this.lastToggledInput.closest("li").index(); | |
if (from > to) { // Swap the indices | |
var tmp = to; | |
to = from; | |
from = tmp; | |
} | |
// Make sure we grab all elements since slice excludes the last index | |
++to; | |
// Change the checkboxes and underlying options | |
var range = this.$ul.find("li").slice(from, to).find("input"); | |
range.prop('checked', checked); | |
if (this.options.selectedClass) { | |
range.closest('li') | |
.toggleClass(this.options.selectedClass, checked); | |
} | |
for (var i = 0, j = range.length; i < j; i++) { | |
var $checkbox = $(range[i]); | |
var $option = this.getOptionByValue($checkbox.val()); | |
$option.prop('selected', checked); | |
} | |
} | |
// Trigger the select "change" event | |
$target.trigger("change"); | |
} | |
// Remembers last clicked option | |
if($target.is("input") && !$target.closest("li").is(".multiselect-item")){ | |
this.lastToggledInput = $target; | |
} | |
$target.blur(); | |
}, this)); | |
// Keyboard support. | |
this.$container.off('keydown.multiselect').on('keydown.multiselect', $.proxy(function(event) { | |
if ($('input[type="text"]', this.$container).is(':focus')) { | |
return; | |
} | |
if (event.keyCode === 9 && this.$container.hasClass('open')) { | |
this.$button.click(); | |
} | |
else { | |
var $items = $(this.$container).find("li:not(.divider):not(.disabled) a").filter(":visible"); | |
if (!$items.length) { | |
return; | |
} | |
var index = $items.index($items.filter(':focus')); | |
// Navigation up. | |
if (event.keyCode === 38 && index > 0) { | |
index--; | |
} | |
// Navigate down. | |
else if (event.keyCode === 40 && index < $items.length - 1) { | |
index++; | |
} | |
else if (!~index) { | |
index = 0; | |
} | |
var $current = $items.eq(index); | |
$current.focus(); | |
if (event.keyCode === 32 || event.keyCode === 13) { | |
var $checkbox = $current.find('input'); | |
$checkbox.prop("checked", !$checkbox.prop("checked")); | |
$checkbox.change(); | |
} | |
event.stopPropagation(); | |
event.preventDefault(); | |
} | |
}, this)); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
$("li.multiselect-group input", this.$ul).on("change", $.proxy(function(event) { | |
event.stopPropagation(); | |
var $target = $(event.target); | |
var checked = $target.prop('checked') || false; | |
var $li = $(event.target).closest('li'); | |
var $group = $li.nextUntil("li.multiselect-group") | |
.not('.multiselect-filter-hidden') | |
.not('.disabled'); | |
var $inputs = $group.find("input"); | |
var values = []; | |
var $options = []; | |
$.each($inputs, $.proxy(function(index, input) { | |
var value = $(input).val(); | |
var $option = this.getOptionByValue(value); | |
if (checked) { | |
$(input).prop('checked', true); | |
$(input).closest('li') | |
.addClass(this.options.selectedClass); | |
$option.prop('selected', true); | |
} | |
else { | |
$(input).prop('checked', false); | |
$(input).closest('li') | |
.removeClass(this.options.selectedClass); | |
$option.prop('selected', false); | |
} | |
$options.push(this.getOptionByValue(value)); | |
}, this)) | |
// Cannot use select or deselect here because it would call updateOptGroups again. | |
this.options.onChange($options, checked); | |
this.updateButtonText(); | |
this.updateSelectAll(); | |
}, this)); | |
} | |
if (this.options.enableCollapsibleOptGroups && this.options.multiple) { | |
$("li.multiselect-group .caret-container", this.$ul).on("click", $.proxy(function(event) { | |
var $li = $(event.target).closest('li'); | |
var $inputs = $li.nextUntil("li.multiselect-group") | |
.not('.multiselect-filter-hidden'); | |
var visible = true; | |
$inputs.each(function() { | |
visible = visible && $(this).is(':visible'); | |
}); | |
if (visible) { | |
$inputs.hide() | |
.addClass('multiselect-collapsible-hidden'); | |
} | |
else { | |
$inputs.show() | |
.removeClass('multiselect-collapsible-hidden'); | |
} | |
}, this)); | |
$("li.multiselect-all", this.$ul).css('background', '#f3f3f3').css('border-bottom', '1px solid #eaeaea'); | |
$("li.multiselect-all > a > label.checkbox", this.$ul).css('padding', '3px 20px 3px 35px'); | |
$("li.multiselect-group > a > input", this.$ul).css('margin', '4px 0px 5px -20px'); | |
} | |
}, | |
/** | |
* Create an option using the given select option. | |
* | |
* @param {jQuery} element | |
*/ | |
createOptionValue: function(element) { | |
var $element = $(element); | |
if ($element.is(':selected')) { | |
$element.prop('selected', true); | |
} | |
// Support the label attribute on options. | |
var label = this.options.optionLabel(element); | |
var classes = this.options.optionClass(element); | |
var value = $element.val(); | |
var inputType = this.options.multiple ? "checkbox" : "radio"; | |
var $li = $(this.options.templates.li); | |
var $label = $('label', $li); | |
$label.addClass(inputType); | |
$li.addClass(classes); | |
if (this.options.enableHTML) { | |
$label.html(" " + label); | |
} | |
else { | |
$label.text(" " + label); | |
} | |
var $checkbox = $('<input/>').attr('type', inputType); | |
var name = this.options.checkboxName($element); | |
if (name) { | |
$checkbox.attr('name', name); | |
} | |
$label.prepend($checkbox); | |
var selected = $element.prop('selected') || false; | |
$checkbox.val(value); | |
if (value === this.options.selectAllValue) { | |
$li.addClass("multiselect-item multiselect-all"); | |
$checkbox.parent().parent() | |
.addClass('multiselect-all'); | |
} | |
$label.attr('title', $element.attr('title')); | |
this.$ul.append($li); | |
if ($element.is(':disabled')) { | |
$checkbox.attr('disabled', 'disabled') | |
.prop('disabled', true) | |
.closest('a') | |
.attr("tabindex", "-1") | |
.closest('li') | |
.addClass('disabled'); | |
} | |
$checkbox.prop('checked', selected); | |
if (selected && this.options.selectedClass) { | |
$checkbox.closest('li') | |
.addClass(this.options.selectedClass); | |
} | |
}, | |
/** | |
* Creates a divider using the given select option. | |
* | |
* @param {jQuery} element | |
*/ | |
createDivider: function(element) { | |
var $divider = $(this.options.templates.divider); | |
this.$ul.append($divider); | |
}, | |
/** | |
* Creates an optgroup. | |
* | |
* @param {jQuery} group | |
*/ | |
createOptgroup: function(group) { | |
var label = $(group).attr("label"); | |
var value = $(group).attr("value"); | |
var $li = $('<li class="multiselect-item multiselect-group"><a href="javascript:void(0);"><label><b></b></label></a></li>'); | |
var classes = this.options.optionClass(group); | |
$li.addClass(classes); | |
if (this.options.enableHTML) { | |
$('label b', $li).html(" " + label); | |
} | |
else { | |
$('label b', $li).text(" " + label); | |
} | |
if (this.options.enableCollapsibleOptGroups && this.options.multiple) { | |
$('a', $li).append('<span class="caret-container"><b class="caret"></b></span>'); | |
} | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
$('a label', $li).prepend('<input type="checkbox" value="' + value + '"/>'); | |
} | |
if ($(group).is(':disabled')) { | |
$li.addClass('disabled'); | |
} | |
this.$ul.append($li); | |
$("option", group).each($.proxy(function($, group) { | |
this.createOptionValue(group); | |
}, this)) | |
}, | |
/** | |
* Build the select all. | |
* | |
* Checks if a select all has already been created. | |
*/ | |
buildSelectAll: function() { | |
if (typeof this.options.selectAllValue === 'number') { | |
this.options.selectAllValue = this.options.selectAllValue.toString(); | |
} | |
var alreadyHasSelectAll = this.hasSelectAll(); | |
if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple | |
&& $('option', this.$select).length > this.options.includeSelectAllIfMoreThan) { | |
// Check whether to add a divider after the select all. | |
if (this.options.includeSelectAllDivider) { | |
this.$ul.prepend($(this.options.templates.divider)); | |
} | |
var $li = $(this.options.templates.li); | |
$('label', $li).addClass("checkbox"); | |
if (this.options.enableHTML) { | |
$('label', $li).html(" " + this.options.selectAllText); | |
} | |
else { | |
$('label', $li).text(" " + this.options.selectAllText); | |
} | |
if (this.options.selectAllName) { | |
$('label', $li).prepend('<input type="checkbox" name="' + this.options.selectAllName + '" />'); | |
} | |
else { | |
$('label', $li).prepend('<input type="checkbox" />'); | |
} | |
var $checkbox = $('input', $li); | |
$checkbox.val(this.options.selectAllValue); | |
$li.addClass("multiselect-item multiselect-all"); | |
$checkbox.parent().parent() | |
.addClass('multiselect-all'); | |
this.$ul.prepend($li); | |
$checkbox.prop('checked', false); | |
} | |
}, | |
/** | |
* Builds the filter. | |
*/ | |
buildFilter: function() { | |
// Build filter if filtering OR case insensitive filtering is enabled and the number of options exceeds (or equals) enableFilterLength. | |
if (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering) { | |
var enableFilterLength = Math.max(this.options.enableFiltering, this.options.enableCaseInsensitiveFiltering); | |
if (this.$select.find('option').length >= enableFilterLength) { | |
this.$filter = $(this.options.templates.filter); | |
$('input', this.$filter).attr('placeholder', this.options.filterPlaceholder); | |
// Adds optional filter clear button | |
if(this.options.includeFilterClearBtn) { | |
var clearBtn = $(this.options.templates.filterClearBtn); | |
clearBtn.on('click', $.proxy(function(event){ | |
clearTimeout(this.searchTimeout); | |
this.$filter.find('.multiselect-search').val(''); | |
$('li', this.$ul).show().removeClass('multiselect-filter-hidden'); | |
this.updateSelectAll(); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
}, this)); | |
this.$filter.find('.input-group').append(clearBtn); | |
} | |
this.$ul.prepend(this.$filter); | |
this.$filter.val(this.query).on('click', function(event) { | |
event.stopPropagation(); | |
}).on('input keydown', $.proxy(function(event) { | |
// Cancel enter key default behaviour | |
if (event.which === 13) { | |
event.preventDefault(); | |
} | |
// This is useful to catch "keydown" events after the browser has updated the control. | |
clearTimeout(this.searchTimeout); | |
this.searchTimeout = this.asyncFunction($.proxy(function() { | |
if (this.query !== event.target.value) { | |
this.query = event.target.value; | |
var currentGroup, currentGroupVisible; | |
$.each($('li', this.$ul), $.proxy(function(index, element) { | |
var value = $('input', element).length > 0 ? $('input', element).val() : ""; | |
var text = $('label', element).text(); | |
var filterCandidate = ''; | |
if ((this.options.filterBehavior === 'text')) { | |
filterCandidate = text; | |
} | |
else if ((this.options.filterBehavior === 'value')) { | |
filterCandidate = value; | |
} | |
else if (this.options.filterBehavior === 'both') { | |
filterCandidate = text + '\n' + value; | |
} | |
if (value !== this.options.selectAllValue && text) { | |
// By default lets assume that element is not | |
// interesting for this search. | |
var showElement = false; | |
if (this.options.enableCaseInsensitiveFiltering) { | |
filterCandidate = filterCandidate.toLowerCase(); | |
this.query = this.query.toLowerCase(); | |
} | |
if (this.options.enableFullValueFiltering && this.options.filterBehavior !== 'both') { | |
var valueToMatch = filterCandidate.trim().substring(0, this.query.length); | |
if (this.query.indexOf(valueToMatch) > -1) { | |
showElement = true; | |
} | |
} | |
else if (filterCandidate.indexOf(this.query) > -1) { | |
showElement = true; | |
} | |
// Toggle current element (group or group item) according to showElement boolean. | |
$(element).toggle(showElement) | |
.toggleClass('multiselect-filter-hidden', !showElement); | |
// Differentiate groups and group items. | |
if ($(element).hasClass('multiselect-group')) { | |
// Remember group status. | |
currentGroup = element; | |
currentGroupVisible = showElement; | |
} | |
else { | |
// Show group name when at least one of its items is visible. | |
if (showElement) { | |
$(currentGroup).show() | |
.removeClass('multiselect-filter-hidden'); | |
} | |
// Show all group items when group name satisfies filter. | |
if (!showElement && currentGroupVisible) { | |
$(element).show() | |
.removeClass('multiselect-filter-hidden'); | |
} | |
} | |
} | |
}, this)); | |
} | |
this.updateSelectAll(); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
this.options.onFiltering(event.target); | |
}, this), 300, this); | |
}, this)); | |
} | |
} | |
}, | |
/** | |
* Unbinds the whole plugin. | |
*/ | |
destroy: function() { | |
this.$container.remove(); | |
this.$select.show(); | |
this.$select.data('multiselect', null); | |
}, | |
/** | |
* Refreshs the multiselect based on the selected options of the select. | |
*/ | |
refresh: function () { | |
var inputs = $.map($('li input', this.$ul), $); | |
$('option', this.$select).each($.proxy(function (index, element) { | |
var $elem = $(element); | |
var value = $elem.val(); | |
var $input; | |
for (var i = inputs.length; 0 < i--; /**/) { | |
if (value !== ($input = inputs[i]).val()) | |
continue; // wrong li | |
if ($elem.is(':selected')) { | |
$input.prop('checked', true); | |
if (this.options.selectedClass) { | |
$input.closest('li') | |
.addClass(this.options.selectedClass); | |
} | |
} | |
else { | |
$input.prop('checked', false); | |
if (this.options.selectedClass) { | |
$input.closest('li') | |
.removeClass(this.options.selectedClass); | |
} | |
} | |
if ($elem.is(":disabled")) { | |
$input.attr('disabled', 'disabled') | |
.prop('disabled', true) | |
.closest('li') | |
.addClass('disabled'); | |
} | |
else { | |
$input.prop('disabled', false) | |
.closest('li') | |
.removeClass('disabled'); | |
} | |
break; // assumes unique values | |
} | |
}, this)); | |
this.updateButtonText(); | |
this.updateSelectAll(); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
}, | |
/** | |
* Select all options of the given values. | |
* | |
* If triggerOnChange is set to true, the on change event is triggered if | |
* and only if one value is passed. | |
* | |
* @param {Array} selectValues | |
* @param {Boolean} triggerOnChange | |
*/ | |
select: function(selectValues, triggerOnChange) { | |
if(!$.isArray(selectValues)) { | |
selectValues = [selectValues]; | |
} | |
for (var i = 0; i < selectValues.length; i++) { | |
var value = selectValues[i]; | |
if (value === null || value === undefined) { | |
continue; | |
} | |
var $option = this.getOptionByValue(value); | |
var $checkbox = this.getInputByValue(value); | |
if($option === undefined || $checkbox === undefined) { | |
continue; | |
} | |
if (!this.options.multiple) { | |
this.deselectAll(false); | |
} | |
if (this.options.selectedClass) { | |
$checkbox.closest('li') | |
.addClass(this.options.selectedClass); | |
} | |
$checkbox.prop('checked', true); | |
$option.prop('selected', true); | |
if (triggerOnChange) { | |
this.options.onChange($option, true); | |
} | |
} | |
this.updateButtonText(); | |
this.updateSelectAll(); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
}, | |
/** | |
* Clears all selected items. | |
*/ | |
clearSelection: function () { | |
this.deselectAll(false); | |
this.updateButtonText(); | |
this.updateSelectAll(); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
}, | |
/** | |
* Deselects all options of the given values. | |
* | |
* If triggerOnChange is set to true, the on change event is triggered, if | |
* and only if one value is passed. | |
* | |
* @param {Array} deselectValues | |
* @param {Boolean} triggerOnChange | |
*/ | |
deselect: function(deselectValues, triggerOnChange) { | |
if(!$.isArray(deselectValues)) { | |
deselectValues = [deselectValues]; | |
} | |
for (var i = 0; i < deselectValues.length; i++) { | |
var value = deselectValues[i]; | |
if (value === null || value === undefined) { | |
continue; | |
} | |
var $option = this.getOptionByValue(value); | |
var $checkbox = this.getInputByValue(value); | |
if($option === undefined || $checkbox === undefined) { | |
continue; | |
} | |
if (this.options.selectedClass) { | |
$checkbox.closest('li') | |
.removeClass(this.options.selectedClass); | |
} | |
$checkbox.prop('checked', false); | |
$option.prop('selected', false); | |
if (triggerOnChange) { | |
this.options.onChange($option, false); | |
} | |
} | |
this.updateButtonText(); | |
this.updateSelectAll(); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
}, | |
/** | |
* Selects all enabled & visible options. | |
* | |
* If justVisible is true or not specified, only visible options are selected. | |
* | |
* @param {Boolean} justVisible | |
* @param {Boolean} triggerOnSelectAll | |
*/ | |
selectAll: function (justVisible, triggerOnSelectAll) { | |
triggerOnSelectAll = true; | |
var justVisible = typeof justVisible === 'undefined' ? true : justVisible; | |
var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul); | |
var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible'); | |
if(justVisible) { | |
$('input:enabled' , visibleLis).prop('checked', true); | |
visibleLis.addClass(this.options.selectedClass); | |
$('input:enabled' , visibleLis).each($.proxy(function(index, element) { | |
var value = $(element).val(); | |
var option = this.getOptionByValue(value); | |
$(option).prop('selected', true); | |
}, this)); | |
} | |
else { | |
$('input:enabled' , allLis).prop('checked', true); | |
allLis.addClass(this.options.selectedClass); | |
$('input:enabled' , allLis).each($.proxy(function(index, element) { | |
var value = $(element).val(); | |
var option = this.getOptionByValue(value); | |
$(option).prop('selected', true); | |
}, this)); | |
} | |
$('li input[value="' + this.options.selectAllValue + '"]').prop('checked', true); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
if (triggerOnSelectAll) { | |
this.options.onSelectAll(); | |
} | |
}, | |
/** | |
* Deselects all options. | |
* | |
* If justVisible is true or not specified, only visible options are deselected. | |
* | |
* @param {Boolean} justVisible | |
*/ | |
deselectAll: function (justVisible, triggerOnDeselectAll) { | |
triggerOnDeselectAll = true; | |
var justVisible = typeof justVisible === 'undefined' ? true : justVisible; | |
var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul); | |
var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible'); | |
if(justVisible) { | |
$('input[type="checkbox"]:enabled' , visibleLis).prop('checked', false); | |
visibleLis.removeClass(this.options.selectedClass); | |
$('input[type="checkbox"]:enabled' , visibleLis).each($.proxy(function(index, element) { | |
var value = $(element).val(); | |
var option = this.getOptionByValue(value); | |
$(option).prop('selected', false); | |
}, this)); | |
} | |
else { | |
$('input[type="checkbox"]:enabled' , allLis).prop('checked', false); | |
allLis.removeClass(this.options.selectedClass); | |
$('input[type="checkbox"]:enabled' , allLis).each($.proxy(function(index, element) { | |
var value = $(element).val(); | |
var option = this.getOptionByValue(value); | |
$(option).prop('selected', false); | |
}, this)); | |
} | |
$('li input[value="' + this.options.selectAllValue + '"]').prop('checked', false); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
if (triggerOnDeselectAll) { | |
this.options.onDeselectAll(); | |
} | |
}, | |
/** | |
* Rebuild the plugin. | |
* | |
* Rebuilds the dropdown, the filter and the select all option. | |
*/ | |
rebuild: function() { | |
this.$ul.html(''); | |
// Important to distinguish between radios and checkboxes. | |
this.options.multiple = this.$select.attr('multiple') === "multiple"; | |
this.buildSelectAll(); | |
this.buildDropdownOptions(); | |
this.buildFilter(); | |
this.updateButtonText(); | |
this.updateSelectAll(true); | |
if (this.options.enableClickableOptGroups && this.options.multiple) { | |
this.updateOptGroups(); | |
} | |
if (this.options.disableIfEmpty && $('option', this.$select).length <= 0) { | |
this.disable(); | |
} | |
else { | |
this.enable(); | |
} | |
if (this.options.dropRight) { | |
this.$ul.addClass('pull-right'); | |
} | |
}, | |
/** | |
* The provided data will be used to build the dropdown. | |
*/ | |
dataprovider: function(dataprovider) { | |
var groupCounter = 0; | |
var $select = this.$select.empty(); | |
$.each(dataprovider, function (index, option) { | |
var $tag; | |
if ($.isArray(option.children)) { // create optiongroup tag | |
groupCounter++; | |
$tag = $('<optgroup/>').attr({ | |
label: option.label || 'Group ' + groupCounter, | |
disabled: !!option.disabled | |
}); | |
forEach(option.children, function(subOption) { // add children option tags | |
var attributes = { | |
value: subOption.value, | |
label: subOption.label || subOption.value, | |
title: subOption.title, | |
selected: !!subOption.selected, | |
disabled: !!subOption.disabled | |
}; | |
//Loop through attributes object and add key-value for each attribute | |
for (var key in subOption.attributes) { | |
attributes['data-' + key] = subOption.attributes[key]; | |
} | |
//Append original attributes + new data attributes to option | |
$tag.append($('<option/>').attr(attributes)); | |
}); | |
} | |
else { | |
var attributes = { | |
'value': option.value, | |
'label': option.label || option.value, | |
'title': option.title, | |
'class': option.class, | |
'selected': !!option.selected, | |
'disabled': !!option.disabled | |
}; | |
//Loop through attributes object and add key-value for each attribute | |
for (var key in option.attributes) { | |
attributes['data-' + key] = option.attributes[key]; | |
} | |
//Append original attributes + new data attributes to option | |
$tag = $('<option/>').attr(attributes); | |
$tag.text(option.label || option.value); | |
} | |
$select.append($tag); | |
}); | |
this.rebuild(); | |
}, | |
/** | |
* Enable the multiselect. | |
*/ | |
enable: function() { | |
this.$select.prop('disabled', false); | |
this.$button.prop('disabled', false) | |
.removeClass('disabled'); | |
}, | |
/** | |
* Disable the multiselect. | |
*/ | |
disable: function() { | |
this.$select.prop('disabled', true); | |
this.$button.prop('disabled', true) | |
.addClass('disabled'); | |
}, | |
/** | |
* Set the options. | |
* | |
* @param {Array} options | |
*/ | |
setOptions: function(options) { | |
this.options = this.mergeOptions(options); | |
}, | |
/** | |
* Merges the given options with the default options. | |
* | |
* @param {Array} options | |
* @returns {Array} | |
*/ | |
mergeOptions: function(options) { | |
return $.extend(true, {}, this.defaults, this.options, options); | |
}, | |
/** | |
* Checks whether a select all checkbox is present. | |
* | |
* @returns {Boolean} | |
*/ | |
hasSelectAll: function() { | |
return $('li.multiselect-all', this.$ul).length > 0; | |
}, | |
/** | |
* Update opt groups. | |
*/ | |
updateOptGroups: function() { | |
var $groups = $('li.multiselect-group', this.$ul) | |
$groups.each(function() { | |
var $options = $(this).nextUntil('li.multiselect-group') | |
.not('.multiselect-filter-hidden') | |
.not('.disabled'); | |
var checked = true; | |
$options.each(function() { | |
var $input = $('input', this); | |
if (!$input.prop('checked')) { | |
checked = false; | |
} | |
}); | |
$('input', this).prop('checked', checked); | |
}); | |
}, | |
/** | |
* Updates the select all checkbox based on the currently displayed and selected checkboxes. | |
*/ | |
updateSelectAll: function(notTriggerOnSelectAll) { | |
if (this.hasSelectAll()) { | |
var allBoxes = $("li:not(.multiselect-item):not(.multiselect-filter-hidden):not(.multiselect-group):not(.disabled) input:enabled", this.$ul); | |
var allBoxesLength = allBoxes.length; | |
var checkedBoxesLength = allBoxes.filter(":checked").length; | |
var selectAllLi = $("li.multiselect-all", this.$ul); | |
var selectAllInput = selectAllLi.find("input"); | |
if (checkedBoxesLength > 0 && checkedBoxesLength === allBoxesLength) { | |
selectAllInput.prop("checked", true); | |
selectAllLi.addClass(this.options.selectedClass); | |
this.options.onSelectAll(); | |
} | |
else { | |
selectAllInput.prop("checked", false); | |
selectAllLi.removeClass(this.options.selectedClass); | |
if (checkedBoxesLength === 0) { | |
if (!notTriggerOnSelectAll) { | |
this.options.onDeselectAll(); | |
} | |
} | |
} | |
} | |
}, | |
/** | |
* Update the button text and its title based on the currently selected options. | |
*/ | |
updateButtonText: function() { | |
var options = this.getSelected(); | |
// First update the displayed button text. | |
if (this.options.enableHTML) { | |
$('.multiselect .multiselect-selected-text', this.$container).html(this.options.buttonText(options, this.$select)); | |
} | |
else { | |
$('.multiselect .multiselect-selected-text', this.$container).text(this.options.buttonText(options, this.$select)); | |
} | |
// Now update the title attribute of the button. | |
$('.multiselect', this.$container).attr('title', this.options.buttonTitle(options, this.$select)); | |
}, | |
/** | |
* Get all selected options. | |
* | |
* @returns {jQUery} | |
*/ | |
getSelected: function() { | |
return $('option', this.$select).filter(":selected"); | |
}, | |
/** | |
* Gets a select option by its value. | |
* | |
* @param {String} value | |
* @returns {jQuery} | |
*/ | |
getOptionByValue: function (value) { | |
var options = $('option', this.$select); | |
var valueToCompare = value.toString(); | |
for (var i = 0; i < options.length; i = i + 1) { | |
var option = options[i]; | |
if (option.value === valueToCompare) { | |
return $(option); | |
} | |
} | |
}, | |
/** | |
* Get the input (radio/checkbox) by its value. | |
* | |
* @param {String} value | |
* @returns {jQuery} | |
*/ | |
getInputByValue: function (value) { | |
var checkboxes = $('li input', this.$ul); | |
var valueToCompare = value.toString(); | |
for (var i = 0; i < checkboxes.length; i = i + 1) { | |
var checkbox = checkboxes[i]; | |
if (checkbox.value === valueToCompare) { | |
return $(checkbox); | |
} | |
} | |
}, | |
/** | |
* Used for knockout integration. | |
*/ | |
updateOriginalOptions: function() { | |
this.originalOptions = this.$select.clone()[0].options; | |
}, | |
asyncFunction: function(callback, timeout, self) { | |
var args = Array.prototype.slice.call(arguments, 3); | |
return setTimeout(function() { | |
callback.apply(self || window, args); | |
}, timeout); | |
}, | |
setAllSelectedText: function(allSelectedText) { | |
this.options.allSelectedText = allSelectedText; | |
this.updateButtonText(); | |
} | |
}; | |
$.fn.multiselect = function(option, parameter, extraOptions) { | |
return this.each(function() { | |
var data = $(this).data('multiselect'); | |
var options = typeof option === 'object' && option; | |
// Initialize the multiselect. | |
if (!data) { | |
data = new Multiselect(this, options); | |
$(this).data('multiselect', data); | |
} | |
// Call multiselect method. | |
if (typeof option === 'string') { | |
data[option](parameter, extraOptions); | |
if (option === 'destroy') { | |
$(this).data('multiselect', false); | |
} | |
} | |
}); | |
}; | |
$.fn.multiselect.Constructor = Multiselect; | |
$(function() { | |
$("select[data-role=multiselect]").multiselect(); | |
}); | |
}(window.jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* Bootstrap v3.3.6 (http://getbootstrap.com) | |
* Copyright 2011-2015 Twitter, Inc. | |
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) | |
*//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(glyphicons-halflings-regular.woff2) format('woff2'),url(glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control: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)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control: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}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control: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-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control: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-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} | |
/*# sourceMappingURL=bootstrap.min.css.map */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* Bootstrap v3.3.6 (http://getbootstrap.com) | |
* Copyright 2011-2015 Twitter, Inc. | |
* Licensed under the MIT license | |
*/ | |
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&j<i.length-1&&j++,~j||(j=0),i.eq(j).trigger("focus")}}}};var h=a.fn.dropdown;a.fn.dropdown=d,a.fn.dropdown.Constructor=g,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=h,this},a(document).on("click.bs.dropdown.data-api",c).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",f,g.prototype.toggle).on("keydown.bs.dropdown.data-api",f,g.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",g.prototype.keydown)}(jQuery),+function(a){"use strict";function b(b,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},c.DEFAULTS,e.data(),"object"==typeof b&&b);f||e.data("bs.modal",f=new c(this,g)),"string"==typeof b?f[b](d):g.show&&f.show(d)})}var c=function(b,c){this.options=c,this.$body=a(document.body),this.$element=a(b),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=300,c.BACKDROP_TRANSITION_DURATION=150,c.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},c.prototype.toggle=function(a){return this.isShown?this.hide():this.show(a)},c.prototype.show=function(b){var d=this,e=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(e),this.isShown||e.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){d.$element.one("mouseup.dismiss.bs.modal",function(b){a(b.target).is(d.$element)&&(d.ignoreBackdropClick=!0)})}),this.backdrop(function(){var e=a.support.transition&&d.$element.hasClass("fade");d.$element.parent().length||d.$element.appendTo(d.$body),d.$element.show().scrollTop(0),d.adjustDialog(),e&&d.$element[0].offsetWidth,d.$element.addClass("in"),d.enforceFocus();var f=a.Event("shown.bs.modal",{relatedTarget:b});e?d.$dialog.one("bsTransitionEnd",function(){d.$element.trigger("focus").trigger(f)}).emulateTransitionEnd(c.TRANSITION_DURATION):d.$element.trigger("focus").trigger(f)}))},c.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b),this.isShown&&!b.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(c.TRANSITION_DURATION):this.hideModal())},c.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]===a.target||this.$element.has(a.target).length||this.$element.trigger("focus")},this))},c.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(a){27==a.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},c.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},c.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.$body.removeClass("modal-open"),a.resetAdjustments(),a.resetScrollbar(),a.$element.trigger("hidden.bs.modal")})},c.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},c.prototype.backdrop=function(b){var d=this,e=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var f=a.support.transition&&e;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+e).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(a){return this.ignoreBackdropClick?void(this.ignoreBackdropClick=!1):void(a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide()))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.adjustDialog()},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth<a,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"",this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad)},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",a,b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m<o.top?"bottom":"right"==h&&k.right+l>o.width?"left":"left"==h&&k.left-l<o.left?"right":h,f.removeClass(n).addClass(h)}var p=this.getCalculatedOffset(h,k,l,m);this.applyPlacement(p,h);var q=function(){var a=e.hoverState;e.$element.trigger("shown.bs."+e.type),e.hoverState=null,"out"==a&&e.leave(e)};a.support.transition&&this.$tip.hasClass("fade")?f.one("bsTransitionEnd",q).emulateTransitionEnd(c.TRANSITION_DURATION):q()}},c.prototype.applyPlacement=function(b,c){var d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),b.top+=g,b.left+=h,a.offset.setOffset(d[0],a.extend({using:function(a){d.css({top:Math.round(a.top),left:Math.round(a.left)})}},b),0),d.addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;"top"==c&&j!=f&&(b.top=b.top+f-j);var k=this.getViewportAdjustedDelta(c,b,i,j);k.left?b.left+=k.left:b.top+=k.top;var l=/top|bottom/.test(c),m=l?2*k.left-e+i:2*k.top-f+j,n=l?"offsetWidth":"offsetHeight";d.offset(b),this.replaceArrow(m,d[0][n],l)},c.prototype.replaceArrow=function(a,b,c){this.arrow().css(c?"left":"top",50*(1-a/b)+"%").css(c?"top":"left","")},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},c.prototype.hide=function(b){function d(){"in"!=e.hoverState&&f.detach(),e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),b&&b()}var e=this,f=a(this.$tip),g=a.Event("hide.bs."+this.type);return this.$element.trigger(g),g.isDefaultPrevented()?void 0:(f.removeClass("in"),a.support.transition&&f.hasClass("fade")?f.one("bsTransitionEnd",d).emulateTransitionEnd(c.TRANSITION_DURATION):d(),this.hoverState=null,this)},c.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||"string"!=typeof a.attr("data-original-title"))&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},c.prototype.hasContent=function(){return this.getTitle()},c.prototype.getPosition=function(b){b=b||this.$element;var c=b[0],d="BODY"==c.tagName,e=c.getBoundingClientRect();null==e.width&&(e=a.extend({},e,{width:e.right-e.left,height:e.bottom-e.top}));var f=d?{top:0,left:0}:b.offset(),g={scroll:d?document.documentElement.scrollTop||document.body.scrollTop:b.scrollTop()},h=d?{width:a(window).width(),height:a(window).height()}:null;return a.extend({},e,g,h,f)},c.prototype.getCalculatedOffset=function(a,b,c,d){return"bottom"==a?{top:b.top+b.height,left:b.left+b.width/2-c/2}:"top"==a?{top:b.top-d,left:b.left+b.width/2-c/2}:"left"==a?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},c.prototype.getViewportAdjustedDelta=function(a,b,c,d){var e={top:0,left:0};if(!this.$viewport)return e;var f=this.options.viewport&&this.options.viewport.padding||0,g=this.getPosition(this.$viewport);if(/right|left/.test(a)){var h=b.top-f-g.scroll,i=b.top+f-g.scroll+d;h<g.top?e.top=g.top-h:i>g.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;j<g.left?e.left=g.left-j:k>g.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b<e[0])return this.activeTarget=null,this.clear();for(a=e.length;a--;)g!=f[a]&&b>=e[a]&&(void 0===e[a+1]||b<e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active"); | |
d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.6",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# make a function global | |
window.global = (f) -> window[f.name] = f | |
# object able to trigger events | |
global class EventSource | |
# instantiate a new EventSource with the given event types | |
constructor: (config) -> | |
@_dispatcher = d3.dispatch(config.events...) | |
# register a callback on the given event type, with an optional namespace | |
# syntax: event_type.namespace | |
on: (event_type_ns, callback) -> | |
@_dispatcher.on event_type_ns, callback | |
return this | |
# trigger an event of the given type and pass the given args | |
trigger: (event_type, args...) -> | |
@_dispatcher[event_type](args...) | |
return this | |
# GUI component | |
global class View | |
constructor: (conf) -> | |
# div is default | |
if not conf.tag? | |
conf.tag = 'div' | |
# both DOM and d3 element references | |
@el = document.createElement(conf.tag) | |
@d3el = d3.select(@el) | |
# set a CSS class equal to the class name of the view | |
# WARNING this is not supported on IE | |
# if needed, this polyfill can be used: | |
# https://github.com/JamesMGreene/Function.name | |
@d3el.classed this.constructor.name, true | |
# automatically append this view to the given parent, if any | |
if conf.parent? | |
@append_to(conf.parent) | |
# append this view to a parent view or node | |
append_to: (parent) -> | |
if parent.el? # Backbone-style view | |
p_el = parent.el | |
else # selector or d3 selection or dom node | |
p_el = d3.select(parent).node() | |
p_el.appendChild @el | |
# listen to an event source | |
listen_to: (es, event, cb) -> | |
# WARNING this is not supported on IE | |
# if needed, this polyfill can be used: | |
# https://github.com/JamesMGreene/Function.name | |
es.on event + '.' + this.constructor.name, cb | |
# recompute width and height | |
recompute_size: () -> | |
@width = @el.getBoundingClientRect().width | |
@height = @el.getBoundingClientRect().height | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.10.0 | |
(function() { | |
var EventSource, View, | |
slice = [].slice; | |
window.global = function(f) { | |
return window[f.name] = f; | |
}; | |
global(EventSource = (function() { | |
function EventSource(config) { | |
this._dispatcher = d3.dispatch.apply(d3, config.events); | |
} | |
EventSource.prototype.on = function(event_type_ns, callback) { | |
this._dispatcher.on(event_type_ns, callback); | |
return this; | |
}; | |
EventSource.prototype.trigger = function() { | |
var args, event_type, ref; | |
event_type = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : []; | |
(ref = this._dispatcher)[event_type].apply(ref, args); | |
return this; | |
}; | |
return EventSource; | |
})()); | |
global(View = (function() { | |
function View(conf) { | |
if (conf.tag == null) { | |
conf.tag = 'div'; | |
} | |
this.el = document.createElement(conf.tag); | |
this.d3el = d3.select(this.el); | |
this.d3el.classed(this.constructor.name, true); | |
if (conf.parent != null) { | |
this.append_to(conf.parent); | |
} | |
} | |
View.prototype.append_to = function(parent) { | |
var p_el; | |
if (parent.el != null) { | |
p_el = parent.el; | |
} else { | |
p_el = d3.select(parent).node(); | |
} | |
return p_el.appendChild(this.el); | |
}; | |
View.prototype.listen_to = function(es, event, cb) { | |
return es.on(event + '.' + this.constructor.name, cb); | |
}; | |
View.prototype.recompute_size = function() { | |
this.width = this.el.getBoundingClientRect().width; | |
return this.height = this.el.getBoundingClientRect().height; | |
}; | |
return View; | |
})()); | |
}).call(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
new AppView | |
parent: 'body' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
svg = d3.select('svg') | |
width = svg.node().getBoundingClientRect().width | |
height = svg.node().getBoundingClientRect().height | |
# append a group for zoomable content | |
zoomable_layer = svg.append('g') | |
# define a zoom behavior | |
zoom = d3.behavior.zoom() | |
.scaleExtent([0.3,4]) | |
.on 'zoom', () -> | |
zoomable_layer | |
.attr | |
transform: "translate(#{zoom.translate()})scale(#{zoom.scale()})" | |
svg.call(zoom) | |
simcolor = d3.scale.linear() | |
.domain([0,1]) | |
.range([d3.hcl(20,0,100),d3.hcl(20,75,25)]) | |
.interpolate(d3.interpolateHcl) | |
matrix = zoomable_layer.append('g') | |
.attr('transform', 'translate(125,170)scale(0.4)') | |
SIZE = 13 | |
d3.json 'poetq.json', (data) -> | |
items = [] | |
predicates_data = [] | |
instances_data = [] | |
data.forEach (e1) -> | |
vector = [] | |
instances_data.push e1.k1 | |
e1.similarities.forEach (e2) -> | |
vector.push e2.sim | |
if e2.k2 not in predicates_data | |
predicates_data.push e2.k2 | |
items.push vector | |
console.debug 'Computing hierarchical clustering...' | |
clusters = clusterfck.hcluster( | |
items, | |
clusterfck.EUCLIDEAN_DISTANCE, | |
clusterfck.SINGLE_LINKAGE | |
) | |
tree = tree_utils.binary_to_std(clusters) | |
matrix_data = tree_utils.get_leaves(tree).map (d) -> d.value | |
# COLUMNS | |
mouseover = () -> | |
d3.select(this) | |
.style | |
opacity: 0.8 | |
mouseout = () -> | |
d3.select(this) | |
.style | |
opacity: 1 | |
columns = matrix.selectAll('.column') | |
.data(matrix_data) | |
enter_columns = columns.enter().append('g') | |
.attr('class', 'column') | |
.attr('transform', (d,i) -> "translate(#{SIZE*i},0)") | |
.on('mouseover', mouseover) | |
.on('mouseout', mouseout) | |
# CELLS | |
cells = columns.selectAll('.cell') | |
.data((column) -> column) | |
cells.enter().append('rect') | |
.attr('class', 'cell') | |
.attr('width', SIZE) | |
.attr('height', SIZE) | |
.attr('transform', (d, i) -> "translate(0,#{SIZE*i})") | |
.attr('fill', (d) -> if d is 0 then 'gray' else 'black') | |
matrix.append('rect') | |
.attr('class','border') | |
.attr('x', -1) | |
.attr('y', -1) | |
.attr('width', SIZE*matrix_data.length+2) | |
.attr('height', SIZE*predicates_data.length+2) | |
# HORIZONTAL LABELS | |
hlabels = matrix.selectAll('.hlabel') | |
.data(predicates_data) | |
hlabels.enter().append('a') | |
.attr('xlink:href', (d) -> d.k1) | |
.append('text') | |
.attr('class','hlabel') | |
.text((d) -> d) | |
.attr('transform', (d,i) -> "translate(0,#{SIZE*i})") | |
.attr('dy', '1em') | |
.attr('dx', -6) | |
# VERTICAL LABELS | |
vlabels = matrix.selectAll('.vlabel') | |
.data(instances_data) | |
vlabels.enter().append('a') | |
.attr('xlink:href', (d) -> d.k1) | |
.append('text') | |
.attr('class','vlabel') | |
.text((d) -> d.replace('http://dbpedia.org/resource/','')) | |
.attr('transform', (d,i) -> "translate(#{SIZE*i},0) rotate(-90)") | |
.attr('dy', '1em') | |
.attr('dx', 6) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
padding: 0; | |
margin: 0; | |
width: 100%; | |
height: 100%; | |
} | |
svg { | |
width: 100%; | |
height: 100%; | |
background: white; | |
} | |
.multiselect-container { | |
position: absolute; | |
top: 100px; | |
left: 10px; | |
font-family: sans-serif; | |
max-width: 300px; | |
} | |
.multiselect-container>li>a { | |
white-space: normal !important; | |
} | |
.x_label, .y_label { | |
font-family: sans-serif; | |
font-size: 1px; | |
cursor: pointer; | |
} | |
.x_label { | |
text-anchor: start; | |
} | |
.y_label { | |
text-anchor: end; | |
} | |
.cell, .x_label, .y_label { | |
fill: #BBB; | |
} | |
.selected { | |
fill: black; | |
} | |
.filter_box { | |
position: absolute; | |
top: 10px; | |
left: 10px; | |
font-family: sans-serif; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>DIITET matrix menu filtering</title> | |
<link type="text/css" href="index.css" rel="stylesheet"/> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<!-- Include Twitter Bootstrap and jQuery: --> | |
<script type="text/javascript" src="jquery.min.js"></script> | |
<link rel="stylesheet" href="bootstrap.min.css" type="text/css"/> | |
<script type="text/javascript" src="bootstrap.min.js"></script> | |
<!-- Include the multiselect plugin's CSS and JS: --> | |
<script type="text/javascript" src="bootstrap-multiselect.js"></script> | |
<link rel="stylesheet" href="bootstrap-multiselect.css" type="text/css"/> | |
<script src="esv.js"></script> | |
<script src="Bigraph.js"></script> | |
<script src="AppView.js"></script> | |
<link type="text/css" href="AppView.css" rel="stylesheet"/> | |
<script src="SelectionControls.js"></script> | |
<link type="text/css" href="SelectionControls.css" rel="stylesheet"/> | |
<script src="Matrix.js"></script> | |
<link type="text/css" href="Matrix.css" rel="stylesheet"/> | |
</head> | |
<body> | |
<script src="index.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.10.0 | |
(function() { | |
new AppView({ | |
parent: 'body' | |
}); | |
}).call(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id | istituto | ist_sigla | dipartimento_id | dipartimento | dip_sigla | |
---|---|---|---|---|---|---|
1 | Istituto di Informatica e Telematica | IIT | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
2 | Istituto di Scienze e Tecnologie Informatiche | ISTI | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
6 | Istituto Nazionale per Studi ed Esperienze di Architettura Navale | INSEAN | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
28 | Istituto di Fisica del Plasma Piero Caldirola | IFP | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
29 | Istituto Gas Ionizzati | IGI | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
31 | Istituto di Ricerche sulla Combustione | IRC | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
32 | Istituto di Tecnologie Avanzate per l'Energia Nicola Giordano | ITAE | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
33 | Istituto Motori | IM | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
80 | Istituto di Fisica Applicata Nello Carrara | IFAC | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
84 | Istituto dei Materiali per l'Elettronica ed il Magnetismo | IMEM | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
85 | Istituto di Studi sui Sistemi Intelligenti per l'Automazione | ISSIA | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
86 | Istituto per le Macchine Agricole e Movimento Terra | IMAMOTER | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
87 | Istituto di Tecnologie Industriali e Automazione | ITIA | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
88 | Istituto per le Tecnologie della Costruzione | ITC | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
89 | Istituto di Acustica e Sensoristica Orso Mario Corbino | IDASC | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
90 | Istituto per il Rilevamento Elettromagnetico dell'Ambiente | IREA | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
91 | Istituto di Elettronica e di Ingegneria dell'Informazione e delle Telecomunicazioni | IEIIT | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
92 | Istituto di Calcolo e Reti ad Alte Prestazioni | ICAR | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
93 | Istituto per le Applicazioni del Calcolo Mauro Picone | IAC | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
94 | Istituto di Analisi dei Sistemi ed Informatica Antonio Ruberti | IASI | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
95 | Istituto di Matematica Applicata e Tecnologie Informatiche | IMATI | 1 | Dipartimento Ingegneria, ICT e Tecnologie per l'Energia e i Trasporti | DIITET | |
72 | Istituto Officina dei Materiali | IOM | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
73 | Istituto Superconduttori, Materiali innovativi e dispositivi | SPIN | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
74 | Istituto di Nanoscienze | NANO | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
75 | Istituto Nazionale di Ottica | INO | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
76 | Istituto di Struttura della Materia | ISM | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
77 | Istituto dei Sistemi Complessi | ISC | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
78 | Istituto di Biofisica | IBF | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
79 | Istituto di Scienze Applicate e Sistemi Intelligenti Eduardo Caianiello | ISASI | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
81 | Istituto di Nanotecnologia | NANOTEC | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
82 | Istituto di Fotonica e Nanotecnologie | IFN | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
83 | Istituto per la Microelettronica e Microsistemi | IMM | 2 | Dipartimento di Scienze Fisiche e Tecnologie della Materia | DSFTM | |
58 | Istituto per la Tecnologia delle Membrane | ITM | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
59 | Istituto per lo Studio dei Materiali Nanostrutturati | ISMN | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
60 | Istituto di Metodologie Chimiche | IMC | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
61 | Istituto per lo Studio delle Macromolecole | ISMAC | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
62 | Istituto per i Polimeri, Compositi e Biomateriali | IPCB | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
63 | Istituto di Scienze e Tecnologie Molecolari | ISTM | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
64 | Istituto per i Processi Chimico-Fisici | IPCF | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
65 | Istituto di Chimica Biomolecolare | ICB | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
66 | Istituto di Chimica dei Composti Organo Metallici | ICCOm | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
67 | Istituto per la Sintesi Organica e la Fotoreattività | ISOF | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
68 | Istituto di Scienza e Tecnologia dei Materiali Ceramici | ISTEC | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
69 | Istituto di Chimica del Riconoscimento Molecolare | ICRM | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
70 | Istituto di Cristallografia | IC | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
71 | Istituto per l'Energetica e le Interfasi | IENI | 3 | Dipartimento di Scienze Chimiche e Tecnologie dei Materiali | DSCTM | |
15 | Istituto di Ricerca per la Protezione Idrogeologica | IRPI | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
16 | Istituto di Geologia Ambientale e Geoingegneria | IGAG | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
19 | Istituto di Scienze Marine | ISMAR | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
20 | Istituto di Ricerca sulle Acque | IRSA | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
21 | Istituto sull'Inquinamento Atmosferico | IIA | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
22 | Istituto di Scienze dell'Atmosfera e del Clima | ISAC | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
23 | Istituto di Metodologie per l'Analisi Ambientale | IMAA | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
24 | Istituto per l'Ambiente Marino | IAMC | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
25 | Istituto per la Dinamica dei Processi Ambientali | IDPA | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
26 | Istituto di Geoscienze e Georisorse | IGG | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
27 | Istituto di Biologia Agro-Ambientale e Forestale | IBAF | 4 | Dipartimento di Scienze del Sistema Terra e Tecnologie per l'Ambiente | DTA | |
34 | Istituto per il sistema produzione animale in ambiente Mediterraneo | ISPAAM | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
35 | Istituto di Biologia e Biotecnologia Agraria | IBBA | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
36 | Istituto di Biometeorologia | IBIMET | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
37 | Istituto per i Sistemi Agricoli e Forestali del Mediterraneo | ISAFoM | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
38 | Istituto per la Protezione Sostenibile delle Piante | IPSP | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
39 | Istituto di Bioscienze e Biorisorse | IBBR | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
40 | Istituto di Scienze delle Produzioni Alimentari | ISPA | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
41 | Istituto per la Valorizzazione del Legno e delle Specie Arboree | IVALSA | 5 | Dipartimento di Scienze Bio-Agroalimentari | DISBA | |
42 | Istituto di Biostrutture e Bioimmagini | IBB | 6 | Dipartimento di Scienze Biomediche | DSB | |
43 | Istituto di Scienze Neurologiche | ISN | 6 | Dipartimento di Scienze Biomediche | DSB | |
44 | Istituto di Farmacologia Traslazionale | IFT | 6 | Dipartimento di Scienze Biomediche | DSB | |
45 | Istituto di Bioimmagini e Fisiologia Molecolare | IBFM | 6 | Dipartimento di Scienze Biomediche | DSB | |
46 | Istituto di Genetica Molecolare | IGM | 6 | Dipartimento di Scienze Biomediche | DSB | |
47 | Istituto di Tecnologie Biomediche | ITB | 6 | Dipartimento di Scienze Biomediche | DSB | |
48 | Istituto di Biomedicina e di Immunologia Molecolare Alberto Monroy | IBIM | 6 | Dipartimento di Scienze Biomediche | DSB | |
49 | Istituto di Fisiologia Clinica | IFC | 6 | Dipartimento di Scienze Biomediche | DSB | |
50 | Istituto di Neuroscienze | IN | 6 | Dipartimento di Scienze Biomediche | DSB | |
51 | Istituto di Ricerca Genetica e Biomedica | IRGB | 6 | Dipartimento di Scienze Biomediche | DSB | |
52 | Istituto di Biochimica delle Proteine | IBP | 6 | Dipartimento di Scienze Biomediche | DSB | |
53 | Istituto di Genetica e Biofisica Adriano Buzzati Traverso | IGB | 6 | Dipartimento di Scienze Biomediche | DSB | |
54 | istituto di Biologia Cellulare e Neurobiologia | IBCN | 6 | Dipartimento di Scienze Biomediche | DSB | |
55 | Istituto di Biologia e Patologia Molecolari | IBPM | 6 | Dipartimento di Scienze Biomediche | DSB | |
56 | Istituto per l'Endocrinologia e l'Oncologia Gaetano Salvatore | IEOS | 6 | Dipartimento di Scienze Biomediche | DSB | |
57 | Istituto di Biomembrane e Bioenergetica | IBBE | 6 | Dipartimento di Scienze Biomediche | DSB | |
96 | Istituto di Studi sul Mediterraneo Antico | ISMA | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
97 | Centro di Responsabilità di Attività Scientifica | IDAIC | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
98 | Istituto per i Beni Archeologici e Monumentali | IBAM | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
99 | Istituto per le Tecnologie Applicate ai Beni Culturali | ITABC | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
100 | Istituto per la Conservazione e Valorizzazione dei Beni Culturali | ICVBC | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
101 | Istituto di Scienze e Tecnologie della Cognizione | ISTC | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
102 | Istituto per le Tecnologie Didattiche | ITD | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
103 | Istituto di Studi Giuridici Internazionali | ISGI | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
104 | Istituto di Opera del Vocabolario Italiano | OVI | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
105 | Istituto di Teoria e Tecniche dell'Informazione Giuridica | ITTIG | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
106 | Istituto di Linguistica Computazionale Antonio Zampolli | ILC | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
107 | Istituto di Studi sulle Società del Mediterraneo | ISSM | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
108 | Istituto di Ricerca su Innovazione e Servizi per lo Sviluppo | IRISS | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
109 | Istituto di Storia dell'Europa Mediterranea | ISEM | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
110 | Istituto di Studi sui Sistemi Regionali Federali e sulle Autonomie Massimo Severo Giannini | ISSIRFA | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
111 | Istituto di Ricerche sulla Popolazione e le Politiche Sociali | IRPPS | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
112 | Istituto di Ricerca sui Sistemi Giudiziari | IRSIG | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
113 | Istituto per il Lessico Intellettuale Europeo e Storia delle Idee | ILIESI | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
114 | Istituto per la Storia del Pensiero Filosofico e Scientifico Moderno | ISPF | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU | |
115 | Istituto di Ricerca sulla Crescita Economica Sostenibile | IRCRES | 7 | Dipartimento di Scienze Umane e Sociali - Patrimonio Culturale | DSU |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
id | istituto_id | tema_id | |
---|---|---|---|
37 | 1 | 28 | |
38 | 85 | 28 | |
39 | 94 | 28 | |
40 | 33 | 28 | |
41 | 91 | 28 | |
42 | 2 | 29 | |
43 | 31 | 30 | |
44 | 31 | 31 | |
45 | 33 | 31 | |
46 | 1 | 31 | |
47 | 2 | 32 | |
48 | 94 | 33 | |
49 | 94 | 34 | |
51 | 91 | 31 | |
52 | 95 | 36 | |
53 | 29 | 41 | |
54 | 28 | 42 | |
55 | 28 | 43 | |
56 | 29 | 43 | |
57 | 29 | 44 | |
58 | 85 | 47 | |
59 | 93 | 47 | |
60 | 80 | 47 | |
61 | 89 | 47 | |
62 | 90 | 47 | |
63 | 92 | 47 | |
64 | 2 | 47 | |
65 | 88 | 47 | |
66 | 91 | 48 | |
67 | 80 | 48 | |
68 | 93 | 48 | |
69 | 94 | 48 | |
70 | 65 | 48 | |
71 | 92 | 48 | |
72 | 85 | 48 | |
73 | 95 | 48 | |
74 | 2 | 48 | |
75 | 88 | 48 | |
76 | 80 | 49 | |
77 | 94 | 49 | |
78 | 85 | 49 | |
79 | 90 | 49 | |
80 | 95 | 49 | |
81 | 93 | 28 | |
82 | 2 | 28 | |
83 | 32 | 28 | |
84 | 92 | 29 | |
85 | 89 | 29 | |
86 | 32 | 29 | |
87 | 93 | 30 | |
88 | 2 | 30 | |
89 | 89 | 30 | |
90 | 32 | 31 | |
91 | 85 | 31 | |
92 | 2 | 31 | |
93 | 1 | 32 | |
94 | 92 | 32 | |
95 | 90 | 32 | |
96 | 2 | 33 | |
97 | 92 | 33 | |
98 | 91 | 34 | |
99 | 90 | 34 | |
100 | 2 | 34 | |
101 | 94 | 35 | |
102 | 93 | 35 | |
103 | 85 | 35 | |
104 | 1 | 35 | |
105 | 2 | 35 | |
106 | 94 | 38 | |
107 | 1 | 38 | |
108 | 93 | 39 | |
109 | 95 | 39 | |
110 | 33 | 39 | |
111 | 94 | 37 | |
112 | 91 | 37 | |
113 | 94 | 36 | |
114 | 93 | 36 | |
115 | 1 | 36 | |
116 | 92 | 36 | |
117 | 6 | 36 | |
118 | 2 | 36 | |
128 | 6 | 50 | |
129 | 89 | 50 | |
130 | 90 | 50 | |
131 | 31 | 50 | |
132 | 32 | 50 | |
133 | 2 | 50 | |
134 | 85 | 51 | |
135 | 6 | 51 | |
136 | 2 | 51 | |
137 | 90 | 51 | |
138 | 32 | 52 | |
139 | 33 | 52 | |
140 | 90 | 53 | |
141 | 6 | 53 | |
142 | 92 | 54 | |
143 | 93 | 55 | |
144 | 1 | 55 | |
145 | 95 | 55 | |
146 | 94 | 55 | |
147 | 85 | 55 | |
148 | 92 | 55 | |
149 | 31 | 56 | |
150 | 91 | 57 | |
151 | 93 | 57 | |
152 | 95 | 57 | |
153 | 94 | 57 | |
154 | 80 | 58 | |
155 | 90 | 58 | |
157 | 89 | 60 | |
158 | 91 | 60 | |
159 | 89 | 59 | |
160 | 2 | 60 | |
161 | 91 | 59 | |
162 | 84 | 60 | |
163 | 28 | 59 | |
164 | 90 | 59 | |
165 | 92 | 61 | |
166 | 91 | 61 | |
167 | 80 | 61 | |
168 | 1 | 61 | |
169 | 85 | 61 | |
170 | 2 | 61 | |
171 | 88 | 61 | |
172 | 87 | 61 | |
173 | 94 | 62 | |
174 | 92 | 62 | |
175 | 91 | 62 | |
176 | 1 | 62 | |
177 | 80 | 62 | |
178 | 2 | 62 | |
179 | 93 | 63 | |
180 | 94 | 63 | |
181 | 92 | 63 | |
182 | 91 | 63 | |
183 | 1 | 63 | |
184 | 85 | 63 | |
185 | 95 | 63 | |
186 | 2 | 63 | |
187 | 88 | 63 | |
188 | 87 | 63 | |
189 | 93 | 64 | |
190 | 91 | 64 | |
191 | 80 | 64 | |
192 | 95 | 64 | |
193 | 84 | 64 | |
194 | 90 | 64 | |
195 | 91 | 65 | |
196 | 80 | 65 | |
197 | 84 | 65 | |
198 | 90 | 65 | |
199 | 95 | 66 | |
200 | 87 | 66 | |
201 | 80 | 67 | |
202 | 85 | 67 | |
203 | 87 | 67 | |
204 | 101 | 67 | |
205 | 94 | 68 | |
206 | 95 | 68 | |
207 | 85 | 68 | |
208 | 87 | 68 | |
209 | 91 | 69 | |
210 | 94 | 69 | |
211 | 85 | 69 | |
212 | 94 | 70 | |
213 | 85 | 70 | |
214 | 2 | 70 | |
215 | 87 | 70 | |
216 | 92 | 67 | |
217 | 94 | 71 | |
218 | 91 | 71 | |
219 | 84 | 71 | |
220 | 85 | 71 | |
221 | 87 | 71 | |
222 | 93 | 72 | |
223 | 32 | 72 | |
224 | 91 | 72 | |
225 | 80 | 72 | |
226 | 84 | 72 | |
227 | 2 | 72 | |
228 | 6 | 72 | |
229 | 80 | 73 | |
230 | 93 | 73 | |
231 | 84 | 73 | |
232 | 90 | 73 | |
233 | 85 | 73 | |
234 | 93 | 74 | |
235 | 94 | 74 | |
236 | 80 | 74 | |
237 | 90 | 74 | |
238 | 85 | 74 | |
239 | 94 | 75 | |
240 | 93 | 75 | |
241 | 80 | 75 | |
242 | 90 | 75 | |
243 | 87 | 75 | |
244 | 85 | 75 | |
245 | 91 | 76 | |
246 | 6 | 76 | |
247 | 87 | 76 | |
248 | 32 | 76 | |
249 | 90 | 76 | |
250 | 2 | 76 | |
251 | 91 | 77 | |
252 | 84 | 77 | |
253 | 80 | 77 | |
254 | 90 | 77 | |
255 | 91 | 78 | |
256 | 2 | 78 | |
257 | 1 | 78 | |
258 | 86 | 78 | |
259 | 85 | 78 | |
260 | 92 | 79 | |
261 | 93 | 79 | |
262 | 2 | 79 | |
263 | 95 | 79 | |
264 | 1 | 79 | |
265 | 94 | 80 | |
266 | 2 | 80 | |
275 | 89 | 82 | |
276 | 91 | 82 | |
277 | 90 | 82 | |
278 | 84 | 82 | |
279 | 85 | 82 | |
280 | 95 | 83 | |
281 | 90 | 83 | |
282 | 85 | 83 | |
283 | 91 | 84 | |
284 | 80 | 84 | |
285 | 95 | 84 | |
286 | 90 | 84 | |
287 | 89 | 85 | |
288 | 80 | 85 | |
289 | 1 | 85 | |
290 | 95 | 85 | |
291 | 84 | 85 | |
292 | 90 | 85 | |
293 | 85 | 85 | |
294 | 2 | 85 | |
295 | 94 | 86 | |
296 | 2 | 86 | |
297 | 29 | 86 | |
298 | 95 | 86 | |
299 | 1 | 86 | |
300 | 92 | 86 | |
301 | 93 | 87 | |
302 | 91 | 87 | |
303 | 94 | 87 | |
304 | 92 | 87 | |
305 | 1 | 87 | |
306 | 101 | 87 | |
307 | 88 | 87 | |
308 | 95 | 87 | |
309 | 2 | 87 | |
310 | 2 | 88 | |
311 | 2 | 89 | |
312 | 94 | 89 | |
313 | 1 | 89 | |
314 | 95 | 89 | |
315 | 92 | 89 | |
316 | 88 | 89 | |
317 | 1 | 90 | |
318 | 102 | 90 | |
319 | 95 | 91 | |
320 | 1 | 91 | |
321 | 102 | 91 | |
322 | 87 | 91 | |
323 | 1 | 92 | |
324 | 2 | 92 | |
325 | 88 | 92 | |
326 | 92 | 92 | |
327 | 106 | 89 | |
328 | 95 | 94 | |
329 | 88 | 96 | |
330 | 32 | 98 | |
331 | 32 | 97 | |
332 | 85 | 97 | |
333 | 32 | 99 | |
334 | 88 | 95 | |
335 | 93 | 100 | |
336 | 31 | 100 | |
337 | 28 | 100 | |
338 | 84 | 100 | |
339 | 89 | 100 | |
340 | 86 | 100 | |
341 | 33 | 100 | |
342 | 28 | 101 | |
343 | 31 | 101 | |
344 | 84 | 101 | |
345 | 88 | 101 | |
346 | 32 | 101 | |
347 | 91 | 102 | |
348 | 80 | 102 | |
349 | 84 | 102 | |
350 | 28 | 102 | |
351 | 93 | 103 | |
352 | 95 | 103 | |
353 | 33 | 103 | |
354 | 91 | 103 | |
355 | 89 | 104 | |
356 | 91 | 106 | |
357 | 80 | 107 | |
358 | 86 | 108 | |
359 | 86 | 109 | |
360 | 90 | 110 | |
361 | 85 | 111 | |
362 | 88 | 113 | |
363 | 88 | 112 | |
364 | 85 | 107 | |
365 | 92 | 38 | |
366 | 95 | 38 | |
367 | 93 | 38 | |
368 | 95 | 116 | |
369 | 90 | 68 | |
370 | 93 | 37 | |
371 | 94 | 39 | |
372 | 92 | 39 | |
373 | 91 | 38 | |
374 | 33 | 119 | |
375 | 31 | 119 | |
376 | 85 | 119 | |
377 | 84 | 119 | |
378 | 28 | 119 | |
379 | 6 | 119 | |
380 | 32 | 119 | |
381 | 31 | 120 | |
382 | 32 | 120 | |
383 | 31 | 121 | |
384 | 33 | 121 | |
385 | 31 | 122 | |
386 | 32 | 122 | |
387 | 33 | 122 | |
388 | 84 | 123 | |
389 | 32 | 123 | |
390 | 88 | 123 | |
391 | 1 | 124 | |
392 | 2 | 124 | |
393 | 92 | 125 | |
394 | 1 | 125 | |
396 | 2 | 125 | |
397 | 1 | 126 | |
398 | 92 | 126 | |
399 | 2 | 127 | |
400 | 1 | 127 | |
401 | 91 | 127 | |
402 | 1 | 128 | |
403 | 91 | 128 | |
404 | 2 | 128 | |
405 | 1 | 129 | |
406 | 92 | 129 | |
407 | 85 | 130 | |
408 | 1 | 130 | |
409 | 91 | 130 | |
410 | 91 | 131 | |
411 | 1 | 131 | |
412 | 85 | 131 | |
413 | 91 | 132 | |
414 | 85 | 132 | |
415 | 1 | 132 | |
416 | 85 | 133 | |
417 | 2 | 133 | |
418 | 92 | 133 | |
419 | 91 | 133 | |
420 | 1 | 133 | |
421 | 1 | 134 | |
422 | 2 | 134 | |
423 | 106 | 134 | |
424 | 1 | 135 | |
425 | 85 | 135 | |
426 | 91 | 135 | |
427 | 85 | 136 | |
428 | 1 | 136 | |
429 | 91 | 136 | |
430 | 91 | 137 | |
431 | 1 | 137 | |
432 | 85 | 137 | |
433 | 93 | 137 | |
434 | 1 | 118 | |
435 | 95 | 117 | |
436 | 90 | 117 | |
437 | 2 | 117 | |
438 | 85 | 110 | |
439 | 1 | 138 | |
440 | 42 | 138 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* jQuery JavaScript Library v2.0.0 | |
* http://jquery.com/ | |
* | |
* Includes Sizzle.js | |
* http://sizzlejs.com/ | |
* | |
* Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors | |
* Released under the MIT license | |
* http://jquery.org/license | |
* | |
* Date: 2013-04-18 | |
*/ | |
(function( window, undefined ) { | |
// Can't do this because several apps including ASP.NET trace | |
// the stack via arguments.caller.callee and Firefox dies if | |
// you try to trace through "use strict" call chains. (#13335) | |
// Support: Firefox 18+ | |
//"use strict"; | |
var | |
// A central reference to the root jQuery(document) | |
rootjQuery, | |
// The deferred used on DOM ready | |
readyList, | |
// Support: IE9 | |
// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` | |
core_strundefined = typeof undefined, | |
// Use the correct document accordingly with window argument (sandbox) | |
location = window.location, | |
document = window.document, | |
docElem = document.documentElement, | |
// Map over jQuery in case of overwrite | |
_jQuery = window.jQuery, | |
// Map over the $ in case of overwrite | |
_$ = window.$, | |
// [[Class]] -> type pairs | |
class2type = {}, | |
// List of deleted data cache ids, so we can reuse them | |
core_deletedIds = [], | |
core_version = "2.0.0", | |
// Save a reference to some core methods | |
core_concat = core_deletedIds.concat, | |
core_push = core_deletedIds.push, | |
core_slice = core_deletedIds.slice, | |
core_indexOf = core_deletedIds.indexOf, | |
core_toString = class2type.toString, | |
core_hasOwn = class2type.hasOwnProperty, | |
core_trim = core_version.trim, | |
// Define a local copy of jQuery | |
jQuery = function( selector, context ) { | |
// The jQuery object is actually just the init constructor 'enhanced' | |
return new jQuery.fn.init( selector, context, rootjQuery ); | |
}, | |
// Used for matching numbers | |
core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, | |
// Used for splitting on whitespace | |
core_rnotwhite = /\S+/g, | |
// A simple way to check for HTML strings | |
// Prioritize #id over <tag> to avoid XSS via location.hash (#9521) | |
// Strict HTML recognition (#11290: must start with <) | |
rquickExpr = /^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/, | |
// Match a standalone tag | |
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, | |
// Matches dashed string for camelizing | |
rmsPrefix = /^-ms-/, | |
rdashAlpha = /-([\da-z])/gi, | |
// Used by jQuery.camelCase as callback to replace() | |
fcamelCase = function( all, letter ) { | |
return letter.toUpperCase(); | |
}, | |
// The ready event handler and self cleanup method | |
completed = function() { | |
document.removeEventListener( "DOMContentLoaded", completed, false ); | |
window.removeEventListener( "load", completed, false ); | |
jQuery.ready(); | |
}; | |
jQuery.fn = jQuery.prototype = { | |
// The current version of jQuery being used | |
jquery: core_version, | |
constructor: jQuery, | |
init: function( selector, context, rootjQuery ) { | |
var match, elem; | |
// HANDLE: $(""), $(null), $(undefined), $(false) | |
if ( !selector ) { | |
return this; | |
} | |
// Handle HTML strings | |
if ( typeof selector === "string" ) { | |
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { | |
// Assume that strings that start and end with <> are HTML and skip the regex check | |
match = [ null, selector, null ]; | |
} else { | |
match = rquickExpr.exec( selector ); | |
} | |
// Match html or make sure no context is specified for #id | |
if ( match && (match[1] || !context) ) { | |
// HANDLE: $(html) -> $(array) | |
if ( match[1] ) { | |
context = context instanceof jQuery ? context[0] : context; | |
// scripts is true for back-compat | |
jQuery.merge( this, jQuery.parseHTML( | |
match[1], | |
context && context.nodeType ? context.ownerDocument || context : document, | |
true | |
) ); | |
// HANDLE: $(html, props) | |
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { | |
for ( match in context ) { | |
// Properties of context are called as methods if possible | |
if ( jQuery.isFunction( this[ match ] ) ) { | |
this[ match ]( context[ match ] ); | |
// ...and otherwise set as attributes | |
} else { | |
this.attr( match, context[ match ] ); | |
} | |
} | |
} | |
return this; | |
// HANDLE: $(#id) | |
} else { | |
elem = document.getElementById( match[2] ); | |
// Check parentNode to catch when Blackberry 4.6 returns | |
// nodes that are no longer in the document #6963 | |
if ( elem && elem.parentNode ) { | |
// Inject the element directly into the jQuery object | |
this.length = 1; | |
this[0] = elem; | |
} | |
this.context = document; | |
this.selector = selector; | |
return this; | |
} | |
// HANDLE: $(expr, $(...)) | |
} else if ( !context || context.jquery ) { | |
return ( context || rootjQuery ).find( selector ); | |
// HANDLE: $(expr, context) | |
// (which is just equivalent to: $(context).find(expr) | |
} else { | |
return this.constructor( context ).find( selector ); | |
} | |
// HANDLE: $(DOMElement) | |
} else if ( selector.nodeType ) { | |
this.context = this[0] = selector; | |
this.length = 1; | |
return this; | |
// HANDLE: $(function) | |
// Shortcut for document ready | |
} else if ( jQuery.isFunction( selector ) ) { | |
return rootjQuery.ready( selector ); | |
} | |
if ( selector.selector !== undefined ) { | |
this.selector = selector.selector; | |
this.context = selector.context; | |
} | |
return jQuery.makeArray( selector, this ); | |
}, | |
// Start with an empty selector | |
selector: "", | |
// The default length of a jQuery object is 0 | |
length: 0, | |
toArray: function() { | |
return core_slice.call( this ); | |
}, | |
// Get the Nth element in the matched element set OR | |
// Get the whole matched element set as a clean array | |
get: function( num ) { | |
return num == null ? | |
// Return a 'clean' array | |
this.toArray() : | |
// Return just the object | |
( num < 0 ? this[ this.length + num ] : this[ num ] ); | |
}, | |
// Take an array of elements and push it onto the stack | |
// (returning the new matched element set) | |
pushStack: function( elems ) { | |
// Build a new jQuery matched element set | |
var ret = jQuery.merge( this.constructor(), elems ); | |
// Add the old object onto the stack (as a reference) | |
ret.prevObject = this; | |
ret.context = this.context; | |
// Return the newly-formed element set | |
return ret; | |
}, | |
// Execute a callback for every element in the matched set. | |
// (You can seed the arguments with an array of args, but this is | |
// only used internally.) | |
each: function( callback, args ) { | |
return jQuery.each( this, callback, args ); | |
}, | |
ready: function( fn ) { | |
// Add the callback | |
jQuery.ready.promise().done( fn ); | |
return this; | |
}, | |
slice: function() { | |
return this.pushStack( core_slice.apply( this, arguments ) ); | |
}, | |
first: function() { | |
return this.eq( 0 ); | |
}, | |
last: function() { | |
return this.eq( -1 ); | |
}, | |
eq: function( i ) { | |
var len = this.length, | |
j = +i + ( i < 0 ? len : 0 ); | |
return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); | |
}, | |
map: function( callback ) { | |
return this.pushStack( jQuery.map(this, function( elem, i ) { | |
return callback.call( elem, i, elem ); | |
})); | |
}, | |
end: function() { | |
return this.prevObject || this.constructor(null); | |
}, | |
// For internal use only. | |
// Behaves like an Array's method, not like a jQuery method. | |
push: core_push, | |
sort: [].sort, | |
splice: [].splice | |
}; | |
// Give the init function the jQuery prototype for later instantiation | |
jQuery.fn.init.prototype = jQuery.fn; | |
jQuery.extend = jQuery.fn.extend = function() { | |
var options, name, src, copy, copyIsArray, clone, | |
target = arguments[0] || {}, | |
i = 1, | |
length = arguments.length, | |
deep = false; | |
// Handle a deep copy situation | |
if ( typeof target === "boolean" ) { | |
deep = target; | |
target = arguments[1] || {}; | |
// skip the boolean and the target | |
i = 2; | |
} | |
// Handle case when target is a string or something (possible in deep copy) | |
if ( typeof target !== "object" && !jQuery.isFunction(target) ) { | |
target = {}; | |
} | |
// extend jQuery itself if only one argument is passed | |
if ( length === i ) { | |
target = this; | |
--i; | |
} | |
for ( ; i < length; i++ ) { | |
// Only deal with non-null/undefined values | |
if ( (options = arguments[ i ]) != null ) { | |
// Extend the base object | |
for ( name in options ) { | |
src = target[ name ]; | |
copy = options[ name ]; | |
// Prevent never-ending loop | |
if ( target === copy ) { | |
continue; | |
} | |
// Recurse if we're merging plain objects or arrays | |
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { | |
if ( copyIsArray ) { | |
copyIsArray = false; | |
clone = src && jQuery.isArray(src) ? src : []; | |
} else { | |
clone = src && jQuery.isPlainObject(src) ? src : {}; | |
} | |
// Never move original objects, clone them | |
target[ name ] = jQuery.extend( deep, clone, copy ); | |
// Don't bring in undefined values | |
} else if ( copy !== undefined ) { | |
target[ name ] = copy; | |
} | |
} | |
} | |
} | |
// Return the modified object | |
return target; | |
}; | |
jQuery.extend({ | |
// Unique for each copy of jQuery on the page | |
expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), | |
noConflict: function( deep ) { | |
if ( window.$ === jQuery ) { | |
window.$ = _$; | |
} | |
if ( deep && window.jQuery === jQuery ) { | |
window.jQuery = _jQuery; | |
} | |
return jQuery; | |
}, | |
// Is the DOM ready to be used? Set to true once it occurs. | |
isReady: false, | |
// A counter to track how many items to wait for before | |
// the ready event fires. See #6781 | |
readyWait: 1, | |
// Hold (or release) the ready event | |
holdReady: function( hold ) { | |
if ( hold ) { | |
jQuery.readyWait++; | |
} else { | |
jQuery.ready( true ); | |
} | |
}, | |
// Handle when the DOM is ready | |
ready: function( wait ) { | |
// Abort if there are pending holds or we're already ready | |
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { | |
return; | |
} | |
// Remember that the DOM is ready | |
jQuery.isReady = true; | |
// If a normal DOM Ready event fired, decrement, and wait if need be | |
if ( wait !== true && --jQuery.readyWait > 0 ) { | |
return; | |
} | |
// If there are functions bound, to execute | |
readyList.resolveWith( document, [ jQuery ] ); | |
// Trigger any bound ready events | |
if ( jQuery.fn.trigger ) { | |
jQuery( document ).trigger("ready").off("ready"); | |
} | |
}, | |
// See test/unit/core.js for details concerning isFunction. | |
// Since version 1.3, DOM methods and functions like alert | |
// aren't supported. They return false on IE (#2968). | |
isFunction: function( obj ) { | |
return jQuery.type(obj) === "function"; | |
}, | |
isArray: Array.isArray, | |
isWindow: function( obj ) { | |
return obj != null && obj === obj.window; | |
}, | |
isNumeric: function( obj ) { | |
return !isNaN( parseFloat(obj) ) && isFinite( obj ); | |
}, | |
type: function( obj ) { | |
if ( obj == null ) { | |
return String( obj ); | |
} | |
// Support: Safari <= 5.1 (functionish RegExp) | |
return typeof obj === "object" || typeof obj === "function" ? | |
class2type[ core_toString.call(obj) ] || "object" : | |
typeof obj; | |
}, | |
isPlainObject: function( obj ) { | |
// Not plain objects: | |
// - Any object or value whose internal [[Class]] property is not "[object Object]" | |
// - DOM nodes | |
// - window | |
if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { | |
return false; | |
} | |
// Support: Firefox <20 | |
// The try/catch suppresses exceptions thrown when attempting to access | |
// the "constructor" property of certain host objects, ie. |window.location| | |
// https://bugzilla.mozilla.org/show_bug.cgi?id=814622 | |
try { | |
if ( obj.constructor && | |
!core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { | |
return false; | |
} | |
} catch ( e ) { | |
return false; | |
} | |
// If the function hasn't returned already, we're confident that | |
// |obj| is a plain object, created by {} or constructed with new Object | |
return true; | |
}, | |
isEmptyObject: function( obj ) { | |
var name; | |
for ( name in obj ) { | |
return false; | |
} | |
return true; | |
}, | |
error: function( msg ) { | |
throw new Error( msg ); | |
}, | |
// data: string of html | |
// context (optional): If specified, the fragment will be created in this context, defaults to document | |
// keepScripts (optional): If true, will include scripts passed in the html string | |
parseHTML: function( data, context, keepScripts ) { | |
if ( !data || typeof data !== "string" ) { | |
return null; | |
} | |
if ( typeof context === "boolean" ) { | |
keepScripts = context; | |
context = false; | |
} | |
context = context || document; | |
var parsed = rsingleTag.exec( data ), | |
scripts = !keepScripts && []; | |
// Single tag | |
if ( parsed ) { | |
return [ context.createElement( parsed[1] ) ]; | |
} | |
parsed = jQuery.buildFragment( [ data ], context, scripts ); | |
if ( scripts ) { | |
jQuery( scripts ).remove(); | |
} | |
return jQuery.merge( [], parsed.childNodes ); | |
}, | |
parseJSON: JSON.parse, | |
// Cross-browser xml parsing | |
parseXML: function( data ) { | |
var xml, tmp; | |
if ( !data || typeof data !== "string" ) { | |
return null; | |
} | |
// Support: IE9 | |
try { | |
tmp = new DOMParser(); | |
xml = tmp.parseFromString( data , "text/xml" ); | |
} catch ( e ) { | |
xml = undefined; | |
} | |
if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { | |
jQuery.error( "Invalid XML: " + data ); | |
} | |
return xml; | |
}, | |
noop: function() {}, | |
// Evaluates a script in a global context | |
globalEval: function( code ) { | |
var script, | |
indirect = eval; | |
code = jQuery.trim( code ); | |
if ( code ) { | |
// If the code includes a valid, prologue position | |
// strict mode pragma, execute code by injecting a | |
// script tag into the document. | |
if ( code.indexOf("use strict") === 1 ) { | |
script = document.createElement("script"); | |
script.text = code; | |
document.head.appendChild( script ).parentNode.removeChild( script ); | |
} else { | |
// Otherwise, avoid the DOM node creation, insertion | |
// and removal by using an indirect global eval | |
indirect( code ); | |
} | |
} | |
}, | |
// Convert dashed to camelCase; used by the css and data modules | |
// Microsoft forgot to hump their vendor prefix (#9572) | |
camelCase: function( string ) { | |
return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); | |
}, | |
nodeName: function( elem, name ) { | |
return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); | |
}, | |
// args is for internal usage only | |
each: function( obj, callback, args ) { | |
var value, | |
i = 0, | |
length = obj.length, | |
isArray = isArraylike( obj ); | |
if ( args ) { | |
if ( isArray ) { | |
for ( ; i < length; i++ ) { | |
value = callback.apply( obj[ i ], args ); | |
if ( value === false ) { | |
break; | |
} | |
} | |
} else { | |
for ( i in obj ) { | |
value = callback.apply( obj[ i ], args ); | |
if ( value === false ) { | |
break; | |
} | |
} | |
} | |
// A special, fast, case for the most common use of each | |
} else { | |
if ( isArray ) { | |
for ( ; i < length; i++ ) { | |
value = callback.call( obj[ i ], i, obj[ i ] ); | |
if ( value === false ) { | |
break; | |
} | |
} | |
} else { | |
for ( i in obj ) { | |
value = callback.call( obj[ i ], i, obj[ i ] ); | |
if ( value === false ) { | |
break; | |
} | |
} | |
} | |
} | |
return obj; | |
}, | |
trim: function( text ) { | |
return text == null ? "" : core_trim.call( text ); | |
}, | |
// results is for internal usage only | |
makeArray: function( arr, results ) { | |
var ret = results || []; | |
if ( arr != null ) { | |
if ( isArraylike( Object(arr) ) ) { | |
jQuery.merge( ret, | |
typeof arr === "string" ? | |
[ arr ] : arr | |
); | |
} else { | |
core_push.call( ret, arr ); | |
} | |
} | |
return ret; | |
}, | |
inArray: function( elem, arr, i ) { | |
return arr == null ? -1 : core_indexOf.call( arr, elem, i ); | |
}, | |
merge: function( first, second ) { | |
var l = second.length, | |
i = first.length, | |
j = 0; | |
if ( typeof l === "number" ) { | |
for ( ; j < l; j++ ) { | |
first[ i++ ] = second[ j ]; | |
} | |
} else { | |
while ( second[j] !== undefined ) { | |
first[ i++ ] = second[ j++ ]; | |
} | |
} | |
first.length = i; | |
return first; | |
}, | |
grep: function( elems, callback, inv ) { | |
var retVal, | |
ret = [], | |
i = 0, | |
length = elems.length; | |
inv = !!inv; | |
// Go through the array, only saving the items | |
// that pass the validator function | |
for ( ; i < length; i++ ) { | |
retVal = !!callback( elems[ i ], i ); | |
if ( inv !== retVal ) { | |
ret.push( elems[ i ] ); | |
} | |
} | |
return ret; | |
}, | |
// arg is for internal usage only | |
map: function( elems, callback, arg ) { | |
var value, | |
i = 0, | |
length = elems.length, | |
isArray = isArraylike( elems ), | |
ret = []; | |
// Go through the array, translating each of the items to their | |
if ( isArray ) { | |
for ( ; i < length; i++ ) { | |
value = callback( elems[ i ], i, arg ); | |
if ( value != null ) { | |
ret[ ret.length ] = value; | |
} | |
} | |
// Go through every key on the object, | |
} else { | |
for ( i in elems ) { | |
value = callback( elems[ i ], i, arg ); | |
if ( value != null ) { | |
ret[ ret.length ] = value; | |
} | |
} | |
} | |
// Flatten any nested arrays | |
return core_concat.apply( [], ret ); | |
}, | |
// A global GUID counter for objects | |
guid: 1, | |
// Bind a function to a context, optionally partially applying any | |
// arguments. | |
proxy: function( fn, context ) { | |
var tmp, args, proxy; | |
if ( typeof context === "string" ) { | |
tmp = fn[ context ]; | |
context = fn; | |
fn = tmp; | |
} | |
// Quick check to determine if target is callable, in the spec | |
// this throws a TypeError, but we will just return undefined. | |
if ( !jQuery.isFunction( fn ) ) { | |
return undefined; | |
} | |
// Simulated bind | |
args = core_slice.call( arguments, 2 ); | |
proxy = function() { | |
return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); | |
}; | |
// Set the guid of unique handler to the same of original handler, so it can be removed | |
proxy.guid = fn.guid = fn.guid || jQuery.guid++; | |
return proxy; | |
}, | |
// Multifunctional method to get and set values of a collection | |
// The value/s can optionally be executed if it's a function | |
access: function( elems, fn, key, value, chainable, emptyGet, raw ) { | |
var i = 0, | |
length = elems.length, | |
bulk = key == null; | |
// Sets many values | |
if ( jQuery.type( key ) === "object" ) { | |
chainable = true; | |
for ( i in key ) { | |
jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); | |
} | |
// Sets one value | |
} else if ( value !== undefined ) { | |
chainable = true; | |
if ( !jQuery.isFunction( value ) ) { | |
raw = true; | |
} | |
if ( bulk ) { | |
// Bulk operations run against the entire set | |
if ( raw ) { | |
fn.call( elems, value ); | |
fn = null; | |
// ...except when executing function values | |
} else { | |
bulk = fn; | |
fn = function( elem, key, value ) { | |
return bulk.call( jQuery( elem ), value ); | |
}; | |
} | |
} | |
if ( fn ) { | |
for ( ; i < length; i++ ) { | |
fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); | |
} | |
} | |
} | |
return chainable ? | |
elems : | |
// Gets | |
bulk ? | |
fn.call( elems ) : | |
length ? fn( elems[0], key ) : emptyGet; | |
}, | |
now: Date.now, | |
// A method for quickly swapping in/out CSS properties to get correct calculations. | |
// Note: this method belongs to the css module but it's needed here for the support module. | |
// If support gets modularized, this method should be moved back to the css module. | |
swap: function( elem, options, callback, args ) { | |
var ret, name, | |
old = {}; | |
// Remember the old values, and insert the new ones | |
for ( name in options ) { | |
old[ name ] = elem.style[ name ]; | |
elem.style[ name ] = options[ name ]; | |
} | |
ret = callback.apply( elem, args || [] ); | |
// Revert the old values | |
for ( name in options ) { | |
elem.style[ name ] = old[ name ]; | |
} | |
return ret; | |
} | |
}); | |
jQuery.ready.promise = function( obj ) { | |
if ( !readyList ) { | |
readyList = jQuery.Deferred(); | |
// Catch cases where $(document).ready() is called after the browser event has already occurred. | |
// we once tried to use readyState "interactive" here, but it caused issues like the one | |
// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 | |
if ( document.readyState === "complete" ) { | |
// Handle it asynchronously to allow scripts the opportunity to delay ready | |
setTimeout( jQuery.ready ); | |
} else { | |
// Use the handy event callback | |
document.addEventListener( "DOMContentLoaded", completed, false ); | |
// A fallback to window.onload, that will always work | |
window.addEventListener( "load", completed, false ); | |
} | |
} | |
return readyList.promise( obj ); | |
}; | |
// Populate the class2type map | |
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { | |
class2type[ "[object " + name + "]" ] = name.toLowerCase(); | |
}); | |
function isArraylike( obj ) { | |
var length = obj.length, | |
type = jQuery.type( obj ); | |
if ( jQuery.isWindow( obj ) ) { | |
return false; | |
} | |
if ( obj.nodeType === 1 && length ) { | |
return true; | |
} | |
return type === "array" || type !== "function" && | |
( length === 0 || | |
typeof length === "number" && length > 0 && ( length - 1 ) in obj ); | |
} | |
// All jQuery objects should point back to these | |
rootjQuery = jQuery(document); | |
/*! | |
* Sizzle CSS Selector Engine v1.9.2-pre | |
* http://sizzlejs.com/ | |
* | |
* Copyright 2013 jQuery Foundation, Inc. and other contributors | |
* Released under the MIT license | |
* http://jquery.org/license | |
* | |
* Date: 2013-04-16 | |
*/ | |
(function( window, undefined ) { | |
var i, | |
cachedruns, | |
Expr, | |
getText, | |
isXML, | |
compile, | |
outermostContext, | |
sortInput, | |
// Local document vars | |
setDocument, | |
document, | |
docElem, | |
documentIsHTML, | |
rbuggyQSA, | |
rbuggyMatches, | |
matches, | |
contains, | |
// Instance-specific data | |
expando = "sizzle" + -(new Date()), | |
preferredDoc = window.document, | |
support = {}, | |
dirruns = 0, | |
done = 0, | |
classCache = createCache(), | |
tokenCache = createCache(), | |
compilerCache = createCache(), | |
hasDuplicate = false, | |
sortOrder = function() { return 0; }, | |
// General-purpose constants | |
strundefined = typeof undefined, | |
MAX_NEGATIVE = 1 << 31, | |
// Array methods | |
arr = [], | |
pop = arr.pop, | |
push_native = arr.push, | |
push = arr.push, | |
slice = arr.slice, | |
// Use a stripped-down indexOf if we can't use a native one | |
indexOf = arr.indexOf || function( elem ) { | |
var i = 0, | |
len = this.length; | |
for ( ; i < len; i++ ) { | |
if ( this[i] === elem ) { | |
return i; | |
} | |
} | |
return -1; | |
}, | |
booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", | |
// Regular expressions | |
// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace | |
whitespace = "[\\x20\\t\\r\\n\\f]", | |
// http://www.w3.org/TR/css3-syntax/#characters | |
characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", | |
// Loosely modeled on CSS identifier characters | |
// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors | |
// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier | |
identifier = characterEncoding.replace( "w", "w#" ), | |
// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors | |
attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + | |
"*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", | |
// Prefer arguments quoted, | |
// then not containing pseudos/brackets, | |
// then attribute selectors/non-parenthetical expressions, | |
// then anything else | |
// These preferences are here to reduce the number of selectors | |
// needing tokenize in the PSEUDO preFilter | |
pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", | |
// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter | |
rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), | |
rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), | |
rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), | |
rsibling = new RegExp( whitespace + "*[+~]" ), | |
rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), | |
rpseudo = new RegExp( pseudos ), | |
ridentifier = new RegExp( "^" + identifier + "$" ), | |
matchExpr = { | |
"ID": new RegExp( "^#(" + characterEncoding + ")" ), | |
"CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), | |
"TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), | |
"ATTR": new RegExp( "^" + attributes ), | |
"PSEUDO": new RegExp( "^" + pseudos ), | |
"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + | |
"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + | |
"*(\\d+)|))" + whitespace + "*\\)|)", "i" ), | |
"boolean": new RegExp( "^(?:" + booleans + ")$", "i" ), | |
// For use in libraries implementing .is() | |
// We use this for POS matching in `select` | |
"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + | |
whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) | |
}, | |
rnative = /^[^{]+\{\s*\[native \w/, | |
// Easily-parseable/retrievable ID or TAG or CLASS selectors | |
rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, | |
rinputs = /^(?:input|select|textarea|button)$/i, | |
rheader = /^h\d$/i, | |
rescape = /'|\\/g, | |
// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters | |
runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g, | |
funescape = function( _, escaped ) { | |
var high = "0x" + escaped - 0x10000; | |
// NaN means non-codepoint | |
return high !== high ? | |
escaped : | |
// BMP codepoint | |
high < 0 ? | |
String.fromCharCode( high + 0x10000 ) : | |
// Supplemental Plane codepoint (surrogate pair) | |
String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); | |
}; | |
// Optimize for push.apply( _, NodeList ) | |
try { | |
push.apply( | |
(arr = slice.call( preferredDoc.childNodes )), | |
preferredDoc.childNodes | |
); | |
// Support: Android<4.0 | |
// Detect silently failing push.apply | |
arr[ preferredDoc.childNodes.length ].nodeType; | |
} catch ( e ) { | |
push = { apply: arr.length ? | |
// Leverage slice if possible | |
function( target, els ) { | |
push_native.apply( target, slice.call(els) ); | |
} : | |
// Support: IE<9 | |
// Otherwise append directly | |
function( target, els ) { | |
var j = target.length, | |
i = 0; | |
// Can't trust NodeList.length | |
while ( (target[j++] = els[i++]) ) {} | |
target.length = j - 1; | |
} | |
}; | |
} | |
/** | |
* For feature detection | |
* @param {Function} fn The function to test for native support | |
*/ | |
function isNative( fn ) { | |
return rnative.test( fn + "" ); | |
} | |
/** | |
* Create key-value caches of limited size | |
* @returns {Function(string, Object)} Returns the Object data after storing it on itself with | |
* property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) | |
* deleting the oldest entry | |
*/ | |
function createCache() { | |
var cache, | |
keys = []; | |
return (cache = function( key, value ) { | |
// Use (key + " ") to avoid collision with native prototype properties (see Issue #157) | |
if ( keys.push( key += " " ) > Expr.cacheLength ) { | |
// Only keep the most recent entries | |
delete cache[ keys.shift() ]; | |
} | |
return (cache[ key ] = value); | |
}); | |
} | |
/** | |
* Mark a function for special use by Sizzle | |
* @param {Function} fn The function to mark | |
*/ | |
function markFunction( fn ) { | |
fn[ expando ] = true; | |
return fn; | |
} | |
/** | |
* Support testing using an element | |
* @param {Function} fn Passed the created div and expects a boolean result | |
*/ | |
function assert( fn ) { | |
var div = document.createElement("div"); | |
try { | |
return !!fn( div ); | |
} catch (e) { | |
return false; | |
} finally { | |
if ( div.parentNode ) { | |
div.parentNode.removeChild( div ); | |
} | |
// release memory in IE | |
div = null; | |
} | |
} | |
function Sizzle( selector, context, results, seed ) { | |
var match, elem, m, nodeType, | |
// QSA vars | |
i, groups, old, nid, newContext, newSelector; | |
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { | |
setDocument( context ); | |
} | |
context = context || document; | |
results = results || []; | |
if ( !selector || typeof selector !== "string" ) { | |
return results; | |
} | |
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { | |
return []; | |
} | |
if ( documentIsHTML && !seed ) { | |
// Shortcuts | |
if ( (match = rquickExpr.exec( selector )) ) { | |
// Speed-up: Sizzle("#ID") | |
if ( (m = match[1]) ) { | |
if ( nodeType === 9 ) { | |
elem = context.getElementById( m ); | |
// Check parentNode to catch when Blackberry 4.6 returns | |
// nodes that are no longer in the document #6963 | |
if ( elem && elem.parentNode ) { | |
// Handle the case where IE, Opera, and Webkit return items | |
// by name instead of ID | |
if ( elem.id === m ) { | |
results.push( elem ); | |
return results; | |
} | |
} else { | |
return results; | |
} | |
} else { | |
// Context is not a document | |
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && | |
contains( context, elem ) && elem.id === m ) { | |
results.push( elem ); | |
return results; | |
} | |
} | |
// Speed-up: Sizzle("TAG") | |
} else if ( match[2] ) { | |
push.apply( results, context.getElementsByTagName( selector ) ); | |
return results; | |
// Speed-up: Sizzle(".CLASS") | |
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { | |
push.apply( results, context.getElementsByClassName( m ) ); | |
return results; | |
} | |
} | |
// QSA path | |
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { | |
nid = old = expando; | |
newContext = context; | |
newSelector = nodeType === 9 && selector; | |
// qSA works strangely on Element-rooted queries | |
// We can work around this by specifying an extra ID on the root | |
// and working up from there (Thanks to Andrew Dupont for the technique) | |
// IE 8 doesn't work on object elements | |
if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { | |
groups = tokenize( selector ); | |
if ( (old = context.getAttribute("id")) ) { | |
nid = old.replace( rescape, "\\$&" ); | |
} else { | |
context.setAttribute( "id", nid ); | |
} | |
nid = "[id='" + nid + "'] "; | |
i = groups.length; | |
while ( i-- ) { | |
groups[i] = nid + toSelector( groups[i] ); | |
} | |
newContext = rsibling.test( selector ) && context.parentNode || context; | |
newSelector = groups.join(","); | |
} | |
if ( newSelector ) { | |
try { | |
push.apply( results, | |
newContext.querySelectorAll( newSelector ) | |
); | |
return results; | |
} catch(qsaError) { | |
} finally { | |
if ( !old ) { | |
context.removeAttribute("id"); | |
} | |
} | |
} | |
} | |
} | |
// All others | |
return select( selector.replace( rtrim, "$1" ), context, results, seed ); | |
} | |
/** | |
* Detect xml | |
* @param {Element|Object} elem An element or a document | |
*/ | |
isXML = Sizzle.isXML = function( elem ) { | |
// documentElement is verified for cases where it doesn't yet exist | |
// (such as loading iframes in IE - #4833) | |
var documentElement = elem && (elem.ownerDocument || elem).documentElement; | |
return documentElement ? documentElement.nodeName !== "HTML" : false; | |
}; | |
/** | |
* Sets document-related variables once based on the current document | |
* @param {Element|Object} [doc] An element or document object to use to set the document | |
* @returns {Object} Returns the current document | |
*/ | |
setDocument = Sizzle.setDocument = function( node ) { | |
var doc = node ? node.ownerDocument || node : preferredDoc; | |
// If no document and documentElement is available, return | |
if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { | |
return document; | |
} | |
// Set our document | |
document = doc; | |
docElem = doc.documentElement; | |
// Support tests | |
documentIsHTML = !isXML( doc ); | |
// Check if getElementsByTagName("*") returns only elements | |
support.getElementsByTagName = assert(function( div ) { | |
div.appendChild( doc.createComment("") ); | |
return !div.getElementsByTagName("*").length; | |
}); | |
// Support: IE<8 | |
// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) | |
support.attributes = assert(function( div ) { | |
div.className = "i"; | |
return !div.getAttribute("className"); | |
}); | |
// Check if getElementsByClassName can be trusted | |
support.getElementsByClassName = assert(function( div ) { | |
div.innerHTML = "<div class='a'></div><div class='a i'></div>"; | |
// Support: Safari<4 | |
// Catch class over-caching | |
div.firstChild.className = "i"; | |
// Support: Opera<10 | |
// Catch gEBCN failure to find non-leading classes | |
return div.getElementsByClassName("i").length === 2; | |
}); | |
// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) | |
// Detached nodes confoundingly follow *each other* | |
support.sortDetached = assert(function( div1 ) { | |
// Should return 1, but returns 4 (following) | |
return div1.compareDocumentPosition( document.createElement("div") ) & 1; | |
}); | |
// Support: IE<10 | |
// Check if getElementById returns elements by name | |
// Support: Windows 8 Native Apps | |
// Assigning innerHTML with "name" attributes throws uncatchable exceptions | |
// (http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx) | |
// and the broken getElementById methods don't pick up programatically-set names, | |
// so use a roundabout getElementsByName test | |
support.getById = assert(function( div ) { | |
docElem.appendChild( div ).id = expando; | |
return !doc.getElementsByName || !doc.getElementsByName( expando ).length; | |
}); | |
// ID find and filter | |
if ( support.getById ) { | |
Expr.find["ID"] = function( id, context ) { | |
if ( typeof context.getElementById !== strundefined && documentIsHTML ) { | |
var m = context.getElementById( id ); | |
// Check parentNode to catch when Blackberry 4.6 returns | |
// nodes that are no longer in the document #6963 | |
return m && m.parentNode ? [m] : []; | |
} | |
}; | |
Expr.filter["ID"] = function( id ) { | |
var attrId = id.replace( runescape, funescape ); | |
return function( elem ) { | |
return elem.getAttribute("id") === attrId; | |
}; | |
}; | |
} else { | |
Expr.find["ID"] = function( id, context ) { | |
if ( typeof context.getElementById !== strundefined && documentIsHTML ) { | |
var m = context.getElementById( id ); | |
return m ? | |
m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? | |
[m] : | |
undefined : | |
[]; | |
} | |
}; | |
Expr.filter["ID"] = function( id ) { | |
var attrId = id.replace( runescape, funescape ); | |
return function( elem ) { | |
var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); | |
return node && node.value === attrId; | |
}; | |
}; | |
} | |
// Tag | |
Expr.find["TAG"] = support.getElementsByTagName ? | |
function( tag, context ) { | |
if ( typeof context.getElementsByTagName !== strundefined ) { | |
return context.getElementsByTagName( tag ); | |
} | |
} : | |
function( tag, context ) { | |
var elem, | |
tmp = [], | |
i = 0, | |
results = context.getElementsByTagName( tag ); | |
// Filter out possible comments | |
if ( tag === "*" ) { | |
while ( (elem = results[i++]) ) { | |
if ( elem.nodeType === 1 ) { | |
tmp.push( elem ); | |
} | |
} | |
return tmp; | |
} | |
return results; | |
}; | |
// Class | |
Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { | |
if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { | |
return context.getElementsByClassName( className ); | |
} | |
}; | |
// QSA and matchesSelector support | |
// matchesSelector(:active) reports false when true (IE9/Opera 11.5) | |
rbuggyMatches = []; | |
// qSa(:focus) reports false when true (Chrome 21) | |
// We allow this because of a bug in IE8/9 that throws an error | |
// whenever `document.activeElement` is accessed on an iframe | |
// So, we allow :focus to pass through QSA all the time to avoid the IE error | |
// See http://bugs.jquery.com/ticket/13378 | |
rbuggyQSA = []; | |
if ( (support.qsa = isNative(doc.querySelectorAll)) ) { | |
// Build QSA regex | |
// Regex strategy adopted from Diego Perini | |
assert(function( div ) { | |
// Select is set to empty string on purpose | |
// This is to test IE's treatment of not explicitly | |
// setting a boolean content attribute, | |
// since its presence should be enough | |
// http://bugs.jquery.com/ticket/12359 | |
div.innerHTML = "<select><option selected=''></option></select>"; | |
// Support: IE8 | |
// Boolean attributes and "value" are not treated correctly | |
if ( !div.querySelectorAll("[selected]").length ) { | |
rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); | |
} | |
// Webkit/Opera - :checked should return selected option elements | |
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked | |
// IE8 throws error here and will not see later tests | |
if ( !div.querySelectorAll(":checked").length ) { | |
rbuggyQSA.push(":checked"); | |
} | |
}); | |
assert(function( div ) { | |
// Support: Opera 10-12/IE8 | |
// ^= $= *= and empty values | |
// Should not select anything | |
// Support: Windows 8 Native Apps | |
// The type attribute is restricted during .innerHTML assignment | |
var input = document.createElement("input"); | |
input.setAttribute( "type", "hidden" ); | |
div.appendChild( input ).setAttribute( "t", "" ); | |
if ( div.querySelectorAll("[t^='']").length ) { | |
rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); | |
} | |
// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) | |
// IE8 throws error here and will not see later tests | |
if ( !div.querySelectorAll(":enabled").length ) { | |
rbuggyQSA.push( ":enabled", ":disabled" ); | |
} | |
// Opera 10-11 does not throw on post-comma invalid pseudos | |
div.querySelectorAll("*,:x"); | |
rbuggyQSA.push(",.*:"); | |
}); | |
} | |
if ( (support.matchesSelector = isNative( (matches = docElem.webkitMatchesSelector || | |
docElem.mozMatchesSelector || | |
docElem.oMatchesSelector || | |
docElem.msMatchesSelector) )) ) { | |
assert(function( div ) { | |
// Check to see if it's possible to do matchesSelector | |
// on a disconnected node (IE 9) | |
support.disconnectedMatch = matches.call( div, "div" ); | |
// This should fail with an exception | |
// Gecko does not error, returns false instead | |
matches.call( div, "[s!='']:x" ); | |
rbuggyMatches.push( "!=", pseudos ); | |
}); | |
} | |
rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); | |
rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); | |
// Element contains another | |
// Purposefully does not implement inclusive descendent | |
// As in, an element does not contain itself | |
contains = isNative(docElem.contains) || docElem.compareDocumentPosition ? | |
function( a, b ) { | |
var adown = a.nodeType === 9 ? a.documentElement : a, | |
bup = b && b.parentNode; | |
return a === bup || !!( bup && bup.nodeType === 1 && ( | |
adown.contains ? | |
adown.contains( bup ) : | |
a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 | |
)); | |
} : | |
function( a, b ) { | |
if ( b ) { | |
while ( (b = b.parentNode) ) { | |
if ( b === a ) { | |
return true; | |
} | |
} | |
} | |
return false; | |
}; | |
// Document order sorting | |
sortOrder = docElem.compareDocumentPosition ? | |
function( a, b ) { | |
// Flag for duplicate removal | |
if ( a === b ) { | |
hasDuplicate = true; | |
return 0; | |
} | |
var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); | |
if ( compare ) { | |
// Disconnected nodes | |
if ( compare & 1 || | |
(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { | |
// Choose the first element that is related to our preferred document | |
if ( a === doc || contains(preferredDoc, a) ) { | |
return -1; | |
} | |
if ( b === doc || contains(preferredDoc, b) ) { | |
return 1; | |
} | |
// Maintain original order | |
return sortInput ? | |
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : | |
0; | |
} | |
return compare & 4 ? -1 : 1; | |
} | |
// Not directly comparable, sort on existence of method | |
return a.compareDocumentPosition ? -1 : 1; | |
} : | |
function( a, b ) { | |
var cur, | |
i = 0, | |
aup = a.parentNode, | |
bup = b.parentNode, | |
ap = [ a ], | |
bp = [ b ]; | |
// Exit early if the nodes are identical | |
if ( a === b ) { | |
hasDuplicate = true; | |
return 0; | |
// Parentless nodes are either documents or disconnected | |
} else if ( !aup || !bup ) { | |
return a === doc ? -1 : | |
b === doc ? 1 : | |
aup ? -1 : | |
bup ? 1 : | |
sortInput ? | |
( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : | |
0; | |
// If the nodes are siblings, we can do a quick check | |
} else if ( aup === bup ) { | |
return siblingCheck( a, b ); | |
} | |
// Otherwise we need full lists of their ancestors for comparison | |
cur = a; | |
while ( (cur = cur.parentNode) ) { | |
ap.unshift( cur ); | |
} | |
cur = b; | |
while ( (cur = cur.parentNode) ) { | |
bp.unshift( cur ); | |
} | |
// Walk down the tree looking for a discrepancy | |
while ( ap[i] === bp[i] ) { | |
i++; | |
} | |
return i ? | |
// Do a sibling check if the nodes have a common ancestor | |
siblingCheck( ap[i], bp[i] ) : | |
// Otherwise nodes in our document sort first | |
ap[i] === preferredDoc ? -1 : | |
bp[i] === preferredDoc ? 1 : | |
0; | |
}; | |
return document; | |
}; | |
Sizzle.matches = function( expr, elements ) { | |
return Sizzle( expr, null, null, elements ); | |
}; | |
Sizzle.matchesSelector = function( elem, expr ) { | |
// Set document vars if needed | |
if ( ( elem.ownerDocument || elem ) !== document ) { | |
setDocument( elem ); | |
} | |
// Make sure that attribute selectors are quoted | |
expr = expr.replace( rattributeQuotes, "='$1']" ); | |
// rbuggyQSA always contains :focus, so no need for an existence check | |
if ( support.matchesSelector && documentIsHTML && | |
(!rbuggyMatches || !rbuggyMatches.test(expr)) && | |
(!rbuggyQSA || !rbuggyQSA.test(expr)) ) { | |
try { | |
var ret = matches.call( elem, expr ); | |
// IE 9's matchesSelector returns false on disconnected nodes | |
if ( ret || support.disconnectedMatch || | |
// As well, disconnected nodes are said to be in a document | |
// fragment in IE 9 | |
elem.document && elem.document.nodeType !== 11 ) { | |
return ret; | |
} | |
} catch(e) {} | |
} | |
return Sizzle( expr, document, null, [elem] ).length > 0; | |
}; | |
Sizzle.contains = function( context, elem ) { | |
// Set document vars if needed | |
if ( ( context.ownerDocument || context ) !== document ) { | |
setDocument( context ); | |
} | |
return contains( context, elem ); | |
}; | |
Sizzle.attr = function( elem, name ) { | |
// Set document vars if needed | |
if ( ( elem.ownerDocument || elem ) !== document ) { | |
setDocument( elem ); | |
} | |
var fn = Expr.attrHandle[ name.toLowerCase() ], | |
val = fn && fn( elem, name, !documentIsHTML ); | |
return val === undefined ? | |
support.attributes || !documentIsHTML ? | |
elem.getAttribute( name ) : | |
(val = elem.getAttributeNode(name)) && val.specified ? | |
val.value : | |
null : | |
val; | |
}; | |
Sizzle.error = function( msg ) { | |
throw new Error( "Syntax error, unrecognized expression: " + msg ); | |
}; | |
// Document sorting and removing duplicates | |
Sizzle.uniqueSort = function( results ) { | |
var elem, | |
duplicates = [], | |
j = 0, | |
i = 0; | |
// Unless we *know* we can detect duplicates, assume their presence | |
hasDuplicate = !support.detectDuplicates; | |
sortInput = !support.sortStable && results.slice( 0 ); | |
results.sort( sortOrder ); | |
if ( hasDuplicate ) { | |
while ( (elem = results[i++]) ) { | |
if ( elem === results[ i ] ) { | |
j = duplicates.push( i ); | |
} | |
} | |
while ( j-- ) { | |
results.splice( duplicates[ j ], 1 ); | |
} | |
} | |
return results; | |
}; | |
/** | |
* Checks document order of two siblings | |
* @param {Element} a | |
* @param {Element} b | |
* @returns Returns -1 if a precedes b, 1 if a follows b | |
*/ | |
function siblingCheck( a, b ) { | |
var cur = b && a, | |
diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE ); | |
// Use IE sourceIndex if available on both nodes | |
if ( diff ) { | |
return diff; | |
} | |
// Check if b follows a | |
if ( cur ) { | |
while ( (cur = cur.nextSibling) ) { | |
if ( cur === b ) { | |
return -1; | |
} | |
} | |
} | |
return a ? 1 : -1; | |
} | |
// Fetches boolean attributes by node | |
function boolHandler( elem, name, isXML ) { | |
var val; | |
return isXML ? | |
undefined : | |
(val = elem.getAttributeNode( name )) && val.specified ? | |
val.value : | |
elem[ name ] === true ? name.toLowerCase() : null; | |
} | |
// Fetches attributes without interpolation | |
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx | |
function interpolationHandler( elem, name, isXML ) { | |
var val; | |
return isXML ? | |
undefined : | |
(val = elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 )); | |
} | |
// Returns a function to use in pseudos for input types | |
function createInputPseudo( type ) { | |
return function( elem ) { | |
var name = elem.nodeName.toLowerCase(); | |
return name === "input" && elem.type === type; | |
}; | |
} | |
// Returns a function to use in pseudos for buttons | |
function createButtonPseudo( type ) { | |
return function( elem ) { | |
var name = elem.nodeName.toLowerCase(); | |
return (name === "input" || name === "button") && elem.type === type; | |
}; | |
} | |
// Returns a function to use in pseudos for positionals | |
function createPositionalPseudo( fn ) { | |
return markFunction(function( argument ) { | |
argument = +argument; | |
return markFunction(function( seed, matches ) { | |
var j, | |
matchIndexes = fn( [], seed.length, argument ), | |
i = matchIndexes.length; | |
// Match elements found at the specified indexes | |
while ( i-- ) { | |
if ( seed[ (j = matchIndexes[i]) ] ) { | |
seed[j] = !(matches[j] = seed[j]); | |
} | |
} | |
}); | |
}); | |
} | |
/** | |
* Utility function for retrieving the text value of an array of DOM nodes | |
* @param {Array|Element} elem | |
*/ | |
getText = Sizzle.getText = function( elem ) { | |
var node, | |
ret = "", | |
i = 0, | |
nodeType = elem.nodeType; | |
if ( !nodeType ) { | |
// If no nodeType, this is expected to be an array | |
for ( ; (node = elem[i]); i++ ) { | |
// Do not traverse comment nodes | |
ret += getText( node ); | |
} | |
} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { | |
// Use textContent for elements | |
// innerText usage removed for consistency of new lines (see #11153) | |
if ( typeof elem.textContent === "string" ) { | |
return elem.textContent; | |
} else { | |
// Traverse its children | |
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { | |
ret += getText( elem ); | |
} | |
} | |
} else if ( nodeType === 3 || nodeType === 4 ) { | |
return elem.nodeValue; | |
} | |
// Do not include comment or processing instruction nodes | |
return ret; | |
}; | |
Expr = Sizzle.selectors = { | |
// Can be adjusted by the user | |
cacheLength: 50, | |
createPseudo: markFunction, | |
match: matchExpr, | |
attrHandle: {}, | |
find: {}, | |
relative: { | |
">": { dir: "parentNode", first: true }, | |
" ": { dir: "parentNode" }, | |
"+": { dir: "previousSibling", first: true }, | |
"~": { dir: "previousSibling" } | |
}, | |
preFilter: { | |
"ATTR": function( match ) { | |
match[1] = match[1].replace( runescape, funescape ); | |
// Move the given value to match[3] whether quoted or unquoted | |
match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); | |
if ( match[2] === "~=" ) { | |
match[3] = " " + match[3] + " "; | |
} | |
return match.slice( 0, 4 ); | |
}, | |
"CHILD": function( match ) { | |
/* matches from matchExpr["CHILD"] | |
1 type (only|nth|...) | |
2 what (child|of-type) | |
3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) | |
4 xn-component of xn+y argument ([+-]?\d*n|) | |
5 sign of xn-component | |
6 x of xn-component | |
7 sign of y-component | |
8 y of y-component | |
*/ | |
match[1] = match[1].toLowerCase(); | |
if ( match[1].slice( 0, 3 ) === "nth" ) { | |
// nth-* requires argument | |
if ( !match[3] ) { | |
Sizzle.error( match[0] ); | |
} | |
// numeric x and y parameters for Expr.filter.CHILD | |
// remember that false/true cast respectively to 0/1 | |
match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); | |
match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); | |
// other types prohibit arguments | |
} else if ( match[3] ) { | |
Sizzle.error( match[0] ); | |
} | |
return match; | |
}, | |
"PSEUDO": function( match ) { | |
var excess, | |
unquoted = !match[5] && match[2]; | |
if ( matchExpr["CHILD"].test( match[0] ) ) { | |
return null; | |
} | |
// Accept quoted arguments as-is | |
if ( match[4] ) { | |
match[2] = match[4]; | |
// Strip excess characters from unquoted arguments | |
} else if ( unquoted && rpseudo.test( unquoted ) && | |
// Get excess from tokenize (recursively) | |
(excess = tokenize( unquoted, true )) && | |
// advance to the next closing parenthesis | |
(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { | |
// excess is a negative index | |
match[0] = match[0].slice( 0, excess ); | |
match[2] = unquoted.slice( 0, excess ); | |
} | |
// Return only captures needed by the pseudo filter method (type and argument) | |
return match.slice( 0, 3 ); | |
} | |
}, | |
filter: { | |
"TAG": function( nodeNameSelector ) { | |
var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); | |
return nodeNameSelector === "*" ? | |
function() { return true; } : | |
function( elem ) { | |
return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; | |
}; | |
}, | |
"CLASS": function( className ) { | |
var pattern = classCache[ className + " " ]; | |
return pattern || | |
(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && | |
classCache( className, function( elem ) { | |
return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); | |
}); | |
}, | |
"ATTR": function( name, operator, check ) { | |
return function( elem ) { | |
var result = Sizzle.attr( elem, name ); | |
if ( result == null ) { | |
return operator === "!="; | |
} | |
if ( !operator ) { | |
return true; | |
} | |
result += ""; | |
return operator === "=" ? result === check : | |
operator === "!=" ? result !== check : | |
operator === "^=" ? check && result.indexOf( check ) === 0 : | |
operator === "*=" ? check && result.indexOf( check ) > -1 : | |
operator === "$=" ? check && result.slice( -check.length ) === check : | |
operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : | |
operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : | |
false; | |
}; | |
}, | |
"CHILD": function( type, what, argument, first, last ) { | |
var simple = type.slice( 0, 3 ) !== "nth", | |
forward = type.slice( -4 ) !== "last", | |
ofType = what === "of-type"; | |
return first === 1 && last === 0 ? | |
// Shortcut for :nth-*(n) | |
function( elem ) { | |
return !!elem.parentNode; | |
} : | |
function( elem, context, xml ) { | |
var cache, outerCache, node, diff, nodeIndex, start, | |
dir = simple !== forward ? "nextSibling" : "previousSibling", | |
parent = elem.parentNode, | |
name = ofType && elem.nodeName.toLowerCase(), | |
useCache = !xml && !ofType; | |
if ( parent ) { | |
// :(first|last|only)-(child|of-type) | |
if ( simple ) { | |
while ( dir ) { | |
node = elem; | |
while ( (node = node[ dir ]) ) { | |
if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { | |
return false; | |
} | |
} | |
// Reverse direction for :only-* (if we haven't yet done so) | |
start = dir = type === "only" && !start && "nextSibling"; | |
} | |
return true; | |
} | |
start = [ forward ? parent.firstChild : parent.lastChild ]; | |
// non-xml :nth-child(...) stores cache data on `parent` | |
if ( forward && useCache ) { | |
// Seek `elem` from a previously-cached index | |
outerCache = parent[ expando ] || (parent[ expando ] = {}); | |
cache = outerCache[ type ] || []; | |
nodeIndex = cache[0] === dirruns && cache[1]; | |
diff = cache[0] === dirruns && cache[2]; | |
node = nodeIndex && parent.childNodes[ nodeIndex ]; | |
while ( (node = ++nodeIndex && node && node[ dir ] || | |
// Fallback to seeking `elem` from the start | |
(diff = nodeIndex = 0) || start.pop()) ) { | |
// When found, cache indexes on `parent` and break | |
if ( node.nodeType === 1 && ++diff && node === elem ) { | |
outerCache[ type ] = [ dirruns, nodeIndex, diff ]; | |
break; | |
} | |
} | |
// Use previously-cached element index if available | |
} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { | |
diff = cache[1]; | |
// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) | |
} else { | |
// Use the same loop as above to seek `elem` from the start | |
while ( (node = ++nodeIndex && node && node[ dir ] || | |
(diff = nodeIndex = 0) || start.pop()) ) { | |
if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { | |
// Cache the index of each encountered element | |
if ( useCache ) { | |
(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; | |
} | |
if ( node === elem ) { | |
break; | |
} | |
} | |
} | |
} | |
// Incorporate the offset, then check against cycle size | |
diff -= last; | |
return diff === first || ( diff % first === 0 && diff / first >= 0 ); | |
} | |
}; | |
}, | |
"PSEUDO": function( pseudo, argument ) { | |
// pseudo-class names are case-insensitive | |
// http://www.w3.org/TR/selectors/#pseudo-classes | |
// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters | |
// Remember that setFilters inherits from pseudos | |
var args, | |
fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || | |
Sizzle.error( "unsupported pseudo: " + pseudo ); | |
// The user may use createPseudo to indicate that | |
// arguments are needed to create the filter function | |
// just as Sizzle does | |
if ( fn[ expando ] ) { | |
return fn( argument ); | |
} | |
// But maintain support for old signatures | |
if ( fn.length > 1 ) { | |
args = [ pseudo, pseudo, "", argument ]; | |
return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? | |
markFunction(function( seed, matches ) { | |
var idx, | |
matched = fn( seed, argument ), | |
i = matched.length; | |
while ( i-- ) { | |
idx = indexOf.call( seed, matched[i] ); | |
seed[ idx ] = !( matches[ idx ] = matched[i] ); | |
} | |
}) : | |
function( elem ) { | |
return fn( elem, 0, args ); | |
}; | |
} | |
return fn; | |
} | |
}, | |
pseudos: { | |
// Potentially complex pseudos | |
"not": markFunction(function( selector ) { | |
// Trim the selector passed to compile | |
// to avoid treating leading and trailing | |
// spaces as combinators | |
var input = [], | |
results = [], | |
matcher = compile( selector.replace( rtrim, "$1" ) ); | |
return matcher[ expando ] ? | |
markFunction(function( seed, matches, context, xml ) { | |
var elem, | |
unmatched = matcher( seed, null, xml, [] ), | |
i = seed.length; | |
// Match elements unmatched by `matcher` | |
while ( i-- ) { | |
if ( (elem = unmatched[i]) ) { | |
seed[i] = !(matches[i] = elem); | |
} | |
} | |
}) : | |
function( elem, context, xml ) { | |
input[0] = elem; | |
matcher( input, null, xml, results ); | |
return !results.pop(); | |
}; | |
}), | |
"has": markFunction(function( selector ) { | |
return function( elem ) { | |
return Sizzle( selector, elem ).length > 0; | |
}; | |
}), | |
"contains": markFunction(function( text ) { | |
return function( elem ) { | |
return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; | |
}; | |
}), | |
// "Whether an element is represented by a :lang() selector | |
// is based solely on the element's language value | |
// being equal to the identifier C, | |
// or beginning with the identifier C immediately followed by "-". | |
// The matching of C against the element's language value is performed case-insensitively. | |
// The identifier C does not have to be a valid language name." | |
// http://www.w3.org/TR/selectors/#lang-pseudo | |
"lang": markFunction( function( lang ) { | |
// lang value must be a valid identifier | |
if ( !ridentifier.test(lang || "") ) { | |
Sizzle.error( "unsupported lang: " + lang ); | |
} | |
lang = lang.replace( runescape, funescape ).toLowerCase(); | |
return function( elem ) { | |
var elemLang; | |
do { | |
if ( (elemLang = documentIsHTML ? | |
elem.lang : | |
elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { | |
elemLang = elemLang.toLowerCase(); | |
return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; | |
} | |
} while ( (elem = elem.parentNode) && elem.nodeType === 1 ); | |
return false; | |
}; | |
}), | |
// Miscellaneous | |
"target": function( elem ) { | |
var hash = window.location && window.location.hash; | |
return hash && hash.slice( 1 ) === elem.id; | |
}, | |
"root": function( elem ) { | |
return elem === docElem; | |
}, | |
"focus": function( elem ) { | |
return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); | |
}, | |
// Boolean properties | |
"enabled": function( elem ) { | |
return elem.disabled === false; | |
}, | |
"disabled": function( elem ) { | |
return elem.disabled === true; | |
}, | |
"checked": function( elem ) { | |
// In CSS3, :checked should return both checked and selected elements | |
// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked | |
var nodeName = elem.nodeName.toLowerCase(); | |
return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); | |
}, | |
"selected": function( elem ) { | |
// Accessing this property makes selected-by-default | |
// options in Safari work properly | |
if ( elem.parentNode ) { | |
elem.parentNode.selectedIndex; | |
} | |
return elem.selected === true; | |
}, | |
// Contents | |
"empty": function( elem ) { | |
// http://www.w3.org/TR/selectors/#empty-pseudo | |
// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), | |
// not comment, processing instructions, or others | |
// Thanks to Diego Perini for the nodeName shortcut | |
// Greater than "@" means alpha characters (specifically not starting with "#" or "?") | |
for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { | |
if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { | |
return false; | |
} | |
} | |
return true; | |
}, | |
"parent": function( elem ) { | |
return !Expr.pseudos["empty"]( elem ); | |
}, | |
// Element/input types | |
"header": function( elem ) { | |
return rheader.test( elem.nodeName ); | |
}, | |
"input": function( elem ) { | |
return rinputs.test( elem.nodeName ); | |
}, | |
"button": function( elem ) { | |
var name = elem.nodeName.toLowerCase(); | |
return name === "input" && elem.type === "button" || name === "button"; | |
}, | |
"text": function( elem ) { | |
var attr; | |
// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) | |
// use getAttribute instead to test this case | |
return elem.nodeName.toLowerCase() === "input" && | |
elem.type === "text" && | |
( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); | |
}, | |
// Position-in-collection | |
"first": createPositionalPseudo(function() { | |
return [ 0 ]; | |
}), | |
"last": createPositionalPseudo(function( matchIndexes, length ) { | |
return [ length - 1 ]; | |
}), | |
"eq": createPositionalPseudo(function( matchIndexes, length, argument ) { | |
return [ argument < 0 ? argument + length : argument ]; | |
}), | |
"even": createPositionalPseudo(function( matchIndexes, length ) { | |
var i = 0; | |
for ( ; i < length; i += 2 ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}), | |
"odd": createPositionalPseudo(function( matchIndexes, length ) { | |
var i = 1; | |
for ( ; i < length; i += 2 ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}), | |
"lt": createPositionalPseudo(function( matchIndexes, length, argument ) { | |
var i = argument < 0 ? argument + length : argument; | |
for ( ; --i >= 0; ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}), | |
"gt": createPositionalPseudo(function( matchIndexes, length, argument ) { | |
var i = argument < 0 ? argument + length : argument; | |
for ( ; ++i < length; ) { | |
matchIndexes.push( i ); | |
} | |
return matchIndexes; | |
}) | |
} | |
}; | |
// Add button/input type pseudos | |
for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { | |
Expr.pseudos[ i ] = createInputPseudo( i ); | |
} | |
for ( i in { submit: true, reset: true } ) { | |
Expr.pseudos[ i ] = createButtonPseudo( i ); | |
} | |
function tokenize( selector, parseOnly ) { | |
var matched, match, tokens, type, | |
soFar, groups, preFilters, | |
cached = tokenCache[ selector + " " ]; | |
if ( cached ) { | |
return parseOnly ? 0 : cached.slice( 0 ); | |
} | |
soFar = selector; | |
groups = []; | |
preFilters = Expr.preFilter; | |
while ( soFar ) { | |
// Comma and first run | |
if ( !matched || (match = rcomma.exec( soFar )) ) { | |
if ( match ) { | |
// Don't consume trailing commas as valid | |
soFar = soFar.slice( match[0].length ) || soFar; | |
} | |
groups.push( tokens = [] ); | |
} | |
matched = false; | |
// Combinators | |
if ( (match = rcombinators.exec( soFar )) ) { | |
matched = match.shift(); | |
tokens.push( { | |
value: matched, | |
// Cast descendant combinators to space | |
type: match[0].replace( rtrim, " " ) | |
} ); | |
soFar = soFar.slice( matched.length ); | |
} | |
// Filters | |
for ( type in Expr.filter ) { | |
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || | |
(match = preFilters[ type ]( match ))) ) { | |
matched = match.shift(); | |
tokens.push( { | |
value: matched, | |
type: type, | |
matches: match | |
} ); | |
soFar = soFar.slice( matched.length ); | |
} | |
} | |
if ( !matched ) { | |
break; | |
} | |
} | |
// Return the length of the invalid excess | |
// if we're just parsing | |
// Otherwise, throw an error or return tokens | |
return parseOnly ? | |
soFar.length : | |
soFar ? | |
Sizzle.error( selector ) : | |
// Cache the tokens | |
tokenCache( selector, groups ).slice( 0 ); | |
} | |
function toSelector( tokens ) { | |
var i = 0, | |
len = tokens.length, | |
selector = ""; | |
for ( ; i < len; i++ ) { | |
selector += tokens[i].value; | |
} | |
return selector; | |
} | |
function addCombinator( matcher, combinator, base ) { | |
var dir = combinator.dir, | |
checkNonElements = base && dir === "parentNode", | |
doneName = done++; | |
return combinator.first ? | |
// Check against closest ancestor/preceding element | |
function( elem, context, xml ) { | |
while ( (elem = elem[ dir ]) ) { | |
if ( elem.nodeType === 1 || checkNonElements ) { | |
return matcher( elem, context, xml ); | |
} | |
} | |
} : | |
// Check against all ancestor/preceding elements | |
function( elem, context, xml ) { | |
var data, cache, outerCache, | |
dirkey = dirruns + " " + doneName; | |
// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching | |
if ( xml ) { | |
while ( (elem = elem[ dir ]) ) { | |
if ( elem.nodeType === 1 || checkNonElements ) { | |
if ( matcher( elem, context, xml ) ) { | |
return true; | |
} | |
} | |
} | |
} else { | |
while ( (elem = elem[ dir ]) ) { | |
if ( elem.nodeType === 1 || checkNonElements ) { | |
outerCache = elem[ expando ] || (elem[ expando ] = {}); | |
if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { | |
if ( (data = cache[1]) === true || data === cachedruns ) { | |
return data === true; | |
} | |
} else { | |
cache = outerCache[ dir ] = [ dirkey ]; | |
cache[1] = matcher( elem, context, xml ) || cachedruns; | |
if ( cache[1] === true ) { | |
return true; | |
} | |
} | |
} | |
} | |
} | |
}; | |
} | |
function elementMatcher( matchers ) { | |
return matchers.length > 1 ? | |
function( elem, context, xml ) { | |
var i = matchers.length; | |
while ( i-- ) { | |
if ( !matchers[i]( elem, context, xml ) ) { | |
return false; | |
} | |
} | |
return true; | |
} : | |
matchers[0]; | |
} | |
function condense( unmatched, map, filter, context, xml ) { | |
var elem, | |
newUnmatched = [], | |
i = 0, | |
len = unmatched.length, | |
mapped = map != null; | |
for ( ; i < len; i++ ) { | |
if ( (elem = unmatched[i]) ) { | |
if ( !filter || filter( elem, context, xml ) ) { | |
newUnmatched.push( elem ); | |
if ( mapped ) { | |
map.push( i ); | |
} | |
} | |
} | |
} | |
return newUnmatched; | |
} | |
function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { | |
if ( postFilter && !postFilter[ expando ] ) { | |
postFilter = setMatcher( postFilter ); | |
} | |
if ( postFinder && !postFinder[ expando ] ) { | |
postFinder = setMatcher( postFinder, postSelector ); | |
} | |
return markFunction(function( seed, results, context, xml ) { | |
var temp, i, elem, | |
preMap = [], | |
postMap = [], | |
preexisting = results.length, | |
// Get initial elements from seed or context | |
elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), | |
// Prefilter to get matcher input, preserving a map for seed-results synchronization | |
matcherIn = preFilter && ( seed || !selector ) ? | |
condense( elems, preMap, preFilter, context, xml ) : | |
elems, | |
matcherOut = matcher ? | |
// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, | |
postFinder || ( seed ? preFilter : preexisting || postFilter ) ? | |
// ...intermediate processing is necessary | |
[] : | |
// ...otherwise use results directly | |
results : | |
matcherIn; | |
// Find primary matches | |
if ( matcher ) { | |
matcher( matcherIn, matcherOut, context, xml ); | |
} | |
// Apply postFilter | |
if ( postFilter ) { | |
temp = condense( matcherOut, postMap ); | |
postFilter( temp, [], context, xml ); | |
// Un-match failing elements by moving them back to matcherIn | |
i = temp.length; | |
while ( i-- ) { | |
if ( (elem = temp[i]) ) { | |
matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); | |
} | |
} | |
} | |
if ( seed ) { | |
if ( postFinder || preFilter ) { | |
if ( postFinder ) { | |
// Get the final matcherOut by condensing this intermediate into postFinder contexts | |
temp = []; | |
i = matcherOut.length; | |
while ( i-- ) { | |
if ( (elem = matcherOut[i]) ) { | |
// Restore matcherIn since elem is not yet a final match | |
temp.push( (matcherIn[i] = elem) ); | |
} | |
} | |
postFinder( null, (matcherOut = []), temp, xml ); | |
} | |
// Move matched elements from seed to results to keep them synchronized | |
i = matcherOut.length; | |
while ( i-- ) { | |
if ( (elem = matcherOut[i]) && | |
(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { | |
seed[temp] = !(results[temp] = elem); | |
} | |
} | |
} | |
// Add elements to results, through postFinder if defined | |
} else { | |
matcherOut = condense( | |
matcherOut === results ? | |
matcherOut.splice( preexisting, matcherOut.length ) : | |
matcherOut | |
); | |
if ( postFinder ) { | |
postFinder( null, results, matcherOut, xml ); | |
} else { | |
push.apply( results, matcherOut ); | |
} | |
} | |
}); | |
} | |
function matcherFromTokens( tokens ) { | |
var checkContext, matcher, j, | |
len = tokens.length, | |
leadingRelative = Expr.relative[ tokens[0].type ], | |
implicitRelative = leadingRelative || Expr.relative[" "], | |
i = leadingRelative ? 1 : 0, | |
// The foundational matcher ensures that elements are reachable from top-level context(s) | |
matchContext = addCombinator( function( elem ) { | |
return elem === checkContext; | |
}, implicitRelative, true ), | |
matchAnyContext = addCombinator( function( elem ) { | |
return indexOf.call( checkContext, elem ) > -1; | |
}, implicitRelative, true ), | |
matchers = [ function( elem, context, xml ) { | |
return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( | |
(checkContext = context).nodeType ? | |
matchContext( elem, context, xml ) : | |
matchAnyContext( elem, context, xml ) ); | |
} ]; | |
for ( ; i < len; i++ ) { | |
if ( (matcher = Expr.relative[ tokens[i].type ]) ) { | |
matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; | |
} else { | |
matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); | |
// Return special upon seeing a positional matcher | |
if ( matcher[ expando ] ) { | |
// Find the next relative operator (if any) for proper handling | |
j = ++i; | |
for ( ; j < len; j++ ) { | |
if ( Expr.relative[ tokens[j].type ] ) { | |
break; | |
} | |
} | |
return setMatcher( | |
i > 1 && elementMatcher( matchers ), | |
i > 1 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ), | |
matcher, | |
i < j && matcherFromTokens( tokens.slice( i, j ) ), | |
j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), | |
j < len && toSelector( tokens ) | |
); | |
} | |
matchers.push( matcher ); | |
} | |
} | |
return elementMatcher( matchers ); | |
} | |
function matcherFromGroupMatchers( elementMatchers, setMatchers ) { | |
// A counter to specify which element is currently being matched | |
var matcherCachedRuns = 0, | |
bySet = setMatchers.length > 0, | |
byElement = elementMatchers.length > 0, | |
superMatcher = function( seed, context, xml, results, expandContext ) { | |
var elem, j, matcher, | |
setMatched = [], | |
matchedCount = 0, | |
i = "0", | |
unmatched = seed && [], | |
outermost = expandContext != null, | |
contextBackup = outermostContext, | |
// We must always have either seed elements or context | |
elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), | |
// Use integer dirruns iff this is the outermost matcher | |
dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); | |
if ( outermost ) { | |
outermostContext = context !== document && context; | |
cachedruns = matcherCachedRuns; | |
} | |
// Add elements passing elementMatchers directly to results | |
// Keep `i` a string if there are no elements so `matchedCount` will be "00" below | |
for ( ; (elem = elems[i]) != null; i++ ) { | |
if ( byElement && elem ) { | |
j = 0; | |
while ( (matcher = elementMatchers[j++]) ) { | |
if ( matcher( elem, context, xml ) ) { | |
results.push( elem ); | |
break; | |
} | |
} | |
if ( outermost ) { | |
dirruns = dirrunsUnique; | |
cachedruns = ++matcherCachedRuns; | |
} | |
} | |
// Track unmatched elements for set filters | |
if ( bySet ) { | |
// They will have gone through all possible matchers | |
if ( (elem = !matcher && elem) ) { | |
matchedCount--; | |
} | |
// Lengthen the array for every element, matched or not | |
if ( seed ) { | |
unmatched.push( elem ); | |
} | |
} | |
} | |
// Apply set filters to unmatched elements | |
matchedCount += i; | |
if ( bySet && i !== matchedCount ) { | |
j = 0; | |
while ( (matcher = setMatchers[j++]) ) { | |
matcher( unmatched, setMatched, context, xml ); | |
} | |
if ( seed ) { | |
// Reintegrate element matches to eliminate the need for sorting | |
if ( matchedCount > 0 ) { | |
while ( i-- ) { | |
if ( !(unmatched[i] || setMatched[i]) ) { | |
setMatched[i] = pop.call( results ); | |
} | |
} | |
} | |
// Discard index placeholder values to get only actual matches | |
setMatched = condense( setMatched ); | |
} | |
// Add matches to results | |
push.apply( results, setMatched ); | |
// Seedless set matches succeeding multiple successful matchers stipulate sorting | |
if ( outermost && !seed && setMatched.length > 0 && | |
( matchedCount + setMatchers.length ) > 1 ) { | |
Sizzle.uniqueSort( results ); | |
} | |
} | |
// Override manipulation of globals by nested matchers | |
if ( outermost ) { | |
dirruns = dirrunsUnique; | |
outermostContext = contextBackup; | |
} | |
return unmatched; | |
}; | |
return bySet ? | |
markFunction( superMatcher ) : | |
superMatcher; | |
} | |
compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { | |
var i, | |
setMatchers = [], | |
elementMatchers = [], | |
cached = compilerCache[ selector + " " ]; | |
if ( !cached ) { | |
// Generate a function of recursive functions that can be used to check each element | |
if ( !group ) { | |
group = tokenize( selector ); | |
} | |
i = group.length; | |
while ( i-- ) { | |
cached = matcherFromTokens( group[i] ); | |
if ( cached[ expando ] ) { | |
setMatchers.push( cached ); | |
} else { | |
elementMatchers.push( cached ); | |
} | |
} | |
// Cache the compiled function | |
cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); | |
} | |
return cached; | |
}; | |
function multipleContexts( selector, contexts, results ) { | |
var i = 0, | |
len = contexts.length; | |
for ( ; i < len; i++ ) { | |
Sizzle( selector, contexts[i], results ); | |
} | |
return results; | |
} | |
function select( selector, context, results, seed ) { | |
var i, tokens, token, type, find, | |
match = tokenize( selector ); | |
if ( !seed ) { | |
// Try to minimize operations if there is only one group | |
if ( match.length === 1 ) { | |
// Take a shortcut and set the context if the root selector is an ID | |
tokens = match[0] = match[0].slice( 0 ); | |
if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && | |
context.nodeType === 9 && documentIsHTML && | |
Expr.relative[ tokens[1].type ] ) { | |
context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; | |
if ( !context ) { | |
return results; | |
} | |
selector = selector.slice( tokens.shift().value.length ); | |
} | |
// Fetch a seed set for right-to-left matching | |
i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; | |
while ( i-- ) { | |
token = tokens[i]; | |
// Abort if we hit a combinator | |
if ( Expr.relative[ (type = token.type) ] ) { | |
break; | |
} | |
if ( (find = Expr.find[ type ]) ) { | |
// Search, expanding context for leading sibling combinators | |
if ( (seed = find( | |
token.matches[0].replace( runescape, funescape ), | |
rsibling.test( tokens[0].type ) && context.parentNode || context | |
)) ) { | |
// If seed is empty or no tokens remain, we can return early | |
tokens.splice( i, 1 ); | |
selector = seed.length && toSelector( tokens ); | |
if ( !selector ) { | |
push.apply( results, seed ); | |
return results; | |
} | |
break; | |
} | |
} | |
} | |
} | |
} | |
// Compile and execute a filtering function | |
// Provide `match` to avoid retokenization if we modified the selector above | |
compile( selector, match )( | |
seed, | |
context, | |
!documentIsHTML, | |
results, | |
rsibling.test( selector ) | |
); | |
return results; | |
} | |
// Deprecated | |
Expr.pseudos["nth"] = Expr.pseudos["eq"]; | |
// Easy API for creating new setFilters | |
function setFilters() {} | |
setFilters.prototype = Expr.filters = Expr.pseudos; | |
Expr.setFilters = new setFilters(); | |
// One-time assignments | |
// Sort stability | |
support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; | |
// Initialize against the default document | |
setDocument(); | |
// Support: Chrome<<14 | |
// Always assume duplicates if they aren't passed to the comparison function | |
[0, 0].sort( sortOrder ); | |
support.detectDuplicates = hasDuplicate; | |
// Support: IE<8 | |
// Prevent attribute/property "interpolation" | |
assert(function( div ) { | |
div.innerHTML = "<a href='#'></a>"; | |
if ( div.firstChild.getAttribute("href") !== "#" ) { | |
var attrs = "type|href|height|width".split("|"), | |
i = attrs.length; | |
while ( i-- ) { | |
Expr.attrHandle[ attrs[i] ] = interpolationHandler; | |
} | |
} | |
}); | |
// Support: IE<9 | |
// Use getAttributeNode to fetch booleans when getAttribute lies | |
assert(function( div ) { | |
if ( div.getAttribute("disabled") != null ) { | |
var attrs = booleans.split("|"), | |
i = attrs.length; | |
while ( i-- ) { | |
Expr.attrHandle[ attrs[i] ] = boolHandler; | |
} | |
} | |
}); | |
jQuery.find = Sizzle; | |
jQuery.expr = Sizzle.selectors; | |
jQuery.expr[":"] = jQuery.expr.pseudos; | |
jQuery.unique = Sizzle.uniqueSort; | |
jQuery.text = Sizzle.getText; | |
jQuery.isXMLDoc = Sizzle.isXML; | |
jQuery.contains = Sizzle.contains; | |
})( window ); | |
// String to Object options format cache | |
var optionsCache = {}; | |
// Convert String-formatted options into Object-formatted ones and store in cache | |
function createOptions( options ) { | |
var object = optionsCache[ options ] = {}; | |
jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { | |
object[ flag ] = true; | |
}); | |
return object; | |
} | |
/* | |
* Create a callback list using the following parameters: | |
* | |
* options: an optional list of space-separated options that will change how | |
* the callback list behaves or a more traditional option object | |
* | |
* By default a callback list will act like an event callback list and can be | |
* "fired" multiple times. | |
* | |
* Possible options: | |
* | |
* once: will ensure the callback list can only be fired once (like a Deferred) | |
* | |
* memory: will keep track of previous values and will call any callback added | |
* after the list has been fired right away with the latest "memorized" | |
* values (like a Deferred) | |
* | |
* unique: will ensure a callback can only be added once (no duplicate in the list) | |
* | |
* stopOnFalse: interrupt callings when a callback returns false | |
* | |
*/ | |
jQuery.Callbacks = function( options ) { | |
// Convert options from String-formatted to Object-formatted if needed | |
// (we check in cache first) | |
options = typeof options === "string" ? | |
( optionsCache[ options ] || createOptions( options ) ) : | |
jQuery.extend( {}, options ); | |
var // Last fire value (for non-forgettable lists) | |
memory, | |
// Flag to know if list was already fired | |
fired, | |
// Flag to know if list is currently firing | |
firing, | |
// First callback to fire (used internally by add and fireWith) | |
firingStart, | |
// End of the loop when firing | |
firingLength, | |
// Index of currently firing callback (modified by remove if needed) | |
firingIndex, | |
// Actual callback list | |
list = [], | |
// Stack of fire calls for repeatable lists | |
stack = !options.once && [], | |
// Fire callbacks | |
fire = function( data ) { | |
memory = options.memory && data; | |
fired = true; | |
firingIndex = firingStart || 0; | |
firingStart = 0; | |
firingLength = list.length; | |
firing = true; | |
for ( ; list && firingIndex < firingLength; firingIndex++ ) { | |
if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { | |
memory = false; // To prevent further calls using add | |
break; | |
} | |
} | |
firing = false; | |
if ( list ) { | |
if ( stack ) { | |
if ( stack.length ) { | |
fire( stack.shift() ); | |
} | |
} else if ( memory ) { | |
list = []; | |
} else { | |
self.disable(); | |
} | |
} | |
}, | |
// Actual Callbacks object | |
self = { | |
// Add a callback or a collection of callbacks to the list | |
add: function() { | |
if ( list ) { | |
// First, we save the current length | |
var start = list.length; | |
(function add( args ) { | |
jQuery.each( args, function( _, arg ) { | |
var type = jQuery.type( arg ); | |
if ( type === "function" ) { | |
if ( !options.unique || !self.has( arg ) ) { | |
list.push( arg ); | |
} | |
} else if ( arg && arg.length && type !== "string" ) { | |
// Inspect recursively | |
add( arg ); | |
} | |
}); | |
})( arguments ); | |
// Do we need to add the callbacks to the | |
// current firing batch? | |
if ( firing ) { | |
firingLength = list.length; | |
// With memory, if we're not firing then | |
// we should call right away | |
} else if ( memory ) { | |
firingStart = start; | |
fire( memory ); | |
} | |
} | |
return this; | |
}, | |
// Remove a callback from the list | |
remove: function() { | |
if ( list ) { | |
jQuery.each( arguments, function( _, arg ) { | |
var index; | |
while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { | |
list.splice( index, 1 ); | |
// Handle firing indexes | |
if ( firing ) { | |
if ( index <= firingLength ) { | |
firingLength--; | |
} | |
if ( index <= firingIndex ) { | |
firingIndex--; | |
} | |
} | |
} | |
}); | |
} | |
return this; | |
}, | |
// Check if a given callback is in the list. | |
// If no argument is given, return whether or not list has callbacks attached. | |
has: function( fn ) { | |
return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); | |
}, | |
// Remove all callbacks from the list | |
empty: function() { | |
list = []; | |
firingLength = 0; | |
return this; | |
}, | |
// Have the list do nothing anymore | |
disable: function() { | |
list = stack = memory = undefined; | |
return this; | |
}, | |
// Is it disabled? | |
disabled: function() { | |
return !list; | |
}, | |
// Lock the list in its current state | |
lock: function() { | |
stack = undefined; | |
if ( !memory ) { | |
self.disable(); | |
} | |
return this; | |
}, | |
// Is it locked? | |
locked: function() { | |
return !stack; | |
}, | |
// Call all callbacks with the given context and arguments | |
fireWith: function( context, args ) { | |
args = args || []; | |
args = [ context, args.slice ? args.slice() : args ]; | |
if ( list && ( !fired || stack ) ) { | |
if ( firing ) { | |
stack.push( args ); | |
} else { | |
fire( args ); | |
} | |
} | |
return this; | |
}, | |
// Call all the callbacks with the given arguments | |
fire: function() { | |
self.fireWith( this, arguments ); | |
return this; | |
}, | |
// To know if the callbacks have already been called at least once | |
fired: function() { | |
return !!fired; | |
} | |
}; | |
return self; | |
}; | |
jQuery.extend({ | |
Deferred: function( func ) { | |
var tuples = [ | |
// action, add listener, listener list, final state | |
[ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], | |
[ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], | |
[ "notify", "progress", jQuery.Callbacks("memory") ] | |
], | |
state = "pending", | |
promise = { | |
state: function() { | |
return state; | |
}, | |
always: function() { | |
deferred.done( arguments ).fail( arguments ); | |
return this; | |
}, | |
then: function( /* fnDone, fnFail, fnProgress */ ) { | |
var fns = arguments; | |
return jQuery.Deferred(function( newDefer ) { | |
jQuery.each( tuples, function( i, tuple ) { | |
var action = tuple[ 0 ], | |
fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; | |
// deferred[ done | fail | progress ] for forwarding actions to newDefer | |
deferred[ tuple[1] ](function() { | |
var returned = fn && fn.apply( this, arguments ); | |
if ( returned && jQuery.isFunction( returned.promise ) ) { | |
returned.promise() | |
.done( newDefer.resolve ) | |
.fail( newDefer.reject ) | |
.progress( newDefer.notify ); | |
} else { | |
newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); | |
} | |
}); | |
}); | |
fns = null; | |
}).promise(); | |
}, | |
// Get a promise for this deferred | |
// If obj is provided, the promise aspect is added to the object | |
promise: function( obj ) { | |
return obj != null ? jQuery.extend( obj, promise ) : promise; | |
} | |
}, | |
deferred = {}; | |
// Keep pipe for back-compat | |
promise.pipe = promise.then; | |
// Add list-specific methods | |
jQuery.each( tuples, function( i, tuple ) { | |
var list = tuple[ 2 ], | |
stateString = tuple[ 3 ]; | |
// promise[ done | fail | progress ] = list.add | |
promise[ tuple[1] ] = list.add; | |
// Handle state | |
if ( stateString ) { | |
list.add(function() { | |
// state = [ resolved | rejected ] | |
state = stateString; | |
// [ reject_list | resolve_list ].disable; progress_list.lock | |
}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); | |
} | |
// deferred[ resolve | reject | notify ] | |
deferred[ tuple[0] ] = function() { | |
deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); | |
return this; | |
}; | |
deferred[ tuple[0] + "With" ] = list.fireWith; | |
}); | |
// Make the deferred a promise | |
promise.promise( deferred ); | |
// Call given func if any | |
if ( func ) { | |
func.call( deferred, deferred ); | |
} | |
// All done! | |
return deferred; | |
}, | |
// Deferred helper | |
when: function( subordinate /* , ..., subordinateN */ ) { | |
var i = 0, | |
resolveValues = core_slice.call( arguments ), | |
length = resolveValues.length, | |
// the count of uncompleted subordinates | |
remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, | |
// the master Deferred. If resolveValues consist of only a single Deferred, just use that. | |
deferred = remaining === 1 ? subordinate : jQuery.Deferred(), | |
// Update function for both resolve and progress values | |
updateFunc = function( i, contexts, values ) { | |
return function( value ) { | |
contexts[ i ] = this; | |
values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; | |
if( values === progressValues ) { | |
deferred.notifyWith( contexts, values ); | |
} else if ( !( --remaining ) ) { | |
deferred.resolveWith( contexts, values ); | |
} | |
}; | |
}, | |
progressValues, progressContexts, resolveContexts; | |
// add listeners to Deferred subordinates; treat others as resolved | |
if ( length > 1 ) { | |
progressValues = new Array( length ); | |
progressContexts = new Array( length ); | |
resolveContexts = new Array( length ); | |
for ( ; i < length; i++ ) { | |
if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { | |
resolveValues[ i ].promise() | |
.done( updateFunc( i, resolveContexts, resolveValues ) ) | |
.fail( deferred.reject ) | |
.progress( updateFunc( i, progressContexts, progressValues ) ); | |
} else { | |
--remaining; | |
} | |
} | |
} | |
// if we're not waiting on anything, resolve the master | |
if ( !remaining ) { | |
deferred.resolveWith( resolveContexts, resolveValues ); | |
} | |
return deferred.promise(); | |
} | |
}); | |
jQuery.support = (function( support ) { | |
var input = document.createElement("input"), | |
fragment = document.createDocumentFragment(), | |
div = document.createElement("div"), | |
select = document.createElement("select"), | |
opt = select.appendChild( document.createElement("option") ); | |
// Finish early in limited environments | |
if ( !input.type ) { | |
return support; | |
} | |
input.type = "checkbox"; | |
// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 | |
// Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere) | |
support.checkOn = input.value !== ""; | |
// Must access the parent to make an option select properly | |
// Support: IE9, IE10 | |
support.optSelected = opt.selected; | |
// Will be defined later | |
support.reliableMarginRight = true; | |
support.boxSizingReliable = true; | |
support.pixelPosition = false; | |
// Make sure checked status is properly cloned | |
// Support: IE9, IE10 | |
input.checked = true; | |
support.noCloneChecked = input.cloneNode( true ).checked; | |
// Make sure that the options inside disabled selects aren't marked as disabled | |
// (WebKit marks them as disabled) | |
select.disabled = true; | |
support.optDisabled = !opt.disabled; | |
// Check if an input maintains its value after becoming a radio | |
// Support: IE9, IE10 | |
input = document.createElement("input"); | |
input.value = "t"; | |
input.type = "radio"; | |
support.radioValue = input.value === "t"; | |
// #11217 - WebKit loses check when the name is after the checked attribute | |
input.setAttribute( "checked", "t" ); | |
input.setAttribute( "name", "t" ); | |
fragment.appendChild( input ); | |
// Support: Safari 5.1, Android 4.x, Android 2.3 | |
// old WebKit doesn't clone checked state correctly in fragments | |
support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; | |
// Support: Firefox, Chrome, Safari | |
// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) | |
support.focusinBubbles = "onfocusin" in window; | |
div.style.backgroundClip = "content-box"; | |
div.cloneNode( true ).style.backgroundClip = ""; | |
support.clearCloneStyle = div.style.backgroundClip === "content-box"; | |
// Run tests that need a body at doc ready | |
jQuery(function() { | |
var container, marginDiv, | |
// Support: Firefox, Android 2.3 (Prefixed box-sizing versions). | |
divReset = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box", | |
body = document.getElementsByTagName("body")[ 0 ]; | |
if ( !body ) { | |
// Return for frameset docs that don't have a body | |
return; | |
} | |
container = document.createElement("div"); | |
container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; | |
// Check box-sizing and margin behavior. | |
body.appendChild( container ).appendChild( div ); | |
div.innerHTML = ""; | |
// Support: Firefox, Android 2.3 (Prefixed box-sizing versions). | |
div.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%"; | |
// Workaround failing boxSizing test due to offsetWidth returning wrong value | |
// with some non-1 values of body zoom, ticket #13543 | |
jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { | |
support.boxSizing = div.offsetWidth === 4; | |
}); | |
// Use window.getComputedStyle because jsdom on node.js will break without it. | |
if ( window.getComputedStyle ) { | |
support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; | |
support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; | |
// Support: Android 2.3 | |
// Check if div with explicit width and no margin-right incorrectly | |
// gets computed margin-right based on width of container. (#3333) | |
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right | |
marginDiv = div.appendChild( document.createElement("div") ); | |
marginDiv.style.cssText = div.style.cssText = divReset; | |
marginDiv.style.marginRight = marginDiv.style.width = "0"; | |
div.style.width = "1px"; | |
support.reliableMarginRight = | |
!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); | |
} | |
body.removeChild( container ); | |
}); | |
return support; | |
})( {} ); | |
/* | |
Implementation Summary | |
1. Enforce API surface and semantic compatibility with 1.9.x branch | |
2. Improve the module's maintainability by reducing the storage | |
paths to a single mechanism. | |
3. Use the same single mechanism to support "private" and "user" data. | |
4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) | |
5. Avoid exposing implementation details on user objects (eg. expando properties) | |
6. Provide a clear path for implementation upgrade to WeakMap in 2014 | |
*/ | |
var data_user, data_priv, | |
rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, | |
rmultiDash = /([A-Z])/g; | |
function Data() { | |
// Support: Android < 4, | |
// Old WebKit does not have Object.preventExtensions/freeze method, | |
// return new empty object instead with no [[set]] accessor | |
Object.defineProperty( this.cache = {}, 0, { | |
get: function() { | |
return {}; | |
} | |
}); | |
this.expando = jQuery.expando + Math.random(); | |
} | |
Data.uid = 1; | |
Data.accepts = function( owner ) { | |
// Accepts only: | |
// - Node | |
// - Node.ELEMENT_NODE | |
// - Node.DOCUMENT_NODE | |
// - Object | |
// - Any | |
return owner.nodeType ? | |
owner.nodeType === 1 || owner.nodeType === 9 : true; | |
}; | |
Data.prototype = { | |
key: function( owner ) { | |
// We can accept data for non-element nodes in modern browsers, | |
// but we should not, see #8335. | |
// Always return the key for a frozen object. | |
if ( !Data.accepts( owner ) ) { | |
return 0; | |
} | |
var descriptor = {}, | |
// Check if the owner object already has a cache key | |
unlock = owner[ this.expando ]; | |
// If not, create one | |
if ( !unlock ) { | |
unlock = Data.uid++; | |
// Secure it in a non-enumerable, non-writable property | |
try { | |
descriptor[ this.expando ] = { value: unlock }; | |
Object.defineProperties( owner, descriptor ); | |
// Support: Android < 4 | |
// Fallback to a less secure definition | |
} catch ( e ) { | |
descriptor[ this.expando ] = unlock; | |
jQuery.extend( owner, descriptor ); | |
} | |
} | |
// Ensure the cache object | |
if ( !this.cache[ unlock ] ) { | |
this.cache[ unlock ] = {}; | |
} | |
return unlock; | |
}, | |
set: function( owner, data, value ) { | |
var prop, | |
// There may be an unlock assigned to this node, | |
// if there is no entry for this "owner", create one inline | |
// and set the unlock as though an owner entry had always existed | |
unlock = this.key( owner ), | |
cache = this.cache[ unlock ]; | |
// Handle: [ owner, key, value ] args | |
if ( typeof data === "string" ) { | |
cache[ data ] = value; | |
// Handle: [ owner, { properties } ] args | |
} else { | |
// Support an expectation from the old data system where plain | |
// objects used to initialize would be set to the cache by | |
// reference, instead of having properties and values copied. | |
// Note, this will kill the connection between | |
// "this.cache[ unlock ]" and "cache" | |
if ( jQuery.isEmptyObject( cache ) ) { | |
this.cache[ unlock ] = data; | |
// Otherwise, copy the properties one-by-one to the cache object | |
} else { | |
for ( prop in data ) { | |
cache[ prop ] = data[ prop ]; | |
} | |
} | |
} | |
}, | |
get: function( owner, key ) { | |
// Either a valid cache is found, or will be created. | |
// New caches will be created and the unlock returned, | |
// allowing direct access to the newly created | |
// empty data object. A valid owner object must be provided. | |
var cache = this.cache[ this.key( owner ) ]; | |
return key === undefined ? | |
cache : cache[ key ]; | |
}, | |
access: function( owner, key, value ) { | |
// In cases where either: | |
// | |
// 1. No key was specified | |
// 2. A string key was specified, but no value provided | |
// | |
// Take the "read" path and allow the get method to determine | |
// which value to return, respectively either: | |
// | |
// 1. The entire cache object | |
// 2. The data stored at the key | |
// | |
if ( key === undefined || | |
((key && typeof key === "string") && value === undefined) ) { | |
return this.get( owner, key ); | |
} | |
// [*]When the key is not a string, or both a key and value | |
// are specified, set or extend (existing objects) with either: | |
// | |
// 1. An object of properties | |
// 2. A key and value | |
// | |
this.set( owner, key, value ); | |
// Since the "set" path can have two possible entry points | |
// return the expected data based on which path was taken[*] | |
return value !== undefined ? value : key; | |
}, | |
remove: function( owner, key ) { | |
var i, name, | |
unlock = this.key( owner ), | |
cache = this.cache[ unlock ]; | |
if ( key === undefined ) { | |
this.cache[ unlock ] = {}; | |
} else { | |
// Support array or space separated string of keys | |
if ( jQuery.isArray( key ) ) { | |
// If "name" is an array of keys... | |
// When data is initially created, via ("key", "val") signature, | |
// keys will be converted to camelCase. | |
// Since there is no way to tell _how_ a key was added, remove | |
// both plain key and camelCase key. #12786 | |
// This will only penalize the array argument path. | |
name = key.concat( key.map( jQuery.camelCase ) ); | |
} else { | |
// Try the string as a key before any manipulation | |
if ( key in cache ) { | |
name = [ key ]; | |
} else { | |
// If a key with the spaces exists, use it. | |
// Otherwise, create an array by matching non-whitespace | |
name = jQuery.camelCase( key ); | |
name = name in cache ? | |
[ name ] : ( name.match( core_rnotwhite ) || [] ); | |
} | |
} | |
i = name.length; | |
while ( i-- ) { | |
delete cache[ name[ i ] ]; | |
} | |
} | |
}, | |
hasData: function( owner ) { | |
return !jQuery.isEmptyObject( | |
this.cache[ owner[ this.expando ] ] || {} | |
); | |
}, | |
discard: function( owner ) { | |
delete this.cache[ this.key( owner ) ]; | |
} | |
}; | |
// These may be used throughout the jQuery core codebase | |
data_user = new Data(); | |
data_priv = new Data(); | |
jQuery.extend({ | |
acceptData: Data.accepts, | |
hasData: function( elem ) { | |
return data_user.hasData( elem ) || data_priv.hasData( elem ); | |
}, | |
data: function( elem, name, data ) { | |
return data_user.access( elem, name, data ); | |
}, | |
removeData: function( elem, name ) { | |
data_user.remove( elem, name ); | |
}, | |
// TODO: Now that all calls to _data and _removeData have been replaced | |
// with direct calls to data_priv methods, these can be deprecated. | |
_data: function( elem, name, data ) { | |
return data_priv.access( elem, name, data ); | |
}, | |
_removeData: function( elem, name ) { | |
data_priv.remove( elem, name ); | |
} | |
}); | |
jQuery.fn.extend({ | |
data: function( key, value ) { | |
var attrs, name, | |
elem = this[ 0 ], | |
i = 0, | |
data = null; | |
// Gets all values | |
if ( key === undefined ) { | |
if ( this.length ) { | |
data = data_user.get( elem ); | |
if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { | |
attrs = elem.attributes; | |
for ( ; i < attrs.length; i++ ) { | |
name = attrs[ i ].name; | |
if ( name.indexOf( "data-" ) === 0 ) { | |
name = jQuery.camelCase( name.substring(5) ); | |
dataAttr( elem, name, data[ name ] ); | |
} | |
} | |
data_priv.set( elem, "hasDataAttrs", true ); | |
} | |
} | |
return data; | |
} | |
// Sets multiple values | |
if ( typeof key === "object" ) { | |
return this.each(function() { | |
data_user.set( this, key ); | |
}); | |
} | |
return jQuery.access( this, function( value ) { | |
var data, | |
camelKey = jQuery.camelCase( key ); | |
// The calling jQuery object (element matches) is not empty | |
// (and therefore has an element appears at this[ 0 ]) and the | |
// `value` parameter was not undefined. An empty jQuery object | |
// will result in `undefined` for elem = this[ 0 ] which will | |
// throw an exception if an attempt to read a data cache is made. | |
if ( elem && value === undefined ) { | |
// Attempt to get data from the cache | |
// with the key as-is | |
data = data_user.get( elem, key ); | |
if ( data !== undefined ) { | |
return data; | |
} | |
// Attempt to get data from the cache | |
// with the key camelized | |
data = data_user.get( elem, camelKey ); | |
if ( data !== undefined ) { | |
return data; | |
} | |
// Attempt to "discover" the data in | |
// HTML5 custom data-* attrs | |
data = dataAttr( elem, camelKey, undefined ); | |
if ( data !== undefined ) { | |
return data; | |
} | |
// We tried really hard, but the data doesn't exist. | |
return; | |
} | |
// Set the data... | |
this.each(function() { | |
// First, attempt to store a copy or reference of any | |
// data that might've been store with a camelCased key. | |
var data = data_user.get( this, camelKey ); | |
// For HTML5 data-* attribute interop, we have to | |
// store property names with dashes in a camelCase form. | |
// This might not apply to all properties...* | |
data_user.set( this, camelKey, value ); | |
// *... In the case of properties that might _actually_ | |
// have dashes, we need to also store a copy of that | |
// unchanged property. | |
if ( key.indexOf("-") !== -1 && data !== undefined ) { | |
data_user.set( this, key, value ); | |
} | |
}); | |
}, null, value, arguments.length > 1, null, true ); | |
}, | |
removeData: function( key ) { | |
return this.each(function() { | |
data_user.remove( this, key ); | |
}); | |
} | |
}); | |
function dataAttr( elem, key, data ) { | |
var name; | |
// If nothing was found internally, try to fetch any | |
// data from the HTML5 data-* attribute | |
if ( data === undefined && elem.nodeType === 1 ) { | |
name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); | |
data = elem.getAttribute( name ); | |
if ( typeof data === "string" ) { | |
try { | |
data = data === "true" ? true : | |
data === "false" ? false : | |
data === "null" ? null : | |
// Only convert to a number if it doesn't change the string | |
+data + "" === data ? +data : | |
rbrace.test( data ) ? JSON.parse( data ) : | |
data; | |
} catch( e ) {} | |
// Make sure we set the data so it isn't changed later | |
data_user.set( elem, key, data ); | |
} else { | |
data = undefined; | |
} | |
} | |
return data; | |
} | |
jQuery.extend({ | |
queue: function( elem, type, data ) { | |
var queue; | |
if ( elem ) { | |
type = ( type || "fx" ) + "queue"; | |
queue = data_priv.get( elem, type ); | |
// Speed up dequeue by getting out quickly if this is just a lookup | |
if ( data ) { | |
if ( !queue || jQuery.isArray( data ) ) { | |
queue = data_priv.access( elem, type, jQuery.makeArray(data) ); | |
} else { | |
queue.push( data ); | |
} | |
} | |
return queue || []; | |
} | |
}, | |
dequeue: function( elem, type ) { | |
type = type || "fx"; | |
var queue = jQuery.queue( elem, type ), | |
startLength = queue.length, | |
fn = queue.shift(), | |
hooks = jQuery._queueHooks( elem, type ), | |
next = function() { | |
jQuery.dequeue( elem, type ); | |
}; | |
// If the fx queue is dequeued, always remove the progress sentinel | |
if ( fn === "inprogress" ) { | |
fn = queue.shift(); | |
startLength--; | |
} | |
hooks.cur = fn; | |
if ( fn ) { | |
// Add a progress sentinel to prevent the fx queue from being | |
// automatically dequeued | |
if ( type === "fx" ) { | |
queue.unshift( "inprogress" ); | |
} | |
// clear up the last queue stop function | |
delete hooks.stop; | |
fn.call( elem, next, hooks ); | |
} | |
if ( !startLength && hooks ) { | |
hooks.empty.fire(); | |
} | |
}, | |
// not intended for public consumption - generates a queueHooks object, or returns the current one | |
_queueHooks: function( elem, type ) { | |
var key = type + "queueHooks"; | |
return data_priv.get( elem, key ) || data_priv.access( elem, key, { | |
empty: jQuery.Callbacks("once memory").add(function() { | |
data_priv.remove( elem, [ type + "queue", key ] ); | |
}) | |
}); | |
} | |
}); | |
jQuery.fn.extend({ | |
queue: function( type, data ) { | |
var setter = 2; | |
if ( typeof type !== "string" ) { | |
data = type; | |
type = "fx"; | |
setter--; | |
} | |
if ( arguments.length < setter ) { | |
return jQuery.queue( this[0], type ); | |
} | |
return data === undefined ? | |
this : | |
this.each(function() { | |
var queue = jQuery.queue( this, type, data ); | |
// ensure a hooks for this queue | |
jQuery._queueHooks( this, type ); | |
if ( type === "fx" && queue[0] !== "inprogress" ) { | |
jQuery.dequeue( this, type ); | |
} | |
}); | |
}, | |
dequeue: function( type ) { | |
return this.each(function() { | |
jQuery.dequeue( this, type ); | |
}); | |
}, | |
// Based off of the plugin by Clint Helfers, with permission. | |
// http://blindsignals.com/index.php/2009/07/jquery-delay/ | |
delay: function( time, type ) { | |
time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; | |
type = type || "fx"; | |
return this.queue( type, function( next, hooks ) { | |
var timeout = setTimeout( next, time ); | |
hooks.stop = function() { | |
clearTimeout( timeout ); | |
}; | |
}); | |
}, | |
clearQueue: function( type ) { | |
return this.queue( type || "fx", [] ); | |
}, | |
// Get a promise resolved when queues of a certain type | |
// are emptied (fx is the type by default) | |
promise: function( type, obj ) { | |
var tmp, | |
count = 1, | |
defer = jQuery.Deferred(), | |
elements = this, | |
i = this.length, | |
resolve = function() { | |
if ( !( --count ) ) { | |
defer.resolveWith( elements, [ elements ] ); | |
} | |
}; | |
if ( typeof type !== "string" ) { | |
obj = type; | |
type = undefined; | |
} | |
type = type || "fx"; | |
while( i-- ) { | |
tmp = data_priv.get( elements[ i ], type + "queueHooks" ); | |
if ( tmp && tmp.empty ) { | |
count++; | |
tmp.empty.add( resolve ); | |
} | |
} | |
resolve(); | |
return defer.promise( obj ); | |
} | |
}); | |
var nodeHook, boolHook, | |
rclass = /[\t\r\n]/g, | |
rreturn = /\r/g, | |
rfocusable = /^(?:input|select|textarea|button)$/i; | |
jQuery.fn.extend({ | |
attr: function( name, value ) { | |
return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); | |
}, | |
removeAttr: function( name ) { | |
return this.each(function() { | |
jQuery.removeAttr( this, name ); | |
}); | |
}, | |
prop: function( name, value ) { | |
return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); | |
}, | |
removeProp: function( name ) { | |
return this.each(function() { | |
delete this[ jQuery.propFix[ name ] || name ]; | |
}); | |
}, | |
addClass: function( value ) { | |
var classes, elem, cur, clazz, j, | |
i = 0, | |
len = this.length, | |
proceed = typeof value === "string" && value; | |
if ( jQuery.isFunction( value ) ) { | |
return this.each(function( j ) { | |
jQuery( this ).addClass( value.call( this, j, this.className ) ); | |
}); | |
} | |
if ( proceed ) { | |
// The disjunction here is for better compressibility (see removeClass) | |
classes = ( value || "" ).match( core_rnotwhite ) || []; | |
for ( ; i < len; i++ ) { | |
elem = this[ i ]; | |
cur = elem.nodeType === 1 && ( elem.className ? | |
( " " + elem.className + " " ).replace( rclass, " " ) : | |
" " | |
); | |
if ( cur ) { | |
j = 0; | |
while ( (clazz = classes[j++]) ) { | |
if ( cur.indexOf( " " + clazz + " " ) < 0 ) { | |
cur += clazz + " "; | |
} | |
} | |
elem.className = jQuery.trim( cur ); | |
} | |
} | |
} | |
return this; | |
}, | |
removeClass: function( value ) { | |
var classes, elem, cur, clazz, j, | |
i = 0, | |
len = this.length, | |
proceed = arguments.length === 0 || typeof value === "string" && value; | |
if ( jQuery.isFunction( value ) ) { | |
return this.each(function( j ) { | |
jQuery( this ).removeClass( value.call( this, j, this.className ) ); | |
}); | |
} | |
if ( proceed ) { | |
classes = ( value || "" ).match( core_rnotwhite ) || []; | |
for ( ; i < len; i++ ) { | |
elem = this[ i ]; | |
// This expression is here for better compressibility (see addClass) | |
cur = elem.nodeType === 1 && ( elem.className ? | |
( " " + elem.className + " " ).replace( rclass, " " ) : | |
"" | |
); | |
if ( cur ) { | |
j = 0; | |
while ( (clazz = classes[j++]) ) { | |
// Remove *all* instances | |
while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { | |
cur = cur.replace( " " + clazz + " ", " " ); | |
} | |
} | |
elem.className = value ? jQuery.trim( cur ) : ""; | |
} | |
} | |
} | |
return this; | |
}, | |
toggleClass: function( value, stateVal ) { | |
var type = typeof value, | |
isBool = typeof stateVal === "boolean"; | |
if ( jQuery.isFunction( value ) ) { | |
return this.each(function( i ) { | |
jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); | |
}); | |
} | |
return this.each(function() { | |
if ( type === "string" ) { | |
// toggle individual class names | |
var className, | |
i = 0, | |
self = jQuery( this ), | |
state = stateVal, | |
classNames = value.match( core_rnotwhite ) || []; | |
while ( (className = classNames[ i++ ]) ) { | |
// check each className given, space separated list | |
state = isBool ? state : !self.hasClass( className ); | |
self[ state ? "addClass" : "removeClass" ]( className ); | |
} | |
// Toggle whole class name | |
} else if ( type === core_strundefined || type === "boolean" ) { | |
if ( this.className ) { | |
// store className if set | |
data_priv.set( this, "__className__", this.className ); | |
} | |
// If the element has a class name or if we're passed "false", | |
// then remove the whole classname (if there was one, the above saved it). | |
// Otherwise bring back whatever was previously saved (if anything), | |
// falling back to the empty string if nothing was stored. | |
this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || ""; | |
} | |
}); | |
}, | |
hasClass: function( selector ) { | |
var className = " " + selector + " ", | |
i = 0, | |
l = this.length; | |
for ( ; i < l; i++ ) { | |
if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { | |
return true; | |
} | |
} | |
return false; | |
}, | |
val: function( value ) { | |
var hooks, ret, isFunction, | |
elem = this[0]; | |
if ( !arguments.length ) { | |
if ( elem ) { | |
hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; | |
if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { | |
return ret; | |
} | |
ret = elem.value; | |
return typeof ret === "string" ? | |
// handle most common string cases | |
ret.replace(rreturn, "") : | |
// handle cases where value is null/undef or number | |
ret == null ? "" : ret; | |
} | |
return; | |
} | |
isFunction = jQuery.isFunction( value ); | |
return this.each(function( i ) { | |
var val, | |
self = jQuery(this); | |
if ( this.nodeType !== 1 ) { | |
return; | |
} | |
if ( isFunction ) { | |
val = value.call( this, i, self.val() ); | |
} else { | |
val = value; | |
} | |
// Treat null/undefined as ""; convert numbers to string | |
if ( val == null ) { | |
val = ""; | |
} else if ( typeof val === "number" ) { | |
val += ""; | |
} else if ( jQuery.isArray( val ) ) { | |
val = jQuery.map(val, function ( value ) { | |
return value == null ? "" : value + ""; | |
}); | |
} | |
hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; | |
// If set returns undefined, fall back to normal setting | |
if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { | |
this.value = val; | |
} | |
}); | |
} | |
}); | |
jQuery.extend({ | |
valHooks: { | |
option: { | |
get: function( elem ) { | |
// attributes.value is undefined in Blackberry 4.7 but | |
// uses .value. See #6932 | |
var val = elem.attributes.value; | |
return !val || val.specified ? elem.value : elem.text; | |
} | |
}, | |
select: { | |
get: function( elem ) { | |
var value, option, | |
options = elem.options, | |
index = elem.selectedIndex, | |
one = elem.type === "select-one" || index < 0, | |
values = one ? null : [], | |
max = one ? index + 1 : options.length, | |
i = index < 0 ? | |
max : | |
one ? index : 0; | |
// Loop through all the selected options | |
for ( ; i < max; i++ ) { | |
option = options[ i ]; | |
// IE6-9 doesn't update selected after form reset (#2551) | |
if ( ( option.selected || i === index ) && | |
// Don't return options that are disabled or in a disabled optgroup | |
( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && | |
( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { | |
// Get the specific value for the option | |
value = jQuery( option ).val(); | |
// We don't need an array for one selects | |
if ( one ) { | |
return value; | |
} | |
// Multi-Selects return an array | |
values.push( value ); | |
} | |
} | |
return values; | |
}, | |
set: function( elem, value ) { | |
var optionSet, option, | |
options = elem.options, | |
values = jQuery.makeArray( value ), | |
i = options.length; | |
while ( i-- ) { | |
option = options[ i ]; | |
if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { | |
optionSet = true; | |
} | |
} | |
// force browsers to behave consistently when non-matching value is set | |
if ( !optionSet ) { | |
elem.selectedIndex = -1; | |
} | |
return values; | |
} | |
} | |
}, | |
attr: function( elem, name, value ) { | |
var hooks, ret, | |
nType = elem.nodeType; | |
// don't get/set attributes on text, comment and attribute nodes | |
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { | |
return; | |
} | |
// Fallback to prop when attributes are not supported | |
if ( typeof elem.getAttribute === core_strundefined ) { | |
return jQuery.prop( elem, name, value ); | |
} | |
// All attributes are lowercase | |
// Grab necessary hook if one is defined | |
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { | |
name = name.toLowerCase(); | |
hooks = jQuery.attrHooks[ name ] || | |
( jQuery.expr.match.boolean.test( name ) ? boolHook : nodeHook ); | |
} | |
if ( value !== undefined ) { | |
if ( value === null ) { | |
jQuery.removeAttr( elem, name ); | |
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { | |
return ret; | |
} else { | |
elem.setAttribute( name, value + "" ); | |
return value; | |
} | |
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { | |
return ret; | |
} else { | |
ret = jQuery.find.attr( elem, name ); | |
// Non-existent attributes return null, we normalize to undefined | |
return ret == null ? | |
undefined : | |
ret; | |
} | |
}, | |
removeAttr: function( elem, value ) { | |
var name, propName, | |
i = 0, | |
attrNames = value && value.match( core_rnotwhite ); | |
if ( attrNames && elem.nodeType === 1 ) { | |
while ( (name = attrNames[i++]) ) { | |
propName = jQuery.propFix[ name ] || name; | |
// Boolean attributes get special treatment (#10870) | |
if ( jQuery.expr.match.boolean.test( name ) ) { | |
// Set corresponding property to false | |
elem[ propName ] = false; | |
} | |
elem.removeAttribute( name ); | |
} | |
} | |
}, | |
attrHooks: { | |
type: { | |
set: function( elem, value ) { | |
if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { | |
// Setting the type on a radio button after the value resets the value in IE6-9 | |
// Reset value to default in case type is set after value during creation | |
var val = elem.value; | |
elem.setAttribute( "type", value ); | |
if ( val ) { | |
elem.value = val; | |
} | |
return value; | |
} | |
} | |
} | |
}, | |
propFix: { | |
"for": "htmlFor", | |
"class": "className" | |
}, | |
prop: function( elem, name, value ) { | |
var ret, hooks, notxml, | |
nType = elem.nodeType; | |
// don't get/set properties on text, comment and attribute nodes | |
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { | |
return; | |
} | |
notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); | |
if ( notxml ) { | |
// Fix name and attach hooks | |
name = jQuery.propFix[ name ] || name; | |
hooks = jQuery.propHooks[ name ]; | |
} | |
if ( value !== undefined ) { | |
return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? | |
ret : | |
( elem[ name ] = value ); | |
} else { | |
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? | |
ret : | |
elem[ name ]; | |
} | |
}, | |
propHooks: { | |
tabIndex: { | |
get: function( elem ) { | |
return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ? | |
elem.tabIndex : | |
-1; | |
} | |
} | |
} | |
}); | |
// Hooks for boolean attributes | |
boolHook = { | |
set: function( elem, value, name ) { | |
if ( value === false ) { | |
// Remove boolean attributes when set to false | |
jQuery.removeAttr( elem, name ); | |
} else { | |
elem.setAttribute( name, name ); | |
} | |
return name; | |
} | |
}; | |
jQuery.each( jQuery.expr.match.boolean.source.match( /\w+/g ), function( i, name ) { | |
var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; | |
jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) { | |
var fn = jQuery.expr.attrHandle[ name ], | |
ret = isXML ? | |
undefined : | |
/* jshint eqeqeq: false */ | |
// Temporarily disable this handler to check existence | |
(jQuery.expr.attrHandle[ name ] = undefined) != | |
getter( elem, name, isXML ) ? | |
name.toLowerCase() : | |
null; | |
// Restore handler | |
jQuery.expr.attrHandle[ name ] = fn; | |
return ret; | |
}; | |
}); | |
// Support: IE9+ | |
// Selectedness for an option in an optgroup can be inaccurate | |
if ( !jQuery.support.optSelected ) { | |
jQuery.propHooks.selected = { | |
get: function( elem ) { | |
var parent = elem.parentNode; | |
if ( parent && parent.parentNode ) { | |
parent.parentNode.selectedIndex; | |
} | |
return null; | |
} | |
}; | |
} | |
jQuery.each([ | |
"tabIndex", | |
"readOnly", | |
"maxLength", | |
"cellSpacing", | |
"cellPadding", | |
"rowSpan", | |
"colSpan", | |
"useMap", | |
"frameBorder", | |
"contentEditable" | |
], function() { | |
jQuery.propFix[ this.toLowerCase() ] = this; | |
}); | |
// Radios and checkboxes getter/setter | |
jQuery.each([ "radio", "checkbox" ], function() { | |
jQuery.valHooks[ this ] = { | |
set: function( elem, value ) { | |
if ( jQuery.isArray( value ) ) { | |
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); | |
} | |
} | |
}; | |
if ( !jQuery.support.checkOn ) { | |
jQuery.valHooks[ this ].get = function( elem ) { | |
// Support: Webkit | |
// "" is returned instead of "on" if a value isn't specified | |
return elem.getAttribute("value") === null ? "on" : elem.value; | |
}; | |
} | |
}); | |
var rkeyEvent = /^key/, | |
rmouseEvent = /^(?:mouse|contextmenu)|click/, | |
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, | |
rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; | |
function returnTrue() { | |
return true; | |
} | |
function returnFalse() { | |
return false; | |
} | |
function safeActiveElement() { | |
try { | |
return document.activeElement; | |
} catch ( err ) { } | |
} | |
/* | |
* Helper functions for managing events -- not part of the public interface. | |
* Props to Dean Edwards' addEvent library for many of the ideas. | |
*/ | |
jQuery.event = { | |
global: {}, | |
add: function( elem, types, handler, data, selector ) { | |
var handleObjIn, eventHandle, tmp, | |
events, t, handleObj, | |
special, handlers, type, namespaces, origType, | |
elemData = data_priv.get( elem ); | |
// Don't attach events to noData or text/comment nodes (but allow plain objects) | |
if ( !elemData ) { | |
return; | |
} | |
// Caller can pass in an object of custom data in lieu of the handler | |
if ( handler.handler ) { | |
handleObjIn = handler; | |
handler = handleObjIn.handler; | |
selector = handleObjIn.selector; | |
} | |
// Make sure that the handler has a unique ID, used to find/remove it later | |
if ( !handler.guid ) { | |
handler.guid = jQuery.guid++; | |
} | |
// Init the element's event structure and main handler, if this is the first | |
if ( !(events = elemData.events) ) { | |
events = elemData.events = {}; | |
} | |
if ( !(eventHandle = elemData.handle) ) { | |
eventHandle = elemData.handle = function( e ) { | |
// Discard the second event of a jQuery.event.trigger() and | |
// when an event is called after a page has unloaded | |
return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? | |
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : | |
undefined; | |
}; | |
// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events | |
eventHandle.elem = elem; | |
} | |
// Handle multiple events separated by a space | |
types = ( types || "" ).match( core_rnotwhite ) || [""]; | |
t = types.length; | |
while ( t-- ) { | |
tmp = rtypenamespace.exec( types[t] ) || []; | |
type = origType = tmp[1]; | |
namespaces = ( tmp[2] || "" ).split( "." ).sort(); | |
// There *must* be a type, no attaching namespace-only handlers | |
if ( !type ) { | |
continue; | |
} | |
// If event changes its type, use the special event handlers for the changed type | |
special = jQuery.event.special[ type ] || {}; | |
// If selector defined, determine special event api type, otherwise given type | |
type = ( selector ? special.delegateType : special.bindType ) || type; | |
// Update special based on newly reset type | |
special = jQuery.event.special[ type ] || {}; | |
// handleObj is passed to all event handlers | |
handleObj = jQuery.extend({ | |
type: type, | |
origType: origType, | |
data: data, | |
handler: handler, | |
guid: handler.guid, | |
selector: selector, | |
needsContext: selector && jQuery.expr.match.needsContext.test( selector ), | |
namespace: namespaces.join(".") | |
}, handleObjIn ); | |
// Init the event handler queue if we're the first | |
if ( !(handlers = events[ type ]) ) { | |
handlers = events[ type ] = []; | |
handlers.delegateCount = 0; | |
// Only use addEventListener if the special events handler returns false | |
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { | |
if ( elem.addEventListener ) { | |
elem.addEventListener( type, eventHandle, false ); | |
} | |
} | |
} | |
if ( special.add ) { | |
special.add.call( elem, handleObj ); | |
if ( !handleObj.handler.guid ) { | |
handleObj.handler.guid = handler.guid; | |
} | |
} | |
// Add to the element's handler list, delegates in front | |
if ( selector ) { | |
handlers.splice( handlers.delegateCount++, 0, handleObj ); | |
} else { | |
handlers.push( handleObj ); | |
} | |
// Keep track of which events have ever been used, for event optimization | |
jQuery.event.global[ type ] = true; | |
} | |
// Nullify elem to prevent memory leaks in IE | |
elem = null; | |
}, | |
// Detach an event or set of events from an element | |
remove: function( elem, types, handler, selector, mappedTypes ) { | |
var j, origCount, tmp, | |
events, t, handleObj, | |
special, handlers, type, namespaces, origType, | |
elemData = data_priv.hasData( elem ) && data_priv.get( elem ); | |
if ( !elemData || !(events = elemData.events) ) { | |
return; | |
} | |
// Once for each type.namespace in types; type may be omitted | |
types = ( types || "" ).match( core_rnotwhite ) || [""]; | |
t = types.length; | |
while ( t-- ) { | |
tmp = rtypenamespace.exec( types[t] ) || []; | |
type = origType = tmp[1]; | |
namespaces = ( tmp[2] || "" ).split( "." ).sort(); | |
// Unbind all events (on this namespace, if provided) for the element | |
if ( !type ) { | |
for ( type in events ) { | |
jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); | |
} | |
continue; | |
} | |
special = jQuery.event.special[ type ] || {}; | |
type = ( selector ? special.delegateType : special.bindType ) || type; | |
handlers = events[ type ] || []; | |
tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); | |
// Remove matching events | |
origCount = j = handlers.length; | |
while ( j-- ) { | |
handleObj = handlers[ j ]; | |
if ( ( mappedTypes || origType === handleObj.origType ) && | |
( !handler || handler.guid === handleObj.guid ) && | |
( !tmp || tmp.test( handleObj.namespace ) ) && | |
( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { | |
handlers.splice( j, 1 ); | |
if ( handleObj.selector ) { | |
handlers.delegateCount--; | |
} | |
if ( special.remove ) { | |
special.remove.call( elem, handleObj ); | |
} | |
} | |
} | |
// Remove generic event handler if we removed something and no more handlers exist | |
// (avoids potential for endless recursion during removal of special event handlers) | |
if ( origCount && !handlers.length ) { | |
if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { | |
jQuery.removeEvent( elem, type, elemData.handle ); | |
} | |
delete events[ type ]; | |
} | |
} | |
// Remove the expando if it's no longer used | |
if ( jQuery.isEmptyObject( events ) ) { | |
delete elemData.handle; | |
data_priv.remove( elem, "events" ); | |
} | |
}, | |
trigger: function( event, data, elem, onlyHandlers ) { | |
var i, cur, tmp, bubbleType, ontype, handle, special, | |
eventPath = [ elem || document ], | |
type = core_hasOwn.call( event, "type" ) ? event.type : event, | |
namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; | |
cur = tmp = elem = elem || document; | |
// Don't do events on text and comment nodes | |
if ( elem.nodeType === 3 || elem.nodeType === 8 ) { | |
return; | |
} | |
// focus/blur morphs to focusin/out; ensure we're not firing them right now | |
if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { | |
return; | |
} | |
if ( type.indexOf(".") >= 0 ) { | |
// Namespaced trigger; create a regexp to match event type in handle() | |
namespaces = type.split("."); | |
type = namespaces.shift(); | |
namespaces.sort(); | |
} | |
ontype = type.indexOf(":") < 0 && "on" + type; | |
// Caller can pass in a jQuery.Event object, Object, or just an event type string | |
event = event[ jQuery.expando ] ? | |
event : | |
new jQuery.Event( type, typeof event === "object" && event ); | |
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) | |
event.isTrigger = onlyHandlers ? 2 : 3; | |
event.namespace = namespaces.join("."); | |
event.namespace_re = event.namespace ? | |
new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : | |
null; | |
// Clean up the event in case it is being reused | |
event.result = undefined; | |
if ( !event.target ) { | |
event.target = elem; | |
} | |
// Clone any incoming data and prepend the event, creating the handler arg list | |
data = data == null ? | |
[ event ] : | |
jQuery.makeArray( data, [ event ] ); | |
// Allow special events to draw outside the lines | |
special = jQuery.event.special[ type ] || {}; | |
if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { | |
return; | |
} | |
// Determine event propagation path in advance, per W3C events spec (#9951) | |
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724) | |
if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { | |
bubbleType = special.delegateType || type; | |
if ( !rfocusMorph.test( bubbleType + type ) ) { | |
cur = cur.parentNode; | |
} | |
for ( ; cur; cur = cur.parentNode ) { | |
eventPath.push( cur ); | |
tmp = cur; | |
} | |
// Only add window if we got to document (e.g., not plain obj or detached DOM) | |
if ( tmp === (elem.ownerDocument || document) ) { | |
eventPath.push( tmp.defaultView || tmp.parentWindow || window ); | |
} | |
} | |
// Fire handlers on the event path | |
i = 0; | |
while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { | |
event.type = i > 1 ? | |
bubbleType : | |
special.bindType || type; | |
// jQuery handler | |
handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" ); | |
if ( handle ) { | |
handle.apply( cur, data ); | |
} | |
// Native handler | |
handle = ontype && cur[ ontype ]; | |
if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { | |
event.preventDefault(); | |
} | |
} | |
event.type = type; | |
// If nobody prevented the default action, do it now | |
if ( !onlyHandlers && !event.isDefaultPrevented() ) { | |
if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && | |
jQuery.acceptData( elem ) ) { | |
// Call a native DOM method on the target with the same name name as the event. | |
// Don't do default actions on window, that's where global variables be (#6170) | |
if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) { | |
// Don't re-trigger an onFOO event when we call its FOO() method | |
tmp = elem[ ontype ]; | |
if ( tmp ) { | |
elem[ ontype ] = null; | |
} | |
// Prevent re-triggering of the same event, since we already bubbled it above | |
jQuery.event.triggered = type; | |
elem[ type ](); | |
jQuery.event.triggered = undefined; | |
if ( tmp ) { | |
elem[ ontype ] = tmp; | |
} | |
} | |
} | |
} | |
return event.result; | |
}, | |
dispatch: function( event ) { | |
// Make a writable jQuery.Event from the native event object | |
event = jQuery.event.fix( event ); | |
var i, j, ret, matched, handleObj, | |
handlerQueue = [], | |
args = core_slice.call( arguments ), | |
handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [], | |
special = jQuery.event.special[ event.type ] || {}; | |
// Use the fix-ed jQuery.Event rather than the (read-only) native event | |
args[0] = event; | |
event.delegateTarget = this; | |
// Call the preDispatch hook for the mapped type, and let it bail if desired | |
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { | |
return; | |
} | |
// Determine handlers | |
handlerQueue = jQuery.event.handlers.call( this, event, handlers ); | |
// Run delegates first; they may want to stop propagation beneath us | |
i = 0; | |
while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { | |
event.currentTarget = matched.elem; | |
j = 0; | |
while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { | |
// Triggered event must either 1) have no namespace, or | |
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). | |
if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { | |
event.handleObj = handleObj; | |
event.data = handleObj.data; | |
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) | |
.apply( matched.elem, args ); | |
if ( ret !== undefined ) { | |
if ( (event.result = ret) === false ) { | |
event.preventDefault(); | |
event.stopPropagation(); | |
} | |
} | |
} | |
} | |
} | |
// Call the postDispatch hook for the mapped type | |
if ( special.postDispatch ) { | |
special.postDispatch.call( this, event ); | |
} | |
return event.result; | |
}, | |
handlers: function( event, handlers ) { | |
var i, matches, sel, handleObj, | |
handlerQueue = [], | |
delegateCount = handlers.delegateCount, | |
cur = event.target; | |
// Find delegate handlers | |
// Black-hole SVG <use> instance trees (#13180) | |
// Avoid non-left-click bubbling in Firefox (#3861) | |
if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { | |
for ( ; cur !== this; cur = cur.parentNode || this ) { | |
// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) | |
if ( cur.disabled !== true || event.type !== "click" ) { | |
matches = []; | |
for ( i = 0; i < delegateCount; i++ ) { | |
handleObj = handlers[ i ]; | |
// Don't conflict with Object.prototype properties (#13203) | |
sel = handleObj.selector + " "; | |
if ( matches[ sel ] === undefined ) { | |
matches[ sel ] = handleObj.needsContext ? | |
jQuery( sel, this ).index( cur ) >= 0 : | |
jQuery.find( sel, this, null, [ cur ] ).length; | |
} | |
if ( matches[ sel ] ) { | |
matches.push( handleObj ); | |
} | |
} | |
if ( matches.length ) { | |
handlerQueue.push({ elem: cur, handlers: matches }); | |
} | |
} | |
} | |
} | |
// Add the remaining (directly-bound) handlers | |
if ( delegateCount < handlers.length ) { | |
handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); | |
} | |
return handlerQueue; | |
}, | |
// Includes some event props shared by KeyEvent and MouseEvent | |
props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), | |
fixHooks: {}, | |
keyHooks: { | |
props: "char charCode key keyCode".split(" "), | |
filter: function( event, original ) { | |
// Add which for key events | |
if ( event.which == null ) { | |
event.which = original.charCode != null ? original.charCode : original.keyCode; | |
} | |
return event; | |
} | |
}, | |
mouseHooks: { | |
props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "), | |
filter: function( event, original ) { | |
var eventDoc, doc, body, | |
button = original.button; | |
// Calculate pageX/Y if missing and clientX/Y available | |
if ( event.pageX == null && original.clientX != null ) { | |
eventDoc = event.target.ownerDocument || document; | |
doc = eventDoc.documentElement; | |
body = eventDoc.body; | |
event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); | |
event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); | |
} | |
// Add which for click: 1 === left; 2 === middle; 3 === right | |
// Note: button is not normalized, so don't use it | |
if ( !event.which && button !== undefined ) { | |
event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); | |
} | |
return event; | |
} | |
}, | |
fix: function( event ) { | |
if ( event[ jQuery.expando ] ) { | |
return event; | |
} | |
// Create a writable copy of the event object and normalize some properties | |
var i, prop, copy, | |
type = event.type, | |
originalEvent = event, | |
fixHook = this.fixHooks[ type ]; | |
if ( !fixHook ) { | |
this.fixHooks[ type ] = fixHook = | |
rmouseEvent.test( type ) ? this.mouseHooks : | |
rkeyEvent.test( type ) ? this.keyHooks : | |
{}; | |
} | |
copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; | |
event = new jQuery.Event( originalEvent ); | |
i = copy.length; | |
while ( i-- ) { | |
prop = copy[ i ]; | |
event[ prop ] = originalEvent[ prop ]; | |
} | |
// Support: Safari 6.0+, Chrome < 28 | |
// Target should not be a text node (#504, #13143) | |
if ( event.target.nodeType === 3 ) { | |
event.target = event.target.parentNode; | |
} | |
return fixHook.filter? fixHook.filter( event, originalEvent ) : event; | |
}, | |
special: { | |
load: { | |
// Prevent triggered image.load events from bubbling to window.load | |
noBubble: true | |
}, | |
focus: { | |
// Fire native event if possible so blur/focus sequence is correct | |
trigger: function() { | |
if ( this !== safeActiveElement() && this.focus ) { | |
this.focus(); | |
return false; | |
} | |
}, | |
delegateType: "focusin" | |
}, | |
blur: { | |
trigger: function() { | |
if ( this === safeActiveElement() && this.blur ) { | |
this.blur(); | |
return false; | |
} | |
}, | |
delegateType: "focusout" | |
}, | |
click: { | |
// For checkbox, fire native event so checked state will be right | |
trigger: function() { | |
if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { | |
this.click(); | |
return false; | |
} | |
}, | |
// For cross-browser consistency, don't fire native .click() on links | |
_default: function( event ) { | |
return jQuery.nodeName( event.target, "a" ); | |
} | |
}, | |
beforeunload: { | |
postDispatch: function( event ) { | |
// Support: Firefox 20+ | |
// Firefox doesn't alert if the returnValue field is not set. | |
if ( event.result !== undefined ) { | |
event.originalEvent.returnValue = event.result; | |
} | |
} | |
} | |
}, | |
simulate: function( type, elem, event, bubble ) { | |
// Piggyback on a donor event to simulate a different one. | |
// Fake originalEvent to avoid donor's stopPropagation, but if the | |
// simulated event prevents default then we do the same on the donor. | |
var e = jQuery.extend( | |
new jQuery.Event(), | |
event, | |
{ | |
type: type, | |
isSimulated: true, | |
originalEvent: {} | |
} | |
); | |
if ( bubble ) { | |
jQuery.event.trigger( e, null, elem ); | |
} else { | |
jQuery.event.dispatch.call( elem, e ); | |
} | |
if ( e.isDefaultPrevented() ) { | |
event.preventDefault(); | |
} | |
} | |
}; | |
jQuery.removeEvent = function( elem, type, handle ) { | |
if ( elem.removeEventListener ) { | |
elem.removeEventListener( type, handle, false ); | |
} | |
}; | |
jQuery.Event = function( src, props ) { | |
// Allow instantiation without the 'new' keyword | |
if ( !(this instanceof jQuery.Event) ) { | |
return new jQuery.Event( src, props ); | |
} | |
// Event object | |
if ( src && src.type ) { | |
this.originalEvent = src; | |
this.type = src.type; | |
// Events bubbling up the document may have been marked as prevented | |
// by a handler lower down the tree; reflect the correct value. | |
this.isDefaultPrevented = ( src.defaultPrevented || | |
src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; | |
// Event type | |
} else { | |
this.type = src; | |
} | |
// Put explicitly provided properties onto the event object | |
if ( props ) { | |
jQuery.extend( this, props ); | |
} | |
// Create a timestamp if incoming event doesn't have one | |
this.timeStamp = src && src.timeStamp || jQuery.now(); | |
// Mark it as fixed | |
this[ jQuery.expando ] = true; | |
}; | |
// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding | |
// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html | |
jQuery.Event.prototype = { | |
isDefaultPrevented: returnFalse, | |
isPropagationStopped: returnFalse, | |
isImmediatePropagationStopped: returnFalse, | |
preventDefault: function() { | |
var e = this.originalEvent; | |
this.isDefaultPrevented = returnTrue; | |
if ( e && e.preventDefault ) { | |
e.preventDefault(); | |
} | |
}, | |
stopPropagation: function() { | |
var e = this.originalEvent; | |
this.isPropagationStopped = returnTrue; | |
if ( e && e.stopPropagation ) { | |
e.stopPropagation(); | |
} | |
}, | |
stopImmediatePropagation: function() { | |
this.isImmediatePropagationStopped = returnTrue; | |
this.stopPropagation(); | |
} | |
}; | |
// Create mouseenter/leave events using mouseover/out and event-time checks | |
// Support: Chrome 15+ | |
jQuery.each({ | |
mouseenter: "mouseover", | |
mouseleave: "mouseout" | |
}, function( orig, fix ) { | |
jQuery.event.special[ orig ] = { | |
delegateType: fix, | |
bindType: fix, | |
handle: function( event ) { | |
var ret, | |
target = this, | |
related = event.relatedTarget, | |
handleObj = event.handleObj; | |
// For mousenter/leave call the handler if related is outside the target. | |
// NB: No relatedTarget if the mouse left/entered the browser window | |
if ( !related || (related !== target && !jQuery.contains( target, related )) ) { | |
event.type = handleObj.origType; | |
ret = handleObj.handler.apply( this, arguments ); | |
event.type = fix; | |
} | |
return ret; | |
} | |
}; | |
}); | |
// Create "bubbling" focus and blur events | |
// Support: Firefox, Chrome, Safari | |
if ( !jQuery.support.focusinBubbles ) { | |
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { | |
// Attach a single capturing handler while someone wants focusin/focusout | |
var attaches = 0, | |
handler = function( event ) { | |
jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); | |
}; | |
jQuery.event.special[ fix ] = { | |
setup: function() { | |
if ( attaches++ === 0 ) { | |
document.addEventListener( orig, handler, true ); | |
} | |
}, | |
teardown: function() { | |
if ( --attaches === 0 ) { | |
document.removeEventListener( orig, handler, true ); | |
} | |
} | |
}; | |
}); | |
} | |
jQuery.fn.extend({ | |
on: function( types, selector, data, fn, /*INTERNAL*/ one ) { | |
var origFn, type; | |
// Types can be a map of types/handlers | |
if ( typeof types === "object" ) { | |
// ( types-Object, selector, data ) | |
if ( typeof selector !== "string" ) { | |
// ( types-Object, data ) | |
data = data || selector; | |
selector = undefined; | |
} | |
for ( type in types ) { | |
this.on( type, selector, data, types[ type ], one ); | |
} | |
return this; | |
} | |
if ( data == null && fn == null ) { | |
// ( types, fn ) | |
fn = selector; | |
data = selector = undefined; | |
} else if ( fn == null ) { | |
if ( typeof selector === "string" ) { | |
// ( types, selector, fn ) | |
fn = data; | |
data = undefined; | |
} else { | |
// ( types, data, fn ) | |
fn = data; | |
data = selector; | |
selector = undefined; | |
} | |
} | |
if ( fn === false ) { | |
fn = returnFalse; | |
} else if ( !fn ) { | |
return this; | |
} | |
if ( one === 1 ) { | |
origFn = fn; | |
fn = function( event ) { | |
// Can use an empty set, since event contains the info | |
jQuery().off( event ); | |
return origFn.apply( this, arguments ); | |
}; | |
// Use same guid so caller can remove using origFn | |
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); | |
} | |
return this.each( function() { | |
jQuery.event.add( this, types, fn, data, selector ); | |
}); | |
}, | |
one: function( types, selector, data, fn ) { | |
return this.on( types, selector, data, fn, 1 ); | |
}, | |
off: function( types, selector, fn ) { | |
var handleObj, type; | |
if ( types && types.preventDefault && types.handleObj ) { | |
// ( event ) dispatched jQuery.Event | |
handleObj = types.handleObj; | |
jQuery( types.delegateTarget ).off( | |
handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, | |
handleObj.selector, | |
handleObj.handler | |
); | |
return this; | |
} | |
if ( typeof types === "object" ) { | |
// ( types-object [, selector] ) | |
for ( type in types ) { | |
this.off( type, selector, types[ type ] ); | |
} | |
return this; | |
} | |
if ( selector === false || typeof selector === "function" ) { | |
// ( types [, fn] ) | |
fn = selector; | |
selector = undefined; | |
} | |
if ( fn === false ) { | |
fn = returnFalse; | |
} | |
return this.each(function() { | |
jQuery.event.remove( this, types, fn, selector ); | |
}); | |
}, | |
trigger: function( type, data ) { | |
return this.each(function() { | |
jQuery.event.trigger( type, data, this ); | |
}); | |
}, | |
triggerHandler: function( type, data ) { | |
var elem = this[0]; | |
if ( elem ) { | |
return jQuery.event.trigger( type, data, elem, true ); | |
} | |
} | |
}); | |
var isSimple = /^.[^:#\[\.,]*$/, | |
rneedsContext = jQuery.expr.match.needsContext, | |
// methods guaranteed to produce a unique set when starting from a unique set | |
guaranteedUnique = { | |
children: true, | |
contents: true, | |
next: true, | |
prev: true | |
}; | |
jQuery.fn.extend({ | |
find: function( selector ) { | |
var self, matched, i, | |
l = this.length; | |
if ( typeof selector !== "string" ) { | |
self = this; | |
return this.pushStack( jQuery( selector ).filter(function() { | |
for ( i = 0; i < l; i++ ) { | |
if ( jQuery.contains( self[ i ], this ) ) { | |
return true; | |
} | |
} | |
}) ); | |
} | |
matched = []; | |
for ( i = 0; i < l; i++ ) { | |
jQuery.find( selector, this[ i ], matched ); | |
} | |
// Needed because $( selector, context ) becomes $( context ).find( selector ) | |
matched = this.pushStack( l > 1 ? jQuery.unique( matched ) : matched ); | |
matched.selector = ( this.selector ? this.selector + " " : "" ) + selector; | |
return matched; | |
}, | |
has: function( target ) { | |
var targets = jQuery( target, this ), | |
l = targets.length; | |
return this.filter(function() { | |
var i = 0; | |
for ( ; i < l; i++ ) { | |
if ( jQuery.contains( this, targets[i] ) ) { | |
return true; | |
} | |
} | |
}); | |
}, | |
not: function( selector ) { | |
return this.pushStack( winnow(this, selector || [], true) ); | |
}, | |
filter: function( selector ) { | |
return this.pushStack( winnow(this, selector || [], false) ); | |
}, | |
is: function( selector ) { | |
return !!selector && ( | |
typeof selector === "string" ? | |
// If this is a positional/relative selector, check membership in the returned set | |
// so $("p:first").is("p:last") won't return true for a doc with two "p". | |
rneedsContext.test( selector ) ? | |
jQuery( selector, this.context ).index( this[ 0 ] ) >= 0 : | |
jQuery.filter( selector, this ).length > 0 : | |
this.filter( selector ).length > 0 ); | |
}, | |
closest: function( selectors, context ) { | |
var cur, | |
i = 0, | |
l = this.length, | |
matched = [], | |
pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ? | |
jQuery( selectors, context || this.context ) : | |
0; | |
for ( ; i < l; i++ ) { | |
for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { | |
// Always skip document fragments | |
if ( cur.nodeType < 11 && (pos ? | |
pos.index(cur) > -1 : | |
// Don't pass non-elements to Sizzle | |
cur.nodeType === 1 && | |
jQuery.find.matchesSelector(cur, selectors)) ) { | |
cur = matched.push( cur ); | |
break; | |
} | |
} | |
} | |
return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); | |
}, | |
// Determine the position of an element within | |
// the matched set of elements | |
index: function( elem ) { | |
// No argument, return index in parent | |
if ( !elem ) { | |
return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; | |
} | |
// index in selector | |
if ( typeof elem === "string" ) { | |
return core_indexOf.call( jQuery( elem ), this[ 0 ] ); | |
} | |
// Locate the position of the desired element | |
return core_indexOf.call( this, | |
// If it receives a jQuery object, the first element is used | |
elem.jquery ? elem[ 0 ] : elem | |
); | |
}, | |
add: function( selector, context ) { | |
var set = typeof selector === "string" ? | |
jQuery( selector, context ) : | |
jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), | |
all = jQuery.merge( this.get(), set ); | |
return this.pushStack( jQuery.unique(all) ); | |
}, | |
addBack: function( selector ) { | |
return this.add( selector == null ? | |
this.prevObject : this.prevObject.filter(selector) | |
); | |
} | |
}); | |
function sibling( cur, dir ) { | |
while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {} | |
return cur; | |
} | |
jQuery.each({ | |
parent: function( elem ) { | |
var parent = elem.parentNode; | |
return parent && parent.nodeType !== 11 ? parent : null; | |
}, | |
parents: function( elem ) { | |
return jQuery.dir( elem, "parentNode" ); | |
}, | |
parentsUntil: function( elem, i, until ) { | |
return jQuery.dir( elem, "parentNode", until ); | |
}, | |
next: function( elem ) { | |
return sibling( elem, "nextSibling" ); | |
}, | |
prev: function( elem ) { | |
return sibling( elem, "previousSibling" ); | |
}, | |
nextAll: function( elem ) { | |
return jQuery.dir( elem, "nextSibling" ); | |
}, | |
prevAll: function( elem ) { | |
return jQuery.dir( elem, "previousSibling" ); | |
}, | |
nextUntil: function( elem, i, until ) { | |
return jQuery.dir( elem, "nextSibling", until ); | |
}, | |
prevUntil: function( elem, i, until ) { | |
return jQuery.dir( elem, "previousSibling", until ); | |
}, | |
siblings: function( elem ) { | |
return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); | |
}, | |
children: function( elem ) { | |
return jQuery.sibling( elem.firstChild ); | |
}, | |
contents: function( elem ) { | |
return jQuery.nodeName( elem, "iframe" ) ? | |
elem.contentDocument || elem.contentWindow.document : | |
jQuery.merge( [], elem.childNodes ); | |
} | |
}, function( name, fn ) { | |
jQuery.fn[ name ] = function( until, selector ) { | |
var matched = jQuery.map( this, fn, until ); | |
if ( name.slice( -5 ) !== "Until" ) { | |
selector = until; | |
} | |
if ( selector && typeof selector === "string" ) { | |
matched = jQuery.filter( selector, matched ); | |
} | |
if ( this.length > 1 ) { | |
// Remove duplicates | |
if ( !guaranteedUnique[ name ] ) { | |
jQuery.unique( matched ); | |
} | |
// Reverse order for parents* and prev* | |
if ( name[ 0 ] === "p" ) { | |
matched.reverse(); | |
} | |
} | |
return this.pushStack( matched ); | |
}; | |
}); | |
jQuery.extend({ | |
filter: function( expr, elems, not ) { | |
var elem = elems[ 0 ]; | |
if ( not ) { | |
expr = ":not(" + expr + ")"; | |
} | |
return elems.length === 1 && elem.nodeType === 1 ? | |
jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : | |
jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { | |
return elem.nodeType === 1; | |
})); | |
}, | |
dir: function( elem, dir, until ) { | |
var matched = [], | |
truncate = until !== undefined; | |
while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) { | |
if ( elem.nodeType === 1 ) { | |
if ( truncate && jQuery( elem ).is( until ) ) { | |
break; | |
} | |
matched.push( elem ); | |
} | |
} | |
return matched; | |
}, | |
sibling: function( n, elem ) { | |
var matched = []; | |
for ( ; n; n = n.nextSibling ) { | |
if ( n.nodeType === 1 && n !== elem ) { | |
matched.push( n ); | |
} | |
} | |
return matched; | |
} | |
}); | |
// Implement the identical functionality for filter and not | |
function winnow( elements, qualifier, not ) { | |
if ( jQuery.isFunction( qualifier ) ) { | |
return jQuery.grep( elements, function( elem, i ) { | |
/* jshint -W018 */ | |
return !!qualifier.call( elem, i, elem ) !== not; | |
}); | |
} | |
if ( qualifier.nodeType ) { | |
return jQuery.grep( elements, function( elem ) { | |
return ( elem === qualifier ) !== not; | |
}); | |
} | |
if ( typeof qualifier === "string" ) { | |
if ( isSimple.test( qualifier ) ) { | |
return jQuery.filter( qualifier, elements, not ); | |
} | |
qualifier = jQuery.filter( qualifier, elements ); | |
} | |
return jQuery.grep( elements, function( elem ) { | |
return ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not; | |
}); | |
} | |
var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, | |
rtagName = /<([\w:]+)/, | |
rhtml = /<|&#?\w+;/, | |
rnoInnerhtml = /<(?:script|style|link)/i, | |
manipulation_rcheckableType = /^(?:checkbox|radio)$/i, | |
// checked="checked" or checked | |
rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, | |
rscriptType = /^$|\/(?:java|ecma)script/i, | |
rscriptTypeMasked = /^true\/(.*)/, | |
rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, | |
// We have to close these tags to support XHTML (#13200) | |
wrapMap = { | |
// Support: IE 9 | |
option: [ 1, "<select multiple='multiple'>", "</select>" ], | |
thead: [ 1, "<table>", "</table>" ], | |
tr: [ 2, "<table><tbody>", "</tbody></table>" ], | |
td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], | |
_default: [ 0, "", "" ] | |
}; | |
// Support: IE 9 | |
wrapMap.optgroup = wrapMap.option; | |
wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.col = wrapMap.thead; | |
wrapMap.th = wrapMap.td; | |
jQuery.fn.extend({ | |
text: function( value ) { | |
return jQuery.access( this, function( value ) { | |
return value === undefined ? | |
jQuery.text( this ) : | |
this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) ); | |
}, null, value, arguments.length ); | |
}, | |
append: function() { | |
return this.domManip( arguments, function( elem ) { | |
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { | |
var target = manipulationTarget( this, elem ); | |
target.appendChild( elem ); | |
} | |
}); | |
}, | |
prepend: function() { | |
return this.domManip( arguments, function( elem ) { | |
if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { | |
var target = manipulationTarget( this, elem ); | |
target.insertBefore( elem, target.firstChild ); | |
} | |
}); | |
}, | |
before: function() { | |
return this.domManip( arguments, function( elem ) { | |
if ( this.parentNode ) { | |
this.parentNode.insertBefore( elem, this ); | |
} | |
}); | |
}, | |
after: function() { | |
return this.domManip( arguments, function( elem ) { | |
if ( this.parentNode ) { | |
this.parentNode.insertBefore( elem, this.nextSibling ); | |
} | |
}); | |
}, | |
// keepData is for internal use only--do not document | |
remove: function( selector, keepData ) { | |
var elem, | |
elems = selector ? jQuery.filter( selector, this ) : this, | |
i = 0; | |
for ( ; (elem = elems[i]) != null; i++ ) { | |
if ( !keepData && elem.nodeType === 1 ) { | |
jQuery.cleanData( getAll( elem ) ); | |
} | |
if ( elem.parentNode ) { | |
if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { | |
setGlobalEval( getAll( elem, "script" ) ); | |
} | |
elem.parentNode.removeChild( elem ); | |
} | |
} | |
return this; | |
}, | |
empty: function() { | |
var elem, | |
i = 0; | |
for ( ; (elem = this[i]) != null; i++ ) { | |
if ( elem.nodeType === 1 ) { | |
// Prevent memory leaks | |
jQuery.cleanData( getAll( elem, false ) ); | |
// Remove any remaining nodes | |
elem.textContent = ""; | |
} | |
} | |
return this; | |
}, | |
clone: function( dataAndEvents, deepDataAndEvents ) { | |
dataAndEvents = dataAndEvents == null ? false : dataAndEvents; | |
deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; | |
return this.map( function () { | |
return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); | |
}); | |
}, | |
html: function( value ) { | |
return jQuery.access( this, function( value ) { | |
var elem = this[ 0 ] || {}, | |
i = 0, | |
l = this.length; | |
if ( value === undefined && elem.nodeType === 1 ) { | |
return elem.innerHTML; | |
} | |
// See if we can take a shortcut and just use innerHTML | |
if ( typeof value === "string" && !rnoInnerhtml.test( value ) && | |
!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { | |
value = value.replace( rxhtmlTag, "<$1></$2>" ); | |
try { | |
for ( ; i < l; i++ ) { | |
elem = this[ i ] || {}; | |
// Remove element nodes and prevent memory leaks | |
if ( elem.nodeType === 1 ) { | |
jQuery.cleanData( getAll( elem, false ) ); | |
elem.innerHTML = value; | |
} | |
} | |
elem = 0; | |
// If using innerHTML throws an exception, use the fallback method | |
} catch( e ) {} | |
} | |
if ( elem ) { | |
this.empty().append( value ); | |
} | |
}, null, value, arguments.length ); | |
}, | |
replaceWith: function() { | |
var | |
// Snapshot the DOM in case .domManip sweeps something relevant into its fragment | |
args = jQuery.map( this, function( elem ) { | |
return [ elem.nextSibling, elem.parentNode ]; | |
}), | |
i = 0; | |
// Make the changes, replacing each context element with the new content | |
this.domManip( arguments, function( elem ) { | |
var next = args[ i++ ], | |
parent = args[ i++ ]; | |
if ( parent ) { | |
jQuery( this ).remove(); | |
parent.insertBefore( elem, next ); | |
} | |
// Allow new content to include elements from the context set | |
}, true ); | |
// Force removal if there was no new content (e.g., from empty arguments) | |
return i ? this : this.remove(); | |
}, | |
detach: function( selector ) { | |
return this.remove( selector, true ); | |
}, | |
domManip: function( args, callback, allowIntersection ) { | |
// Flatten any nested arrays | |
args = core_concat.apply( [], args ); | |
var fragment, first, scripts, hasScripts, node, doc, | |
i = 0, | |
l = this.length, | |
set = this, | |
iNoClone = l - 1, | |
value = args[ 0 ], | |
isFunction = jQuery.isFunction( value ); | |
// We can't cloneNode fragments that contain checked, in WebKit | |
if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { | |
return this.each(function( index ) { | |
var self = set.eq( index ); | |
if ( isFunction ) { | |
args[ 0 ] = value.call( this, index, self.html() ); | |
} | |
self.domManip( args, callback, allowIntersection ); | |
}); | |
} | |
if ( l ) { | |
fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); | |
first = fragment.firstChild; | |
if ( fragment.childNodes.length === 1 ) { | |
fragment = first; | |
} | |
if ( first ) { | |
scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); | |
hasScripts = scripts.length; | |
// Use the original fragment for the last item instead of the first because it can end up | |
// being emptied incorrectly in certain situations (#8070). | |
for ( ; i < l; i++ ) { | |
node = fragment; | |
if ( i !== iNoClone ) { | |
node = jQuery.clone( node, true, true ); | |
// Keep references to cloned scripts for later restoration | |
if ( hasScripts ) { | |
// Support: QtWebKit | |
// jQuery.merge because core_push.apply(_, arraylike) throws | |
jQuery.merge( scripts, getAll( node, "script" ) ); | |
} | |
} | |
callback.call( this[ i ], node, i ); | |
} | |
if ( hasScripts ) { | |
doc = scripts[ scripts.length - 1 ].ownerDocument; | |
// Reenable scripts | |
jQuery.map( scripts, restoreScript ); | |
// Evaluate executable scripts on first document insertion | |
for ( i = 0; i < hasScripts; i++ ) { | |
node = scripts[ i ]; | |
if ( rscriptType.test( node.type || "" ) && | |
!data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { | |
if ( node.src ) { | |
// Hope ajax is available... | |
jQuery._evalUrl( node.src ); | |
} else { | |
jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) ); | |
} | |
} | |
} | |
} | |
} | |
} | |
return this; | |
} | |
}); | |
jQuery.each({ | |
appendTo: "append", | |
prependTo: "prepend", | |
insertBefore: "before", | |
insertAfter: "after", | |
replaceAll: "replaceWith" | |
}, function( name, original ) { | |
jQuery.fn[ name ] = function( selector ) { | |
var elems, | |
ret = [], | |
insert = jQuery( selector ), | |
last = insert.length - 1, | |
i = 0; | |
for ( ; i <= last; i++ ) { | |
elems = i === last ? this : this.clone( true ); | |
jQuery( insert[ i ] )[ original ]( elems ); | |
// Support: QtWebKit | |
// .get() because core_push.apply(_, arraylike) throws | |
core_push.apply( ret, elems.get() ); | |
} | |
return this.pushStack( ret ); | |
}; | |
}); | |
jQuery.extend({ | |
clone: function( elem, dataAndEvents, deepDataAndEvents ) { | |
var i, l, srcElements, destElements, | |
clone = elem.cloneNode( true ), | |
inPage = jQuery.contains( elem.ownerDocument, elem ); | |
// Support: IE >= 9 | |
// Fix Cloning issues | |
if ( !jQuery.support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { | |
// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 | |
destElements = getAll( clone ); | |
srcElements = getAll( elem ); | |
for ( i = 0, l = srcElements.length; i < l; i++ ) { | |
fixInput( srcElements[ i ], destElements[ i ] ); | |
} | |
} | |
// Copy the events from the original to the clone | |
if ( dataAndEvents ) { | |
if ( deepDataAndEvents ) { | |
srcElements = srcElements || getAll( elem ); | |
destElements = destElements || getAll( clone ); | |
for ( i = 0, l = srcElements.length; i < l; i++ ) { | |
cloneCopyEvent( srcElements[ i ], destElements[ i ] ); | |
} | |
} else { | |
cloneCopyEvent( elem, clone ); | |
} | |
} | |
// Preserve script evaluation history | |
destElements = getAll( clone, "script" ); | |
if ( destElements.length > 0 ) { | |
setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); | |
} | |
// Return the cloned set | |
return clone; | |
}, | |
buildFragment: function( elems, context, scripts, selection ) { | |
var elem, tmp, tag, wrap, contains, j, | |
i = 0, | |
l = elems.length, | |
fragment = context.createDocumentFragment(), | |
nodes = []; | |
for ( ; i < l; i++ ) { | |
elem = elems[ i ]; | |
if ( elem || elem === 0 ) { | |
// Add nodes directly | |
if ( jQuery.type( elem ) === "object" ) { | |
// Support: QtWebKit | |
// jQuery.merge because core_push.apply(_, arraylike) throws | |
jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); | |
// Convert non-html into a text node | |
} else if ( !rhtml.test( elem ) ) { | |
nodes.push( context.createTextNode( elem ) ); | |
// Convert html into DOM nodes | |
} else { | |
tmp = tmp || fragment.appendChild( context.createElement("div") ); | |
// Deserialize a standard representation | |
tag = ( rtagName.exec( elem ) || ["", ""] )[ 1 ].toLowerCase(); | |
wrap = wrapMap[ tag ] || wrapMap._default; | |
tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ]; | |
// Descend through wrappers to the right content | |
j = wrap[ 0 ]; | |
while ( j-- ) { | |
tmp = tmp.firstChild; | |
} | |
// Support: QtWebKit | |
// jQuery.merge because core_push.apply(_, arraylike) throws | |
jQuery.merge( nodes, tmp.childNodes ); | |
// Remember the top-level container | |
tmp = fragment.firstChild; | |
// Fixes #12346 | |
// Support: Webkit, IE | |
tmp.textContent = ""; | |
} | |
} | |
} | |
// Remove wrapper from fragment | |
fragment.textContent = ""; | |
i = 0; | |
while ( (elem = nodes[ i++ ]) ) { | |
// #4087 - If origin and destination elements are the same, and this is | |
// that element, do not do anything | |
if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { | |
continue; | |
} | |
contains = jQuery.contains( elem.ownerDocument, elem ); | |
// Append to fragment | |
tmp = getAll( fragment.appendChild( elem ), "script" ); | |
// Preserve script evaluation history | |
if ( contains ) { | |
setGlobalEval( tmp ); | |
} | |
// Capture executables | |
if ( scripts ) { | |
j = 0; | |
while ( (elem = tmp[ j++ ]) ) { | |
if ( rscriptType.test( elem.type || "" ) ) { | |
scripts.push( elem ); | |
} | |
} | |
} | |
} | |
return fragment; | |
}, | |
cleanData: function( elems ) { | |
var data, elem, type, | |
l = elems.length, | |
i = 0, | |
special = jQuery.event.special; | |
for ( ; i < l; i++ ) { | |
elem = elems[ i ]; | |
if ( jQuery.acceptData( elem ) ) { | |
data = data_priv.access( elem ); | |
if ( data ) { | |
for ( type in data.events ) { | |
if ( special[ type ] ) { | |
jQuery.event.remove( elem, type ); | |
// This is a shortcut to avoid jQuery.event.remove's overhead | |
} else { | |
jQuery.removeEvent( elem, type, data.handle ); | |
} | |
} | |
} | |
} | |
// Discard any remaining `private` and `user` data | |
// One day we'll replace the dual arrays with a WeakMap and this won't be an issue. | |
// (Splices the data objects out of the internal cache arrays) | |
data_user.discard( elem ); | |
data_priv.discard( elem ); | |
} | |
}, | |
_evalUrl: function( url ) { | |
return jQuery.ajax({ | |
url: url, | |
type: "GET", | |
dataType: "text", | |
async: false, | |
global: false, | |
success: jQuery.globalEval | |
}); | |
} | |
}); | |
// Support: 1.x compatibility | |
// Manipulating tables requires a tbody | |
function manipulationTarget( elem, content ) { | |
return jQuery.nodeName( elem, "table" ) && | |
jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? | |
elem.getElementsByTagName("tbody")[0] || | |
elem.appendChild( elem.ownerDocument.createElement("tbody") ) : | |
elem; | |
} | |
// Replace/restore the type attribute of script elements for safe DOM manipulation | |
function disableScript( elem ) { | |
elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type; | |
return elem; | |
} | |
function restoreScript( elem ) { | |
var match = rscriptTypeMasked.exec( elem.type ); | |
if ( match ) { | |
elem.type = match[ 1 ]; | |
} else { | |
elem.removeAttribute("type"); | |
} | |
return elem; | |
} | |
// Mark scripts as having already been evaluated | |
function setGlobalEval( elems, refElements ) { | |
var l = elems.length, | |
i = 0; | |
for ( ; i < l; i++ ) { | |
data_priv.set( | |
elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" ) | |
); | |
} | |
} | |
function cloneCopyEvent( src, dest ) { | |
var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events; | |
if ( dest.nodeType !== 1 ) { | |
return; | |
} | |
// 1. Copy private data: events, handlers, etc. | |
if ( data_priv.hasData( src ) ) { | |
pdataOld = data_priv.access( src ); | |
pdataCur = jQuery.extend( {}, pdataOld ); | |
events = pdataOld.events; | |
data_priv.set( dest, pdataCur ); | |
if ( events ) { | |
delete pdataCur.handle; | |
pdataCur.events = {}; | |
for ( type in events ) { | |
for ( i = 0, l = events[ type ].length; i < l; i++ ) { | |
jQuery.event.add( dest, type, events[ type ][ i ] ); | |
} | |
} | |
} | |
} | |
// 2. Copy user data | |
if ( data_user.hasData( src ) ) { | |
udataOld = data_user.access( src ); | |
udataCur = jQuery.extend( {}, udataOld ); | |
data_user.set( dest, udataCur ); | |
} | |
} | |
function getAll( context, tag ) { | |
var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) : | |
context.querySelectorAll ? context.querySelectorAll( tag || "*" ) : | |
[]; | |
return tag === undefined || tag && jQuery.nodeName( context, tag ) ? | |
jQuery.merge( [ context ], ret ) : | |
ret; | |
} | |
// Support: IE >= 9 | |
function fixInput( src, dest ) { | |
var nodeName = dest.nodeName.toLowerCase(); | |
// Fails to persist the checked state of a cloned checkbox or radio button. | |
if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { | |
dest.checked = src.checked; | |
// Fails to return the selected option to the default selected state when cloning options | |
} else if ( nodeName === "input" || nodeName === "textarea" ) { | |
dest.defaultValue = src.defaultValue; | |
} | |
} | |
jQuery.fn.extend({ | |
wrapAll: function( html ) { | |
var wrap; | |
if ( jQuery.isFunction( html ) ) { | |
return this.each(function( i ) { | |
jQuery( this ).wrapAll( html.call(this, i) ); | |
}); | |
} | |
if ( this[ 0 ] ) { | |
// The elements to wrap the target around | |
wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); | |
if ( this[ 0 ].parentNode ) { | |
wrap.insertBefore( this[ 0 ] ); | |
} | |
wrap.map(function() { | |
var elem = this; | |
while ( elem.firstElementChild ) { | |
elem = elem.firstElementChild; | |
} | |
return elem; | |
}).append( this ); | |
} | |
return this; | |
}, | |
wrapInner: function( html ) { | |
if ( jQuery.isFunction( html ) ) { | |
return this.each(function( i ) { | |
jQuery( this ).wrapInner( html.call(this, i) ); | |
}); | |
} | |
return this.each(function() { | |
var self = jQuery( this ), | |
contents = self.contents(); | |
if ( contents.length ) { | |
contents.wrapAll( html ); | |
} else { | |
self.append( html ); | |
} | |
}); | |
}, | |
wrap: function( html ) { | |
var isFunction = jQuery.isFunction( html ); | |
return this.each(function( i ) { | |
jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); | |
}); | |
}, | |
unwrap: function() { | |
return this.parent().each(function() { | |
if ( !jQuery.nodeName( this, "body" ) ) { | |
jQuery( this ).replaceWith( this.childNodes ); | |
} | |
}).end(); | |
} | |
}); | |
var curCSS, iframe, | |
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption" | |
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display | |
rdisplayswap = /^(none|table(?!-c[ea]).+)/, | |
rmargin = /^margin/, | |
rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), | |
rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), | |
rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), | |
elemdisplay = { BODY: "block" }, | |
cssShow = { position: "absolute", visibility: "hidden", display: "block" }, | |
cssNormalTransform = { | |
letterSpacing: 0, | |
fontWeight: 400 | |
}, | |
cssExpand = [ "Top", "Right", "Bottom", "Left" ], | |
cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; | |
// return a css property mapped to a potentially vendor prefixed property | |
function vendorPropName( style, name ) { | |
// shortcut for names that are not vendor prefixed | |
if ( name in style ) { | |
return name; | |
} | |
// check for vendor prefixed names | |
var capName = name.charAt(0).toUpperCase() + name.slice(1), | |
origName = name, | |
i = cssPrefixes.length; | |
while ( i-- ) { | |
name = cssPrefixes[ i ] + capName; | |
if ( name in style ) { | |
return name; | |
} | |
} | |
return origName; | |
} | |
function isHidden( elem, el ) { | |
// isHidden might be called from jQuery#filter function; | |
// in that case, element will be second argument | |
elem = el || elem; | |
return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); | |
} | |
// NOTE: we've included the "window" in window.getComputedStyle | |
// because jsdom on node.js will break without it. | |
function getStyles( elem ) { | |
return window.getComputedStyle( elem, null ); | |
} | |
function showHide( elements, show ) { | |
var display, elem, hidden, | |
values = [], | |
index = 0, | |
length = elements.length; | |
for ( ; index < length; index++ ) { | |
elem = elements[ index ]; | |
if ( !elem.style ) { | |
continue; | |
} | |
values[ index ] = data_priv.get( elem, "olddisplay" ); | |
display = elem.style.display; | |
if ( show ) { | |
// Reset the inline display of this element to learn if it is | |
// being hidden by cascaded rules or not | |
if ( !values[ index ] && display === "none" ) { | |
elem.style.display = ""; | |
} | |
// Set elements which have been overridden with display: none | |
// in a stylesheet to whatever the default browser style is | |
// for such an element | |
if ( elem.style.display === "" && isHidden( elem ) ) { | |
values[ index ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); | |
} | |
} else { | |
if ( !values[ index ] ) { | |
hidden = isHidden( elem ); | |
if ( display && display !== "none" || !hidden ) { | |
data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css(elem, "display") ); | |
} | |
} | |
} | |
} | |
// Set the display of most of the elements in a second loop | |
// to avoid the constant reflow | |
for ( index = 0; index < length; index++ ) { | |
elem = elements[ index ]; | |
if ( !elem.style ) { | |
continue; | |
} | |
if ( !show || elem.style.display === "none" || elem.style.display === "" ) { | |
elem.style.display = show ? values[ index ] || "" : "none"; | |
} | |
} | |
return elements; | |
} | |
jQuery.fn.extend({ | |
css: function( name, value ) { | |
return jQuery.access( this, function( elem, name, value ) { | |
var styles, len, | |
map = {}, | |
i = 0; | |
if ( jQuery.isArray( name ) ) { | |
styles = getStyles( elem ); | |
len = name.length; | |
for ( ; i < len; i++ ) { | |
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); | |
} | |
return map; | |
} | |
return value !== undefined ? | |
jQuery.style( elem, name, value ) : | |
jQuery.css( elem, name ); | |
}, name, value, arguments.length > 1 ); | |
}, | |
show: function() { | |
return showHide( this, true ); | |
}, | |
hide: function() { | |
return showHide( this ); | |
}, | |
toggle: function( state ) { | |
var bool = typeof state === "boolean"; | |
return this.each(function() { | |
if ( bool ? state : isHidden( this ) ) { | |
jQuery( this ).show(); | |
} else { | |
jQuery( this ).hide(); | |
} | |
}); | |
} | |
}); | |
jQuery.extend({ | |
// Add in style property hooks for overriding the default | |
// behavior of getting and setting a style property | |
cssHooks: { | |
opacity: { | |
get: function( elem, computed ) { | |
if ( computed ) { | |
// We should always get a number back from opacity | |
var ret = curCSS( elem, "opacity" ); | |
return ret === "" ? "1" : ret; | |
} | |
} | |
} | |
}, | |
// Exclude the following css properties to add px | |
cssNumber: { | |
"columnCount": true, | |
"fillOpacity": true, | |
"fontWeight": true, | |
"lineHeight": true, | |
"opacity": true, | |
"orphans": true, | |
"widows": true, | |
"zIndex": true, | |
"zoom": true | |
}, | |
// Add in properties whose names you wish to fix before | |
// setting or getting the value | |
cssProps: { | |
// normalize float css property | |
"float": "cssFloat" | |
}, | |
// Get and set the style property on a DOM Node | |
style: function( elem, name, value, extra ) { | |
// Don't set styles on text and comment nodes | |
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { | |
return; | |
} | |
// Make sure that we're working with the right name | |
var ret, type, hooks, | |
origName = jQuery.camelCase( name ), | |
style = elem.style; | |
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); | |
// gets hook for the prefixed version | |
// followed by the unprefixed version | |
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; | |
// Check if we're setting a value | |
if ( value !== undefined ) { | |
type = typeof value; | |
// convert relative number strings (+= or -=) to relative numbers. #7345 | |
if ( type === "string" && (ret = rrelNum.exec( value )) ) { | |
value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); | |
// Fixes bug #9237 | |
type = "number"; | |
} | |
// Make sure that NaN and null values aren't set. See: #7116 | |
if ( value == null || type === "number" && isNaN( value ) ) { | |
return; | |
} | |
// If a number was passed in, add 'px' to the (except for certain CSS properties) | |
if ( type === "number" && !jQuery.cssNumber[ origName ] ) { | |
value += "px"; | |
} | |
// Fixes #8908, it can be done more correctly by specifying setters in cssHooks, | |
// but it would mean to define eight (for every problematic property) identical functions | |
if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { | |
style[ name ] = "inherit"; | |
} | |
// If a hook was provided, use that value, otherwise just set the specified value | |
if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { | |
style[ name ] = value; | |
} | |
} else { | |
// If a hook was provided get the non-computed value from there | |
if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { | |
return ret; | |
} | |
// Otherwise just get the value from the style object | |
return style[ name ]; | |
} | |
}, | |
css: function( elem, name, extra, styles ) { | |
var val, num, hooks, | |
origName = jQuery.camelCase( name ); | |
// Make sure that we're working with the right name | |
name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); | |
// gets hook for the prefixed version | |
// followed by the unprefixed version | |
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; | |
// If a hook was provided get the computed value from there | |
if ( hooks && "get" in hooks ) { | |
val = hooks.get( elem, true, extra ); | |
} | |
// Otherwise, if a way to get the computed value exists, use that | |
if ( val === undefined ) { | |
val = curCSS( elem, name, styles ); | |
} | |
//convert "normal" to computed value | |
if ( val === "normal" && name in cssNormalTransform ) { | |
val = cssNormalTransform[ name ]; | |
} | |
// Return, converting to number if forced or a qualifier was provided and val looks numeric | |
if ( extra === "" || extra ) { | |
num = parseFloat( val ); | |
return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; | |
} | |
return val; | |
} | |
}); | |
curCSS = function( elem, name, _computed ) { | |
var width, minWidth, maxWidth, | |
computed = _computed || getStyles( elem ), | |
// Support: IE9 | |
// getPropertyValue is only needed for .css('filter') in IE9, see #12537 | |
ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, | |
style = elem.style; | |
if ( computed ) { | |
if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { | |
ret = jQuery.style( elem, name ); | |
} | |
// Support: Safari 5.1 | |
// A tribute to the "awesome hack by Dean Edwards" | |
// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels | |
// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values | |
if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { | |
// Remember the original values | |
width = style.width; | |
minWidth = style.minWidth; | |
maxWidth = style.maxWidth; | |
// Put in the new values to get a computed value out | |
style.minWidth = style.maxWidth = style.width = ret; | |
ret = computed.width; | |
// Revert the changed values | |
style.width = width; | |
style.minWidth = minWidth; | |
style.maxWidth = maxWidth; | |
} | |
} | |
return ret; | |
}; | |
function setPositiveNumber( elem, value, subtract ) { | |
var matches = rnumsplit.exec( value ); | |
return matches ? | |
// Guard against undefined "subtract", e.g., when used as in cssHooks | |
Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : | |
value; | |
} | |
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { | |
var i = extra === ( isBorderBox ? "border" : "content" ) ? | |
// If we already have the right measurement, avoid augmentation | |
4 : | |
// Otherwise initialize for horizontal or vertical properties | |
name === "width" ? 1 : 0, | |
val = 0; | |
for ( ; i < 4; i += 2 ) { | |
// both box models exclude margin, so add it if we want it | |
if ( extra === "margin" ) { | |
val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); | |
} | |
if ( isBorderBox ) { | |
// border-box includes padding, so remove it if we want content | |
if ( extra === "content" ) { | |
val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); | |
} | |
// at this point, extra isn't border nor margin, so remove border | |
if ( extra !== "margin" ) { | |
val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); | |
} | |
} else { | |
// at this point, extra isn't content, so add padding | |
val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); | |
// at this point, extra isn't content nor padding, so add border | |
if ( extra !== "padding" ) { | |
val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); | |
} | |
} | |
} | |
return val; | |
} | |
function getWidthOrHeight( elem, name, extra ) { | |
// Start with offset property, which is equivalent to the border-box value | |
var valueIsBorderBox = true, | |
val = name === "width" ? elem.offsetWidth : elem.offsetHeight, | |
styles = getStyles( elem ), | |
isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; | |
// some non-html elements return undefined for offsetWidth, so check for null/undefined | |
// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 | |
// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 | |
if ( val <= 0 || val == null ) { | |
// Fall back to computed then uncomputed css if necessary | |
val = curCSS( elem, name, styles ); | |
if ( val < 0 || val == null ) { | |
val = elem.style[ name ]; | |
} | |
// Computed unit is not pixels. Stop here and return. | |
if ( rnumnonpx.test(val) ) { | |
return val; | |
} | |
// we need the check for style in case a browser which returns unreliable values | |
// for getComputedStyle silently falls back to the reliable elem.style | |
valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); | |
// Normalize "", auto, and prepare for extra | |
val = parseFloat( val ) || 0; | |
} | |
// use the active box-sizing model to add/subtract irrelevant styles | |
return ( val + | |
augmentWidthOrHeight( | |
elem, | |
name, | |
extra || ( isBorderBox ? "border" : "content" ), | |
valueIsBorderBox, | |
styles | |
) | |
) + "px"; | |
} | |
// Try to determine the default display value of an element | |
function css_defaultDisplay( nodeName ) { | |
var doc = document, | |
display = elemdisplay[ nodeName ]; | |
if ( !display ) { | |
display = actualDisplay( nodeName, doc ); | |
// If the simple way fails, read from inside an iframe | |
if ( display === "none" || !display ) { | |
// Use the already-created iframe if possible | |
iframe = ( iframe || | |
jQuery("<iframe frameborder='0' width='0' height='0'/>") | |
.css( "cssText", "display:block !important" ) | |
).appendTo( doc.documentElement ); | |
// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse | |
doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document; | |
doc.write("<!doctype html><html><body>"); | |
doc.close(); | |
display = actualDisplay( nodeName, doc ); | |
iframe.detach(); | |
} | |
// Store the correct default display | |
elemdisplay[ nodeName ] = display; | |
} | |
return display; | |
} | |
// Called ONLY from within css_defaultDisplay | |
function actualDisplay( name, doc ) { | |
var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), | |
display = jQuery.css( elem[0], "display" ); | |
elem.remove(); | |
return display; | |
} | |
jQuery.each([ "height", "width" ], function( i, name ) { | |
jQuery.cssHooks[ name ] = { | |
get: function( elem, computed, extra ) { | |
if ( computed ) { | |
// certain elements can have dimension info if we invisibly show them | |
// however, it must have a current display style that would benefit from this | |
return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ? | |
jQuery.swap( elem, cssShow, function() { | |
return getWidthOrHeight( elem, name, extra ); | |
}) : | |
getWidthOrHeight( elem, name, extra ); | |
} | |
}, | |
set: function( elem, value, extra ) { | |
var styles = extra && getStyles( elem ); | |
return setPositiveNumber( elem, value, extra ? | |
augmentWidthOrHeight( | |
elem, | |
name, | |
extra, | |
jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", | |
styles | |
) : 0 | |
); | |
} | |
}; | |
}); | |
// These hooks cannot be added until DOM ready because the support test | |
// for it is not run until after DOM ready | |
jQuery(function() { | |
// Support: Android 2.3 | |
if ( !jQuery.support.reliableMarginRight ) { | |
jQuery.cssHooks.marginRight = { | |
get: function( elem, computed ) { | |
if ( computed ) { | |
// Support: Android 2.3 | |
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right | |
// Work around by temporarily setting element display to inline-block | |
return jQuery.swap( elem, { "display": "inline-block" }, | |
curCSS, [ elem, "marginRight" ] ); | |
} | |
} | |
}; | |
} | |
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 | |
// getComputedStyle returns percent when specified for top/left/bottom/right | |
// rather than make the css module depend on the offset module, we just check for it here | |
if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { | |
jQuery.each( [ "top", "left" ], function( i, prop ) { | |
jQuery.cssHooks[ prop ] = { | |
get: function( elem, computed ) { | |
if ( computed ) { | |
computed = curCSS( elem, prop ); | |
// if curCSS returns percentage, fallback to offset | |
return rnumnonpx.test( computed ) ? | |
jQuery( elem ).position()[ prop ] + "px" : | |
computed; | |
} | |
} | |
}; | |
}); | |
} | |
}); | |
if ( jQuery.expr && jQuery.expr.filters ) { | |
jQuery.expr.filters.hidden = function( elem ) { | |
// Support: Opera <= 12.12 | |
// Opera reports offsetWidths and offsetHeights less than zero on some elements | |
return elem.offsetWidth <= 0 && elem.offsetHeight <= 0; | |
}; | |
jQuery.expr.filters.visible = function( elem ) { | |
return !jQuery.expr.filters.hidden( elem ); | |
}; | |
} | |
// These hooks are used by animate to expand properties | |
jQuery.each({ | |
margin: "", | |
padding: "", | |
border: "Width" | |
}, function( prefix, suffix ) { | |
jQuery.cssHooks[ prefix + suffix ] = { | |
expand: function( value ) { | |
var i = 0, | |
expanded = {}, | |
// assumes a single number if not a string | |
parts = typeof value === "string" ? value.split(" ") : [ value ]; | |
for ( ; i < 4; i++ ) { | |
expanded[ prefix + cssExpand[ i ] + suffix ] = | |
parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; | |
} | |
return expanded; | |
} | |
}; | |
if ( !rmargin.test( prefix ) ) { | |
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; | |
} | |
}); | |
var r20 = /%20/g, | |
rbracket = /\[\]$/, | |
rCRLF = /\r?\n/g, | |
rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, | |
rsubmittable = /^(?:input|select|textarea|keygen)/i; | |
jQuery.fn.extend({ | |
serialize: function() { | |
return jQuery.param( this.serializeArray() ); | |
}, | |
serializeArray: function() { | |
return this.map(function(){ | |
// Can add propHook for "elements" to filter or add form elements | |
var elements = jQuery.prop( this, "elements" ); | |
return elements ? jQuery.makeArray( elements ) : this; | |
}) | |
.filter(function(){ | |
var type = this.type; | |
// Use .is(":disabled") so that fieldset[disabled] works | |
return this.name && !jQuery( this ).is( ":disabled" ) && | |
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && | |
( this.checked || !manipulation_rcheckableType.test( type ) ); | |
}) | |
.map(function( i, elem ){ | |
var val = jQuery( this ).val(); | |
return val == null ? | |
null : | |
jQuery.isArray( val ) ? | |
jQuery.map( val, function( val ){ | |
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
}) : | |
{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; | |
}).get(); | |
} | |
}); | |
//Serialize an array of form elements or a set of | |
//key/values into a query string | |
jQuery.param = function( a, traditional ) { | |
var prefix, | |
s = [], | |
add = function( key, value ) { | |
// If value is a function, invoke it and return its value | |
value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); | |
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); | |
}; | |
// Set traditional to true for jQuery <= 1.3.2 behavior. | |
if ( traditional === undefined ) { | |
traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; | |
} | |
// If an array was passed in, assume that it is an array of form elements. | |
if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { | |
// Serialize the form elements | |
jQuery.each( a, function() { | |
add( this.name, this.value ); | |
}); | |
} else { | |
// If traditional, encode the "old" way (the way 1.3.2 or older | |
// did it), otherwise encode params recursively. | |
for ( prefix in a ) { | |
buildParams( prefix, a[ prefix ], traditional, add ); | |
} | |
} | |
// Return the resulting serialization | |
return s.join( "&" ).replace( r20, "+" ); | |
}; | |
function buildParams( prefix, obj, traditional, add ) { | |
var name; | |
if ( jQuery.isArray( obj ) ) { | |
// Serialize array item. | |
jQuery.each( obj, function( i, v ) { | |
if ( traditional || rbracket.test( prefix ) ) { | |
// Treat each array item as a scalar. | |
add( prefix, v ); | |
} else { | |
// Item is non-scalar (array or object), encode its numeric index. | |
buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); | |
} | |
}); | |
} else if ( !traditional && jQuery.type( obj ) === "object" ) { | |
// Serialize object item. | |
for ( name in obj ) { | |
buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); | |
} | |
} else { | |
// Serialize scalar item. | |
add( prefix, obj ); | |
} | |
} | |
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + | |
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + | |
"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { | |
// Handle event binding | |
jQuery.fn[ name ] = function( data, fn ) { | |
return arguments.length > 0 ? | |
this.on( name, null, data, fn ) : | |
this.trigger( name ); | |
}; | |
}); | |
jQuery.fn.extend({ | |
hover: function( fnOver, fnOut ) { | |
return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); | |
}, | |
bind: function( types, data, fn ) { | |
return this.on( types, null, data, fn ); | |
}, | |
unbind: function( types, fn ) { | |
return this.off( types, null, fn ); | |
}, | |
delegate: function( selector, types, data, fn ) { | |
return this.on( types, selector, data, fn ); | |
}, | |
undelegate: function( selector, types, fn ) { | |
// ( namespace ) or ( selector, types [, fn] ) | |
return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); | |
} | |
}); | |
var | |
// Document location | |
ajaxLocParts, | |
ajaxLocation, | |
ajax_nonce = jQuery.now(), | |
ajax_rquery = /\?/, | |
rhash = /#.*$/, | |
rts = /([?&])_=[^&]*/, | |
rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, | |
// #7653, #8125, #8152: local protocol detection | |
rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, | |
rnoContent = /^(?:GET|HEAD)$/, | |
rprotocol = /^\/\//, | |
rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, | |
// Keep a copy of the old load method | |
_load = jQuery.fn.load, | |
/* Prefilters | |
* 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) | |
* 2) These are called: | |
* - BEFORE asking for a transport | |
* - AFTER param serialization (s.data is a string if s.processData is true) | |
* 3) key is the dataType | |
* 4) the catchall symbol "*" can be used | |
* 5) execution will start with transport dataType and THEN continue down to "*" if needed | |
*/ | |
prefilters = {}, | |
/* Transports bindings | |
* 1) key is the dataType | |
* 2) the catchall symbol "*" can be used | |
* 3) selection will start with transport dataType and THEN go to "*" if needed | |
*/ | |
transports = {}, | |
// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression | |
allTypes = "*/".concat("*"); | |
// #8138, IE may throw an exception when accessing | |
// a field from window.location if document.domain has been set | |
try { | |
ajaxLocation = location.href; | |
} catch( e ) { | |
// Use the href attribute of an A element | |
// since IE will modify it given document.location | |
ajaxLocation = document.createElement( "a" ); | |
ajaxLocation.href = ""; | |
ajaxLocation = ajaxLocation.href; | |
} | |
// Segment location into parts | |
ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; | |
// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport | |
function addToPrefiltersOrTransports( structure ) { | |
// dataTypeExpression is optional and defaults to "*" | |
return function( dataTypeExpression, func ) { | |
if ( typeof dataTypeExpression !== "string" ) { | |
func = dataTypeExpression; | |
dataTypeExpression = "*"; | |
} | |
var dataType, | |
i = 0, | |
dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || []; | |
if ( jQuery.isFunction( func ) ) { | |
// For each dataType in the dataTypeExpression | |
while ( (dataType = dataTypes[i++]) ) { | |
// Prepend if requested | |
if ( dataType[0] === "+" ) { | |
dataType = dataType.slice( 1 ) || "*"; | |
(structure[ dataType ] = structure[ dataType ] || []).unshift( func ); | |
// Otherwise append | |
} else { | |
(structure[ dataType ] = structure[ dataType ] || []).push( func ); | |
} | |
} | |
} | |
}; | |
} | |
// Base inspection function for prefilters and transports | |
function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { | |
var inspected = {}, | |
seekingTransport = ( structure === transports ); | |
function inspect( dataType ) { | |
var selected; | |
inspected[ dataType ] = true; | |
jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { | |
var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); | |
if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { | |
options.dataTypes.unshift( dataTypeOrTransport ); | |
inspect( dataTypeOrTransport ); | |
return false; | |
} else if ( seekingTransport ) { | |
return !( selected = dataTypeOrTransport ); | |
} | |
}); | |
return selected; | |
} | |
return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); | |
} | |
// A special extend for ajax options | |
// that takes "flat" options (not to be deep extended) | |
// Fixes #9887 | |
function ajaxExtend( target, src ) { | |
var key, deep, | |
flatOptions = jQuery.ajaxSettings.flatOptions || {}; | |
for ( key in src ) { | |
if ( src[ key ] !== undefined ) { | |
( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; | |
} | |
} | |
if ( deep ) { | |
jQuery.extend( true, target, deep ); | |
} | |
return target; | |
} | |
jQuery.fn.load = function( url, params, callback ) { | |
if ( typeof url !== "string" && _load ) { | |
return _load.apply( this, arguments ); | |
} | |
var selector, type, response, | |
self = this, | |
off = url.indexOf(" "); | |
if ( off >= 0 ) { | |
selector = url.slice( off ); | |
url = url.slice( 0, off ); | |
} | |
// If it's a function | |
if ( jQuery.isFunction( params ) ) { | |
// We assume that it's the callback | |
callback = params; | |
params = undefined; | |
// Otherwise, build a param string | |
} else if ( params && typeof params === "object" ) { | |
type = "POST"; | |
} | |
// If we have elements to modify, make the request | |
if ( self.length > 0 ) { | |
jQuery.ajax({ | |
url: url, | |
// if "type" variable is undefined, then "GET" method will be used | |
type: type, | |
dataType: "html", | |
data: params | |
}).done(function( responseText ) { | |
// Save response for use in complete callback | |
response = arguments; | |
self.html( selector ? | |
// If a selector was specified, locate the right elements in a dummy div | |
// Exclude scripts to avoid IE 'Permission Denied' errors | |
jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : | |
// Otherwise use the full result | |
responseText ); | |
}).complete( callback && function( jqXHR, status ) { | |
self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); | |
}); | |
} | |
return this; | |
}; | |
// Attach a bunch of functions for handling common AJAX events | |
jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){ | |
jQuery.fn[ type ] = function( fn ){ | |
return this.on( type, fn ); | |
}; | |
}); | |
jQuery.extend({ | |
// Counter for holding the number of active queries | |
active: 0, | |
// Last-Modified header cache for next request | |
lastModified: {}, | |
etag: {}, | |
ajaxSettings: { | |
url: ajaxLocation, | |
type: "GET", | |
isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), | |
global: true, | |
processData: true, | |
async: true, | |
contentType: "application/x-www-form-urlencoded; charset=UTF-8", | |
/* | |
timeout: 0, | |
data: null, | |
dataType: null, | |
username: null, | |
password: null, | |
cache: null, | |
throws: false, | |
traditional: false, | |
headers: {}, | |
*/ | |
accepts: { | |
"*": allTypes, | |
text: "text/plain", | |
html: "text/html", | |
xml: "application/xml, text/xml", | |
json: "application/json, text/javascript" | |
}, | |
contents: { | |
xml: /xml/, | |
html: /html/, | |
json: /json/ | |
}, | |
responseFields: { | |
xml: "responseXML", | |
text: "responseText", | |
json: "responseJSON" | |
}, | |
// Data converters | |
// Keys separate source (or catchall "*") and destination types with a single space | |
converters: { | |
// Convert anything to text | |
"* text": String, | |
// Text to html (true = no transformation) | |
"text html": true, | |
// Evaluate text as a json expression | |
"text json": jQuery.parseJSON, | |
// Parse text as xml | |
"text xml": jQuery.parseXML | |
}, | |
// For options that shouldn't be deep extended: | |
// you can add your own custom options here if | |
// and when you create one that shouldn't be | |
// deep extended (see ajaxExtend) | |
flatOptions: { | |
url: true, | |
context: true | |
} | |
}, | |
// Creates a full fledged settings object into target | |
// with both ajaxSettings and settings fields. | |
// If target is omitted, writes into ajaxSettings. | |
ajaxSetup: function( target, settings ) { | |
return settings ? | |
// Building a settings object | |
ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : | |
// Extending ajaxSettings | |
ajaxExtend( jQuery.ajaxSettings, target ); | |
}, | |
ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), | |
ajaxTransport: addToPrefiltersOrTransports( transports ), | |
// Main method | |
ajax: function( url, options ) { | |
// If url is an object, simulate pre-1.5 signature | |
if ( typeof url === "object" ) { | |
options = url; | |
url = undefined; | |
} | |
// Force options to be an object | |
options = options || {}; | |
var transport, | |
// URL without anti-cache param | |
cacheURL, | |
// Response headers | |
responseHeadersString, | |
responseHeaders, | |
// timeout handle | |
timeoutTimer, | |
// Cross-domain detection vars | |
parts, | |
// To know if global events are to be dispatched | |
fireGlobals, | |
// Loop variable | |
i, | |
// Create the final options object | |
s = jQuery.ajaxSetup( {}, options ), | |
// Callbacks context | |
callbackContext = s.context || s, | |
// Context for global events is callbackContext if it is a DOM node or jQuery collection | |
globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? | |
jQuery( callbackContext ) : | |
jQuery.event, | |
// Deferreds | |
deferred = jQuery.Deferred(), | |
completeDeferred = jQuery.Callbacks("once memory"), | |
// Status-dependent callbacks | |
statusCode = s.statusCode || {}, | |
// Headers (they are sent all at once) | |
requestHeaders = {}, | |
requestHeadersNames = {}, | |
// The jqXHR state | |
state = 0, | |
// Default abort message | |
strAbort = "canceled", | |
// Fake xhr | |
jqXHR = { | |
readyState: 0, | |
// Builds headers hashtable if needed | |
getResponseHeader: function( key ) { | |
var match; | |
if ( state === 2 ) { | |
if ( !responseHeaders ) { | |
responseHeaders = {}; | |
while ( (match = rheaders.exec( responseHeadersString )) ) { | |
responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; | |
} | |
} | |
match = responseHeaders[ key.toLowerCase() ]; | |
} | |
return match == null ? null : match; | |
}, | |
// Raw string | |
getAllResponseHeaders: function() { | |
return state === 2 ? responseHeadersString : null; | |
}, | |
// Caches the header | |
setRequestHeader: function( name, value ) { | |
var lname = name.toLowerCase(); | |
if ( !state ) { | |
name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; | |
requestHeaders[ name ] = value; | |
} | |
return this; | |
}, | |
// Overrides response content-type header | |
overrideMimeType: function( type ) { | |
if ( !state ) { | |
s.mimeType = type; | |
} | |
return this; | |
}, | |
// Status-dependent callbacks | |
statusCode: function( map ) { | |
var code; | |
if ( map ) { | |
if ( state < 2 ) { | |
for ( code in map ) { | |
// Lazy-add the new callback in a way that preserves old ones | |
statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; | |
} | |
} else { | |
// Execute the appropriate callbacks | |
jqXHR.always( map[ jqXHR.status ] ); | |
} | |
} | |
return this; | |
}, | |
// Cancel the request | |
abort: function( statusText ) { | |
var finalText = statusText || strAbort; | |
if ( transport ) { | |
transport.abort( finalText ); | |
} | |
done( 0, finalText ); | |
return this; | |
} | |
}; | |
// Attach deferreds | |
deferred.promise( jqXHR ).complete = completeDeferred.add; | |
jqXHR.success = jqXHR.done; | |
jqXHR.error = jqXHR.fail; | |
// Remove hash character (#7531: and string promotion) | |
// Add protocol if not provided (prefilters might expect it) | |
// Handle falsy url in the settings object (#10093: consistency with old signature) | |
// We also use the url parameter if available | |
s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ) | |
.replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); | |
// Alias method option to type as per ticket #12004 | |
s.type = options.method || options.type || s.method || s.type; | |
// Extract dataTypes list | |
s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""]; | |
// A cross-domain request is in order when we have a protocol:host:port mismatch | |
if ( s.crossDomain == null ) { | |
parts = rurl.exec( s.url.toLowerCase() ); | |
s.crossDomain = !!( parts && | |
( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || | |
( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== | |
( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) | |
); | |
} | |
// Convert data if not already a string | |
if ( s.data && s.processData && typeof s.data !== "string" ) { | |
s.data = jQuery.param( s.data, s.traditional ); | |
} | |
// Apply prefilters | |
inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); | |
// If request was aborted inside a prefilter, stop there | |
if ( state === 2 ) { | |
return jqXHR; | |
} | |
// We can fire global events as of now if asked to | |
fireGlobals = s.global; | |
// Watch for a new set of requests | |
if ( fireGlobals && jQuery.active++ === 0 ) { | |
jQuery.event.trigger("ajaxStart"); | |
} | |
// Uppercase the type | |
s.type = s.type.toUpperCase(); | |
// Determine if request has content | |
s.hasContent = !rnoContent.test( s.type ); | |
// Save the URL in case we're toying with the If-Modified-Since | |
// and/or If-None-Match header later on | |
cacheURL = s.url; | |
// More options handling for requests with no content | |
if ( !s.hasContent ) { | |
// If data is available, append data to url | |
if ( s.data ) { | |
cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); | |
// #9682: remove data so that it's not used in an eventual retry | |
delete s.data; | |
} | |
// Add anti-cache in url if needed | |
if ( s.cache === false ) { | |
s.url = rts.test( cacheURL ) ? | |
// If there is already a '_' parameter, set its value | |
cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) : | |
// Otherwise add one to the end | |
cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++; | |
} | |
} | |
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. | |
if ( s.ifModified ) { | |
if ( jQuery.lastModified[ cacheURL ] ) { | |
jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); | |
} | |
if ( jQuery.etag[ cacheURL ] ) { | |
jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); | |
} | |
} | |
// Set the correct header, if data is being sent | |
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { | |
jqXHR.setRequestHeader( "Content-Type", s.contentType ); | |
} | |
// Set the Accepts header for the server, depending on the dataType | |
jqXHR.setRequestHeader( | |
"Accept", | |
s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? | |
s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : | |
s.accepts[ "*" ] | |
); | |
// Check for headers option | |
for ( i in s.headers ) { | |
jqXHR.setRequestHeader( i, s.headers[ i ] ); | |
} | |
// Allow custom headers/mimetypes and early abort | |
if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { | |
// Abort if not done already and return | |
return jqXHR.abort(); | |
} | |
// aborting is no longer a cancellation | |
strAbort = "abort"; | |
// Install callbacks on deferreds | |
for ( i in { success: 1, error: 1, complete: 1 } ) { | |
jqXHR[ i ]( s[ i ] ); | |
} | |
// Get transport | |
transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); | |
// If no transport, we auto-abort | |
if ( !transport ) { | |
done( -1, "No Transport" ); | |
} else { | |
jqXHR.readyState = 1; | |
// Send global event | |
if ( fireGlobals ) { | |
globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); | |
} | |
// Timeout | |
if ( s.async && s.timeout > 0 ) { | |
timeoutTimer = setTimeout(function() { | |
jqXHR.abort("timeout"); | |
}, s.timeout ); | |
} | |
try { | |
state = 1; | |
transport.send( requestHeaders, done ); | |
} catch ( e ) { | |
// Propagate exception as error if not done | |
if ( state < 2 ) { | |
done( -1, e ); | |
// Simply rethrow otherwise | |
} else { | |
throw e; | |
} | |
} | |
} | |
// Callback for when everything is done | |
function done( status, nativeStatusText, responses, headers ) { | |
var isSuccess, success, error, response, modified, | |
statusText = nativeStatusText; | |
// Called once | |
if ( state === 2 ) { | |
return; | |
} | |
// State is "done" now | |
state = 2; | |
// Clear timeout if it exists | |
if ( timeoutTimer ) { | |
clearTimeout( timeoutTimer ); | |
} | |
// Dereference transport for early garbage collection | |
// (no matter how long the jqXHR object will be used) | |
transport = undefined; | |
// Cache response headers | |
responseHeadersString = headers || ""; | |
// Set readyState | |
jqXHR.readyState = status > 0 ? 4 : 0; | |
// Determine if successful | |
isSuccess = status >= 200 && status < 300 || status === 304; | |
// Get response data | |
if ( responses ) { | |
response = ajaxHandleResponses( s, jqXHR, responses ); | |
} | |
// Convert no matter what (that way responseXXX fields are always set) | |
response = ajaxConvert( s, response, jqXHR, isSuccess ); | |
// If successful, handle type chaining | |
if ( isSuccess ) { | |
// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. | |
if ( s.ifModified ) { | |
modified = jqXHR.getResponseHeader("Last-Modified"); | |
if ( modified ) { | |
jQuery.lastModified[ cacheURL ] = modified; | |
} | |
modified = jqXHR.getResponseHeader("etag"); | |
if ( modified ) { | |
jQuery.etag[ cacheURL ] = modified; | |
} | |
} | |
// if no content | |
if ( status === 204 ) { | |
statusText = "nocontent"; | |
// if not modified | |
} else if ( status === 304 ) { | |
statusText = "notmodified"; | |
// If we have data, let's convert it | |
} else { | |
statusText = response.state; | |
success = response.data; | |
error = response.error; | |
isSuccess = !error; | |
} | |
} else { | |
// We extract error from statusText | |
// then normalize statusText and status for non-aborts | |
error = statusText; | |
if ( status || !statusText ) { | |
statusText = "error"; | |
if ( status < 0 ) { | |
status = 0; | |
} | |
} | |
} | |
// Set data for the fake xhr object | |
jqXHR.status = status; | |
jqXHR.statusText = ( nativeStatusText || statusText ) + ""; | |
// Success/Error | |
if ( isSuccess ) { | |
deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); | |
} else { | |
deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); | |
} | |
// Status-dependent callbacks | |
jqXHR.statusCode( statusCode ); | |
statusCode = undefined; | |
if ( fireGlobals ) { | |
globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", | |
[ jqXHR, s, isSuccess ? success : error ] ); | |
} | |
// Complete | |
completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); | |
if ( fireGlobals ) { | |
globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); | |
// Handle the global AJAX counter | |
if ( !( --jQuery.active ) ) { | |
jQuery.event.trigger("ajaxStop"); | |
} | |
} | |
} | |
return jqXHR; | |
}, | |
getJSON: function( url, data, callback ) { | |
return jQuery.get( url, data, callback, "json" ); | |
}, | |
getScript: function( url, callback ) { | |
return jQuery.get( url, undefined, callback, "script" ); | |
} | |
}); | |
jQuery.each( [ "get", "post" ], function( i, method ) { | |
jQuery[ method ] = function( url, data, callback, type ) { | |
// shift arguments if data argument was omitted | |
if ( jQuery.isFunction( data ) ) { | |
type = type || callback; | |
callback = data; | |
data = undefined; | |
} | |
return jQuery.ajax({ | |
url: url, | |
type: method, | |
dataType: type, | |
data: data, | |
success: callback | |
}); | |
}; | |
}); | |
/* Handles responses to an ajax request: | |
* - finds the right dataType (mediates between content-type and expected dataType) | |
* - returns the corresponding response | |
*/ | |
function ajaxHandleResponses( s, jqXHR, responses ) { | |
var ct, type, finalDataType, firstDataType, | |
contents = s.contents, | |
dataTypes = s.dataTypes; | |
// Remove auto dataType and get content-type in the process | |
while( dataTypes[ 0 ] === "*" ) { | |
dataTypes.shift(); | |
if ( ct === undefined ) { | |
ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); | |
} | |
} | |
// Check if we're dealing with a known content-type | |
if ( ct ) { | |
for ( type in contents ) { | |
if ( contents[ type ] && contents[ type ].test( ct ) ) { | |
dataTypes.unshift( type ); | |
break; | |
} | |
} | |
} | |
// Check to see if we have a response for the expected dataType | |
if ( dataTypes[ 0 ] in responses ) { | |
finalDataType = dataTypes[ 0 ]; | |
} else { | |
// Try convertible dataTypes | |
for ( type in responses ) { | |
if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { | |
finalDataType = type; | |
break; | |
} | |
if ( !firstDataType ) { | |
firstDataType = type; | |
} | |
} | |
// Or just use first one | |
finalDataType = finalDataType || firstDataType; | |
} | |
// If we found a dataType | |
// We add the dataType to the list if needed | |
// and return the corresponding response | |
if ( finalDataType ) { | |
if ( finalDataType !== dataTypes[ 0 ] ) { | |
dataTypes.unshift( finalDataType ); | |
} | |
return responses[ finalDataType ]; | |
} | |
} | |
/* Chain conversions given the request and the original response | |
* Also sets the responseXXX fields on the jqXHR instance | |
*/ | |
function ajaxConvert( s, response, jqXHR, isSuccess ) { | |
var conv2, current, conv, tmp, prev, | |
converters = {}, | |
// Work with a copy of dataTypes in case we need to modify it for conversion | |
dataTypes = s.dataTypes.slice(); | |
// Create converters map with lowercased keys | |
if ( dataTypes[ 1 ] ) { | |
for ( conv in s.converters ) { | |
converters[ conv.toLowerCase() ] = s.converters[ conv ]; | |
} | |
} | |
current = dataTypes.shift(); | |
// Convert to each sequential dataType | |
while ( current ) { | |
if ( s.responseFields[ current ] ) { | |
jqXHR[ s.responseFields[ current ] ] = response; | |
} | |
// Apply the dataFilter if provided | |
if ( !prev && isSuccess && s.dataFilter ) { | |
response = s.dataFilter( response, s.dataType ); | |
} | |
prev = current; | |
current = dataTypes.shift(); | |
if ( current ) { | |
// There's only work to do if current dataType is non-auto | |
if ( current === "*" ) { | |
current = prev; | |
// Convert response if prev dataType is non-auto and differs from current | |
} else if ( prev !== "*" && prev !== current ) { | |
// Seek a direct converter | |
conv = converters[ prev + " " + current ] || converters[ "* " + current ]; | |
// If none found, seek a pair | |
if ( !conv ) { | |
for ( conv2 in converters ) { | |
// If conv2 outputs current | |
tmp = conv2.split( " " ); | |
if ( tmp[ 1 ] === current ) { | |
// If prev can be converted to accepted input | |
conv = converters[ prev + " " + tmp[ 0 ] ] || | |
converters[ "* " + tmp[ 0 ] ]; | |
if ( conv ) { | |
// Condense equivalence converters | |
if ( conv === true ) { | |
conv = converters[ conv2 ]; | |
// Otherwise, insert the intermediate dataType | |
} else if ( converters[ conv2 ] !== true ) { | |
current = tmp[ 0 ]; | |
dataTypes.unshift( tmp[ 1 ] ); | |
} | |
break; | |
} | |
} | |
} | |
} | |
// Apply converter (if not an equivalence) | |
if ( conv !== true ) { | |
// Unless errors are allowed to bubble, catch and return them | |
if ( conv && s[ "throws" ] ) { | |
response = conv( response ); | |
} else { | |
try { | |
response = conv( response ); | |
} catch ( e ) { | |
return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; | |
} | |
} | |
} | |
} | |
} | |
} | |
return { state: "success", data: response }; | |
} | |
// Install script dataType | |
jQuery.ajaxSetup({ | |
accepts: { | |
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" | |
}, | |
contents: { | |
script: /(?:java|ecma)script/ | |
}, | |
converters: { | |
"text script": function( text ) { | |
jQuery.globalEval( text ); | |
return text; | |
} | |
} | |
}); | |
// Handle cache's special case and crossDomain | |
jQuery.ajaxPrefilter( "script", function( s ) { | |
if ( s.cache === undefined ) { | |
s.cache = false; | |
} | |
if ( s.crossDomain ) { | |
s.type = "GET"; | |
} | |
}); | |
// Bind script tag hack transport | |
jQuery.ajaxTransport( "script", function( s ) { | |
// This transport only deals with cross domain requests | |
if ( s.crossDomain ) { | |
var script, callback; | |
return { | |
send: function( _, complete ) { | |
script = jQuery("<script>").prop({ | |
async: true, | |
charset: s.scriptCharset, | |
src: s.url | |
}).on( | |
"load error", | |
callback = function( evt ) { | |
script.remove(); | |
callback = null; | |
if ( evt ) { | |
complete( evt.type === "error" ? 404 : 200, evt.type ); | |
} | |
} | |
); | |
document.head.appendChild( script[ 0 ] ); | |
}, | |
abort: function() { | |
if ( callback ) { | |
callback(); | |
} | |
} | |
}; | |
} | |
}); | |
var oldCallbacks = [], | |
rjsonp = /(=)\?(?=&|$)|\?\?/; | |
// Default jsonp settings | |
jQuery.ajaxSetup({ | |
jsonp: "callback", | |
jsonpCallback: function() { | |
var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) ); | |
this[ callback ] = true; | |
return callback; | |
} | |
}); | |
// Detect, normalize options and install callbacks for jsonp requests | |
jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { | |
var callbackName, overwritten, responseContainer, | |
jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? | |
"url" : | |
typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" | |
); | |
// Handle iff the expected data type is "jsonp" or we have a parameter to set | |
if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { | |
// Get callback name, remembering preexisting value associated with it | |
callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? | |
s.jsonpCallback() : | |
s.jsonpCallback; | |
// Insert callback into url or form data | |
if ( jsonProp ) { | |
s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); | |
} else if ( s.jsonp !== false ) { | |
s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; | |
} | |
// Use data converter to retrieve json after script execution | |
s.converters["script json"] = function() { | |
if ( !responseContainer ) { | |
jQuery.error( callbackName + " was not called" ); | |
} | |
return responseContainer[ 0 ]; | |
}; | |
// force json dataType | |
s.dataTypes[ 0 ] = "json"; | |
// Install callback | |
overwritten = window[ callbackName ]; | |
window[ callbackName ] = function() { | |
responseContainer = arguments; | |
}; | |
// Clean-up function (fires after converters) | |
jqXHR.always(function() { | |
// Restore preexisting value | |
window[ callbackName ] = overwritten; | |
// Save back as free | |
if ( s[ callbackName ] ) { | |
// make sure that re-using the options doesn't screw things around | |
s.jsonpCallback = originalSettings.jsonpCallback; | |
// save the callback name for future use | |
oldCallbacks.push( callbackName ); | |
} | |
// Call if it was a function and we have a response | |
if ( responseContainer && jQuery.isFunction( overwritten ) ) { | |
overwritten( responseContainer[ 0 ] ); | |
} | |
responseContainer = overwritten = undefined; | |
}); | |
// Delegate to script | |
return "script"; | |
} | |
}); | |
jQuery.ajaxSettings.xhr = function() { | |
try { | |
return new XMLHttpRequest(); | |
} catch( e ) {} | |
}; | |
var xhrSupported = jQuery.ajaxSettings.xhr(), | |
xhrSuccessStatus = { | |
// file protocol always yields status code 0, assume 200 | |
0: 200, | |
// Support: IE9 | |
// #1450: sometimes IE returns 1223 when it should be 204 | |
1223: 204 | |
}, | |
// Support: IE9 | |
// We need to keep track of outbound xhr and abort them manually | |
// because IE is not smart enough to do it all by itself | |
xhrId = 0, | |
xhrCallbacks = {}; | |
if ( window.ActiveXObject ) { | |
jQuery( window ).on( "unload", function() { | |
for( var key in xhrCallbacks ) { | |
xhrCallbacks[ key ](); | |
} | |
xhrCallbacks = undefined; | |
}); | |
} | |
jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); | |
jQuery.support.ajax = xhrSupported = !!xhrSupported; | |
jQuery.ajaxTransport(function( options ) { | |
var callback; | |
// Cross domain only allowed if supported through XMLHttpRequest | |
if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) { | |
return { | |
send: function( headers, complete ) { | |
var i, id, | |
xhr = options.xhr(); | |
xhr.open( options.type, options.url, options.async, options.username, options.password ); | |
// Apply custom fields if provided | |
if ( options.xhrFields ) { | |
for ( i in options.xhrFields ) { | |
xhr[ i ] = options.xhrFields[ i ]; | |
} | |
} | |
// Override mime type if needed | |
if ( options.mimeType && xhr.overrideMimeType ) { | |
xhr.overrideMimeType( options.mimeType ); | |
} | |
// X-Requested-With header | |
// For cross-domain requests, seeing as conditions for a preflight are | |
// akin to a jigsaw puzzle, we simply never set it to be sure. | |
// (it can always be set on a per-request basis or even using ajaxSetup) | |
// For same-domain requests, won't change header if already provided. | |
if ( !options.crossDomain && !headers["X-Requested-With"] ) { | |
headers["X-Requested-With"] = "XMLHttpRequest"; | |
} | |
// Set headers | |
for ( i in headers ) { | |
xhr.setRequestHeader( i, headers[ i ] ); | |
} | |
// Callback | |
callback = function( type ) { | |
return function() { | |
if ( callback ) { | |
delete xhrCallbacks[ id ]; | |
callback = xhr.onload = xhr.onerror = null; | |
if ( type === "abort" ) { | |
xhr.abort(); | |
} else if ( type === "error" ) { | |
complete( | |
// file protocol always yields status 0, assume 404 | |
xhr.status || 404, | |
xhr.statusText | |
); | |
} else { | |
complete( | |
xhrSuccessStatus[ xhr.status ] || xhr.status, | |
xhr.statusText, | |
// Support: IE9 | |
// #11426: When requesting binary data, IE9 will throw an exception | |
// on any attempt to access responseText | |
typeof xhr.responseText === "string" ? { | |
text: xhr.responseText | |
} : undefined, | |
xhr.getAllResponseHeaders() | |
); | |
} | |
} | |
}; | |
}; | |
// Listen to events | |
xhr.onload = callback(); | |
xhr.onerror = callback("error"); | |
// Create the abort callback | |
callback = xhrCallbacks[( id = xhrId++ )] = callback("abort"); | |
// Do send the request | |
// This may raise an exception which is actually | |
// handled in jQuery.ajax (so no try/catch here) | |
xhr.send( options.hasContent && options.data || null ); | |
}, | |
abort: function() { | |
if ( callback ) { | |
callback(); | |
} | |
} | |
}; | |
} | |
}); | |
var fxNow, timerId, | |
rfxtypes = /^(?:toggle|show|hide)$/, | |
rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), | |
rrun = /queueHooks$/, | |
animationPrefilters = [ defaultPrefilter ], | |
tweeners = { | |
"*": [function( prop, value ) { | |
var end, unit, | |
tween = this.createTween( prop, value ), | |
parts = rfxnum.exec( value ), | |
target = tween.cur(), | |
start = +target || 0, | |
scale = 1, | |
maxIterations = 20; | |
if ( parts ) { | |
end = +parts[2]; | |
unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); | |
// We need to compute starting value | |
if ( unit !== "px" && start ) { | |
// Iteratively approximate from a nonzero starting point | |
// Prefer the current property, because this process will be trivial if it uses the same units | |
// Fallback to end or a simple constant | |
start = jQuery.css( tween.elem, prop, true ) || end || 1; | |
do { | |
// If previous iteration zeroed out, double until we get *something* | |
// Use a string for doubling factor so we don't accidentally see scale as unchanged below | |
scale = scale || ".5"; | |
// Adjust and apply | |
start = start / scale; | |
jQuery.style( tween.elem, prop, start + unit ); | |
// Update scale, tolerating zero or NaN from tween.cur() | |
// And breaking the loop if scale is unchanged or perfect, or if we've just had enough | |
} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); | |
} | |
tween.unit = unit; | |
tween.start = start; | |
// If a +=/-= token was provided, we're doing a relative animation | |
tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; | |
} | |
return tween; | |
}] | |
}; | |
// Animations created synchronously will run synchronously | |
function createFxNow() { | |
setTimeout(function() { | |
fxNow = undefined; | |
}); | |
return ( fxNow = jQuery.now() ); | |
} | |
function createTweens( animation, props ) { | |
jQuery.each( props, function( prop, value ) { | |
var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), | |
index = 0, | |
length = collection.length; | |
for ( ; index < length; index++ ) { | |
if ( collection[ index ].call( animation, prop, value ) ) { | |
// we're done with this property | |
return; | |
} | |
} | |
}); | |
} | |
function Animation( elem, properties, options ) { | |
var result, | |
stopped, | |
index = 0, | |
length = animationPrefilters.length, | |
deferred = jQuery.Deferred().always( function() { | |
// don't match elem in the :animated selector | |
delete tick.elem; | |
}), | |
tick = function() { | |
if ( stopped ) { | |
return false; | |
} | |
var currentTime = fxNow || createFxNow(), | |
remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), | |
// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) | |
temp = remaining / animation.duration || 0, | |
percent = 1 - temp, | |
index = 0, | |
length = animation.tweens.length; | |
for ( ; index < length ; index++ ) { | |
animation.tweens[ index ].run( percent ); | |
} | |
deferred.notifyWith( elem, [ animation, percent, remaining ]); | |
if ( percent < 1 && length ) { | |
return remaining; | |
} else { | |
deferred.resolveWith( elem, [ animation ] ); | |
return false; | |
} | |
}, | |
animation = deferred.promise({ | |
elem: elem, | |
props: jQuery.extend( {}, properties ), | |
opts: jQuery.extend( true, { specialEasing: {} }, options ), | |
originalProperties: properties, | |
originalOptions: options, | |
startTime: fxNow || createFxNow(), | |
duration: options.duration, | |
tweens: [], | |
createTween: function( prop, end ) { | |
var tween = jQuery.Tween( elem, animation.opts, prop, end, | |
animation.opts.specialEasing[ prop ] || animation.opts.easing ); | |
animation.tweens.push( tween ); | |
return tween; | |
}, | |
stop: function( gotoEnd ) { | |
var index = 0, | |
// if we are going to the end, we want to run all the tweens | |
// otherwise we skip this part | |
length = gotoEnd ? animation.tweens.length : 0; | |
if ( stopped ) { | |
return this; | |
} | |
stopped = true; | |
for ( ; index < length ; index++ ) { | |
animation.tweens[ index ].run( 1 ); | |
} | |
// resolve when we played the last frame | |
// otherwise, reject | |
if ( gotoEnd ) { | |
deferred.resolveWith( elem, [ animation, gotoEnd ] ); | |
} else { | |
deferred.rejectWith( elem, [ animation, gotoEnd ] ); | |
} | |
return this; | |
} | |
}), | |
props = animation.props; | |
propFilter( props, animation.opts.specialEasing ); | |
for ( ; index < length ; index++ ) { | |
result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); | |
if ( result ) { | |
return result; | |
} | |
} | |
createTweens( animation, props ); | |
if ( jQuery.isFunction( animation.opts.start ) ) { | |
animation.opts.start.call( elem, animation ); | |
} | |
jQuery.fx.timer( | |
jQuery.extend( tick, { | |
elem: elem, | |
anim: animation, | |
queue: animation.opts.queue | |
}) | |
); | |
// attach callbacks from options | |
return animation.progress( animation.opts.progress ) | |
.done( animation.opts.done, animation.opts.complete ) | |
.fail( animation.opts.fail ) | |
.always( animation.opts.always ); | |
} | |
function propFilter( props, specialEasing ) { | |
var index, name, easing, value, hooks; | |
// camelCase, specialEasing and expand cssHook pass | |
for ( index in props ) { | |
name = jQuery.camelCase( index ); | |
easing = specialEasing[ name ]; | |
value = props[ index ]; | |
if ( jQuery.isArray( value ) ) { | |
easing = value[ 1 ]; | |
value = props[ index ] = value[ 0 ]; | |
} | |
if ( index !== name ) { | |
props[ name ] = value; | |
delete props[ index ]; | |
} | |
hooks = jQuery.cssHooks[ name ]; | |
if ( hooks && "expand" in hooks ) { | |
value = hooks.expand( value ); | |
delete props[ name ]; | |
// not quite $.extend, this wont overwrite keys already present. | |
// also - reusing 'index' from above because we have the correct "name" | |
for ( index in value ) { | |
if ( !( index in props ) ) { | |
props[ index ] = value[ index ]; | |
specialEasing[ index ] = easing; | |
} | |
} | |
} else { | |
specialEasing[ name ] = easing; | |
} | |
} | |
} | |
jQuery.Animation = jQuery.extend( Animation, { | |
tweener: function( props, callback ) { | |
if ( jQuery.isFunction( props ) ) { | |
callback = props; | |
props = [ "*" ]; | |
} else { | |
props = props.split(" "); | |
} | |
var prop, | |
index = 0, | |
length = props.length; | |
for ( ; index < length ; index++ ) { | |
prop = props[ index ]; | |
tweeners[ prop ] = tweeners[ prop ] || []; | |
tweeners[ prop ].unshift( callback ); | |
} | |
}, | |
prefilter: function( callback, prepend ) { | |
if ( prepend ) { | |
animationPrefilters.unshift( callback ); | |
} else { | |
animationPrefilters.push( callback ); | |
} | |
} | |
}); | |
function defaultPrefilter( elem, props, opts ) { | |
/* jshint validthis: true */ | |
var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, | |
anim = this, | |
style = elem.style, | |
orig = {}, | |
handled = [], | |
hidden = elem.nodeType && isHidden( elem ); | |
// handle queue: false promises | |
if ( !opts.queue ) { | |
hooks = jQuery._queueHooks( elem, "fx" ); | |
if ( hooks.unqueued == null ) { | |
hooks.unqueued = 0; | |
oldfire = hooks.empty.fire; | |
hooks.empty.fire = function() { | |
if ( !hooks.unqueued ) { | |
oldfire(); | |
} | |
}; | |
} | |
hooks.unqueued++; | |
anim.always(function() { | |
// doing this makes sure that the complete handler will be called | |
// before this completes | |
anim.always(function() { | |
hooks.unqueued--; | |
if ( !jQuery.queue( elem, "fx" ).length ) { | |
hooks.empty.fire(); | |
} | |
}); | |
}); | |
} | |
// height/width overflow pass | |
if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { | |
// Make sure that nothing sneaks out | |
// Record all 3 overflow attributes because IE9-10 do not | |
// change the overflow attribute when overflowX and | |
// overflowY are set to the same value | |
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; | |
// Set display property to inline-block for height/width | |
// animations on inline elements that are having width/height animated | |
if ( jQuery.css( elem, "display" ) === "inline" && | |
jQuery.css( elem, "float" ) === "none" ) { | |
style.display = "inline-block"; | |
} | |
} | |
if ( opts.overflow ) { | |
style.overflow = "hidden"; | |
anim.always(function() { | |
style.overflow = opts.overflow[ 0 ]; | |
style.overflowX = opts.overflow[ 1 ]; | |
style.overflowY = opts.overflow[ 2 ]; | |
}); | |
} | |
// show/hide pass | |
dataShow = data_priv.get( elem, "fxshow" ); | |
for ( index in props ) { | |
value = props[ index ]; | |
if ( rfxtypes.exec( value ) ) { | |
delete props[ index ]; | |
toggle = toggle || value === "toggle"; | |
if ( value === ( hidden ? "hide" : "show" ) ) { | |
// If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden | |
if( value === "show" && dataShow !== undefined && dataShow[ index ] !== undefined ) { | |
hidden = true; | |
} else { | |
continue; | |
} | |
} | |
handled.push( index ); | |
} | |
} | |
length = handled.length; | |
if ( length ) { | |
dataShow = data_priv.get( elem, "fxshow" ) || data_priv.access( elem, "fxshow", {} ); | |
if ( "hidden" in dataShow ) { | |
hidden = dataShow.hidden; | |
} | |
// store state if its toggle - enables .stop().toggle() to "reverse" | |
if ( toggle ) { | |
dataShow.hidden = !hidden; | |
} | |
if ( hidden ) { | |
jQuery( elem ).show(); | |
} else { | |
anim.done(function() { | |
jQuery( elem ).hide(); | |
}); | |
} | |
anim.done(function() { | |
var prop; | |
data_priv.remove( elem, "fxshow" ); | |
for ( prop in orig ) { | |
jQuery.style( elem, prop, orig[ prop ] ); | |
} | |
}); | |
for ( index = 0 ; index < length ; index++ ) { | |
prop = handled[ index ]; | |
tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); | |
orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); | |
if ( !( prop in dataShow ) ) { | |
dataShow[ prop ] = tween.start; | |
if ( hidden ) { | |
tween.end = tween.start; | |
tween.start = prop === "width" || prop === "height" ? 1 : 0; | |
} | |
} | |
} | |
} | |
} | |
function Tween( elem, options, prop, end, easing ) { | |
return new Tween.prototype.init( elem, options, prop, end, easing ); | |
} | |
jQuery.Tween = Tween; | |
Tween.prototype = { | |
constructor: Tween, | |
init: function( elem, options, prop, end, easing, unit ) { | |
this.elem = elem; | |
this.prop = prop; | |
this.easing = easing || "swing"; | |
this.options = options; | |
this.start = this.now = this.cur(); | |
this.end = end; | |
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); | |
}, | |
cur: function() { | |
var hooks = Tween.propHooks[ this.prop ]; | |
return hooks && hooks.get ? | |
hooks.get( this ) : | |
Tween.propHooks._default.get( this ); | |
}, | |
run: function( percent ) { | |
var eased, | |
hooks = Tween.propHooks[ this.prop ]; | |
if ( this.options.duration ) { | |
this.pos = eased = jQuery.easing[ this.easing ]( | |
percent, this.options.duration * percent, 0, 1, this.options.duration | |
); | |
} else { | |
this.pos = eased = percent; | |
} | |
this.now = ( this.end - this.start ) * eased + this.start; | |
if ( this.options.step ) { | |
this.options.step.call( this.elem, this.now, this ); | |
} | |
if ( hooks && hooks.set ) { | |
hooks.set( this ); | |
} else { | |
Tween.propHooks._default.set( this ); | |
} | |
return this; | |
} | |
}; | |
Tween.prototype.init.prototype = Tween.prototype; | |
Tween.propHooks = { | |
_default: { | |
get: function( tween ) { | |
var result; | |
if ( tween.elem[ tween.prop ] != null && | |
(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { | |
return tween.elem[ tween.prop ]; | |
} | |
// passing an empty string as a 3rd parameter to .css will automatically | |
// attempt a parseFloat and fallback to a string if the parse fails | |
// so, simple values such as "10px" are parsed to Float. | |
// complex values such as "rotate(1rad)" are returned as is. | |
result = jQuery.css( tween.elem, tween.prop, "" ); | |
// Empty strings, null, undefined and "auto" are converted to 0. | |
return !result || result === "auto" ? 0 : result; | |
}, | |
set: function( tween ) { | |
// use step hook for back compat - use cssHook if its there - use .style if its | |
// available and use plain properties where available | |
if ( jQuery.fx.step[ tween.prop ] ) { | |
jQuery.fx.step[ tween.prop ]( tween ); | |
} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { | |
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); | |
} else { | |
tween.elem[ tween.prop ] = tween.now; | |
} | |
} | |
} | |
}; | |
// Support: IE9 | |
// Panic based approach to setting things on disconnected nodes | |
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { | |
set: function( tween ) { | |
if ( tween.elem.nodeType && tween.elem.parentNode ) { | |
tween.elem[ tween.prop ] = tween.now; | |
} | |
} | |
}; | |
jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { | |
var cssFn = jQuery.fn[ name ]; | |
jQuery.fn[ name ] = function( speed, easing, callback ) { | |
return speed == null || typeof speed === "boolean" ? | |
cssFn.apply( this, arguments ) : | |
this.animate( genFx( name, true ), speed, easing, callback ); | |
}; | |
}); | |
jQuery.fn.extend({ | |
fadeTo: function( speed, to, easing, callback ) { | |
// show any hidden elements after setting opacity to 0 | |
return this.filter( isHidden ).css( "opacity", 0 ).show() | |
// animate to the value specified | |
.end().animate({ opacity: to }, speed, easing, callback ); | |
}, | |
animate: function( prop, speed, easing, callback ) { | |
var empty = jQuery.isEmptyObject( prop ), | |
optall = jQuery.speed( speed, easing, callback ), | |
doAnimation = function() { | |
// Operate on a copy of prop so per-property easing won't be lost | |
var anim = Animation( this, jQuery.extend( {}, prop ), optall ); | |
doAnimation.finish = function() { | |
anim.stop( true ); | |
}; | |
// Empty animations, or finishing resolves immediately | |
if ( empty || data_priv.get( this, "finish" ) ) { | |
anim.stop( true ); | |
} | |
}; | |
doAnimation.finish = doAnimation; | |
return empty || optall.queue === false ? | |
this.each( doAnimation ) : | |
this.queue( optall.queue, doAnimation ); | |
}, | |
stop: function( type, clearQueue, gotoEnd ) { | |
var stopQueue = function( hooks ) { | |
var stop = hooks.stop; | |
delete hooks.stop; | |
stop( gotoEnd ); | |
}; | |
if ( typeof type !== "string" ) { | |
gotoEnd = clearQueue; | |
clearQueue = type; | |
type = undefined; | |
} | |
if ( clearQueue && type !== false ) { | |
this.queue( type || "fx", [] ); | |
} | |
return this.each(function() { | |
var dequeue = true, | |
index = type != null && type + "queueHooks", | |
timers = jQuery.timers, | |
data = data_priv.get( this ); | |
if ( index ) { | |
if ( data[ index ] && data[ index ].stop ) { | |
stopQueue( data[ index ] ); | |
} | |
} else { | |
for ( index in data ) { | |
if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { | |
stopQueue( data[ index ] ); | |
} | |
} | |
} | |
for ( index = timers.length; index--; ) { | |
if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { | |
timers[ index ].anim.stop( gotoEnd ); | |
dequeue = false; | |
timers.splice( index, 1 ); | |
} | |
} | |
// start the next in the queue if the last step wasn't forced | |
// timers currently will call their complete callbacks, which will dequeue | |
// but only if they were gotoEnd | |
if ( dequeue || !gotoEnd ) { | |
jQuery.dequeue( this, type ); | |
} | |
}); | |
}, | |
finish: function( type ) { | |
if ( type !== false ) { | |
type = type || "fx"; | |
} | |
return this.each(function() { | |
var index, | |
data = data_priv.get( this ), | |
queue = data[ type + "queue" ], | |
hooks = data[ type + "queueHooks" ], | |
timers = jQuery.timers, | |
length = queue ? queue.length : 0; | |
// enable finishing flag on private data | |
data.finish = true; | |
// empty the queue first | |
jQuery.queue( this, type, [] ); | |
if ( hooks && hooks.cur && hooks.cur.finish ) { | |
hooks.cur.finish.call( this ); | |
} | |
// look for any active animations, and finish them | |
for ( index = timers.length; index--; ) { | |
if ( timers[ index ].elem === this && timers[ index ].queue === type ) { | |
timers[ index ].anim.stop( true ); | |
timers.splice( index, 1 ); | |
} | |
} | |
// look for any animations in the old queue and finish them | |
for ( index = 0; index < length; index++ ) { | |
if ( queue[ index ] && queue[ index ].finish ) { | |
queue[ index ].finish.call( this ); | |
} | |
} | |
// turn off finishing flag | |
delete data.finish; | |
}); | |
} | |
}); | |
// Generate parameters to create a standard animation | |
function genFx( type, includeWidth ) { | |
var which, | |
attrs = { height: type }, | |
i = 0; | |
// if we include width, step value is 1 to do all cssExpand values, | |
// if we don't include width, step value is 2 to skip over Left and Right | |
includeWidth = includeWidth? 1 : 0; | |
for( ; i < 4 ; i += 2 - includeWidth ) { | |
which = cssExpand[ i ]; | |
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; | |
} | |
if ( includeWidth ) { | |
attrs.opacity = attrs.width = type; | |
} | |
return attrs; | |
} | |
// Generate shortcuts for custom animations | |
jQuery.each({ | |
slideDown: genFx("show"), | |
slideUp: genFx("hide"), | |
slideToggle: genFx("toggle"), | |
fadeIn: { opacity: "show" }, | |
fadeOut: { opacity: "hide" }, | |
fadeToggle: { opacity: "toggle" } | |
}, function( name, props ) { | |
jQuery.fn[ name ] = function( speed, easing, callback ) { | |
return this.animate( props, speed, easing, callback ); | |
}; | |
}); | |
jQuery.speed = function( speed, easing, fn ) { | |
var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { | |
complete: fn || !fn && easing || | |
jQuery.isFunction( speed ) && speed, | |
duration: speed, | |
easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing | |
}; | |
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : | |
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; | |
// normalize opt.queue - true/undefined/null -> "fx" | |
if ( opt.queue == null || opt.queue === true ) { | |
opt.queue = "fx"; | |
} | |
// Queueing | |
opt.old = opt.complete; | |
opt.complete = function() { | |
if ( jQuery.isFunction( opt.old ) ) { | |
opt.old.call( this ); | |
} | |
if ( opt.queue ) { | |
jQuery.dequeue( this, opt.queue ); | |
} | |
}; | |
return opt; | |
}; | |
jQuery.easing = { | |
linear: function( p ) { | |
return p; | |
}, | |
swing: function( p ) { | |
return 0.5 - Math.cos( p*Math.PI ) / 2; | |
} | |
}; | |
jQuery.timers = []; | |
jQuery.fx = Tween.prototype.init; | |
jQuery.fx.tick = function() { | |
var timer, | |
timers = jQuery.timers, | |
i = 0; | |
fxNow = jQuery.now(); | |
for ( ; i < timers.length; i++ ) { | |
timer = timers[ i ]; | |
// Checks the timer has not already been removed | |
if ( !timer() && timers[ i ] === timer ) { | |
timers.splice( i--, 1 ); | |
} | |
} | |
if ( !timers.length ) { | |
jQuery.fx.stop(); | |
} | |
fxNow = undefined; | |
}; | |
jQuery.fx.timer = function( timer ) { | |
if ( timer() && jQuery.timers.push( timer ) ) { | |
jQuery.fx.start(); | |
} | |
}; | |
jQuery.fx.interval = 13; | |
jQuery.fx.start = function() { | |
if ( !timerId ) { | |
timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); | |
} | |
}; | |
jQuery.fx.stop = function() { | |
clearInterval( timerId ); | |
timerId = null; | |
}; | |
jQuery.fx.speeds = { | |
slow: 600, | |
fast: 200, | |
// Default speed | |
_default: 400 | |
}; | |
// Back Compat <1.8 extension point | |
jQuery.fx.step = {}; | |
if ( jQuery.expr && jQuery.expr.filters ) { | |
jQuery.expr.filters.animated = function( elem ) { | |
return jQuery.grep(jQuery.timers, function( fn ) { | |
return elem === fn.elem; | |
}).length; | |
}; | |
} | |
jQuery.fn.offset = function( options ) { | |
if ( arguments.length ) { | |
return options === undefined ? | |
this : | |
this.each(function( i ) { | |
jQuery.offset.setOffset( this, options, i ); | |
}); | |
} | |
var docElem, win, | |
elem = this[ 0 ], | |
box = { top: 0, left: 0 }, | |
doc = elem && elem.ownerDocument; | |
if ( !doc ) { | |
return; | |
} | |
docElem = doc.documentElement; | |
// Make sure it's not a disconnected DOM node | |
if ( !jQuery.contains( docElem, elem ) ) { | |
return box; | |
} | |
// If we don't have gBCR, just use 0,0 rather than error | |
// BlackBerry 5, iOS 3 (original iPhone) | |
if ( typeof elem.getBoundingClientRect !== core_strundefined ) { | |
box = elem.getBoundingClientRect(); | |
} | |
win = getWindow( doc ); | |
return { | |
top: box.top + win.pageYOffset - docElem.clientTop, | |
left: box.left + win.pageXOffset - docElem.clientLeft | |
}; | |
}; | |
jQuery.offset = { | |
setOffset: function( elem, options, i ) { | |
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, | |
position = jQuery.css( elem, "position" ), | |
curElem = jQuery( elem ), | |
props = {}; | |
// Set position first, in-case top/left are set even on static elem | |
if ( position === "static" ) { | |
elem.style.position = "relative"; | |
} | |
curOffset = curElem.offset(); | |
curCSSTop = jQuery.css( elem, "top" ); | |
curCSSLeft = jQuery.css( elem, "left" ); | |
calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1; | |
// Need to be able to calculate position if either top or left is auto and position is either absolute or fixed | |
if ( calculatePosition ) { | |
curPosition = curElem.position(); | |
curTop = curPosition.top; | |
curLeft = curPosition.left; | |
} else { | |
curTop = parseFloat( curCSSTop ) || 0; | |
curLeft = parseFloat( curCSSLeft ) || 0; | |
} | |
if ( jQuery.isFunction( options ) ) { | |
options = options.call( elem, i, curOffset ); | |
} | |
if ( options.top != null ) { | |
props.top = ( options.top - curOffset.top ) + curTop; | |
} | |
if ( options.left != null ) { | |
props.left = ( options.left - curOffset.left ) + curLeft; | |
} | |
if ( "using" in options ) { | |
options.using.call( elem, props ); | |
} else { | |
curElem.css( props ); | |
} | |
} | |
}; | |
jQuery.fn.extend({ | |
position: function() { | |
if ( !this[ 0 ] ) { | |
return; | |
} | |
var offsetParent, offset, | |
elem = this[ 0 ], | |
parentOffset = { top: 0, left: 0 }; | |
// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent | |
if ( jQuery.css( elem, "position" ) === "fixed" ) { | |
// We assume that getBoundingClientRect is available when computed position is fixed | |
offset = elem.getBoundingClientRect(); | |
} else { | |
// Get *real* offsetParent | |
offsetParent = this.offsetParent(); | |
// Get correct offsets | |
offset = this.offset(); | |
if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { | |
parentOffset = offsetParent.offset(); | |
} | |
// Add offsetParent borders | |
parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); | |
parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); | |
} | |
// Subtract parent offsets and element margins | |
return { | |
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), | |
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) | |
}; | |
}, | |
offsetParent: function() { | |
return this.map(function() { | |
var offsetParent = this.offsetParent || docElem; | |
while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) { | |
offsetParent = offsetParent.offsetParent; | |
} | |
return offsetParent || docElem; | |
}); | |
} | |
}); | |
// Create scrollLeft and scrollTop methods | |
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { | |
var top = "pageYOffset" === prop; | |
jQuery.fn[ method ] = function( val ) { | |
return jQuery.access( this, function( elem, method, val ) { | |
var win = getWindow( elem ); | |
if ( val === undefined ) { | |
return win ? win[ prop ] : elem[ method ]; | |
} | |
if ( win ) { | |
win.scrollTo( | |
!top ? val : window.pageXOffset, | |
top ? val : window.pageYOffset | |
); | |
} else { | |
elem[ method ] = val; | |
} | |
}, method, val, arguments.length, null ); | |
}; | |
}); | |
function getWindow( elem ) { | |
return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView; | |
} | |
// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods | |
jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { | |
jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { | |
// margin is only for outerHeight, outerWidth | |
jQuery.fn[ funcName ] = function( margin, value ) { | |
var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), | |
extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); | |
return jQuery.access( this, function( elem, type, value ) { | |
var doc; | |
if ( jQuery.isWindow( elem ) ) { | |
// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there | |
// isn't a whole lot we can do. See pull request at this URL for discussion: | |
// https://github.com/jquery/jquery/pull/764 | |
return elem.document.documentElement[ "client" + name ]; | |
} | |
// Get document width or height | |
if ( elem.nodeType === 9 ) { | |
doc = elem.documentElement; | |
// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], | |
// whichever is greatest | |
return Math.max( | |
elem.body[ "scroll" + name ], doc[ "scroll" + name ], | |
elem.body[ "offset" + name ], doc[ "offset" + name ], | |
doc[ "client" + name ] | |
); | |
} | |
return value === undefined ? | |
// Get width or height on the element, requesting but not forcing parseFloat | |
jQuery.css( elem, type, extra ) : | |
// Set width or height on the element | |
jQuery.style( elem, type, value, extra ); | |
}, type, chainable ? margin : undefined, chainable, null ); | |
}; | |
}); | |
}); | |
// Limit scope pollution from any deprecated API | |
// (function() { | |
// The number of elements contained in the matched element set | |
jQuery.fn.size = function() { | |
return this.length; | |
}; | |
jQuery.fn.andSelf = jQuery.fn.addBack; | |
// })(); | |
if ( typeof module === "object" && typeof module.exports === "object" ) { | |
// Expose jQuery as module.exports in loaders that implement the Node | |
// module pattern (including browserify). Do not create the global, since | |
// the user will be storing it themselves locally, and globals are frowned | |
// upon in the Node module world. | |
module.exports = jQuery; | |
} else { | |
// Register as a named AMD module, since jQuery can be concatenated with other | |
// files that may use define, but not via a proper concatenation script that | |
// understands anonymous AMD modules. A named AMD is safest and most robust | |
// way to register. Lowercase jquery is used because AMD module names are | |
// derived from file names, and jQuery is normally delivered in a lowercase | |
// file name. Do this after creating the global so that if an AMD module wants | |
// to call noConflict to hide this version of jQuery, it will work. | |
if ( typeof define === "function" && define.amd ) { | |
define( "jquery", [], function () { return jQuery; } ); | |
} | |
} | |
// If there is a window object, that at least has a document property, | |
// define jQuery and $ identifiers | |
if ( typeof window === "object" && typeof window.document === "object" ) { | |
window.jQuery = window.$ = jQuery; | |
} | |
})( window ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
LABEL_PAD = 0.5 | |
ANIMATION_DURATION = 700 | |
global class Matrix extends View | |
constructor: (conf) -> | |
super(conf) | |
@bigraph = conf.bigraph | |
@listen_to @bigraph, 'ready', @render | |
@listen_to @bigraph, 'select', @redraw | |
@filters = | |
hide_unselected: false | |
hide_empty: false | |
svg = @d3el.append 'svg' | |
# Group for zoomable content | |
zoomable_layer = svg.append('g') | |
# Zoom behavior definition | |
zoom = d3.behavior.zoom() | |
.scaleExtent [0,Infinity] | |
.on 'zoom', () -> | |
zoomable_layer | |
.attr | |
transform: "translate(#{zoom.translate()})scale(#{zoom.scale()})" | |
svg.call(zoom) | |
@matrix = zoomable_layer.append 'g' | |
# filter controls | |
filter_controls = @d3el.append 'div' | |
.attr 'class', 'filter_controls' | |
label = filter_controls.append 'label' | |
.html "<input type='checkbox'>Hide unselected <br/>" | |
@hide_unselected_input = label.select 'input' | |
.on 'click', () => | |
@filters.hide_unselected = not @filters.hide_unselected | |
@redraw() | |
label = filter_controls.append 'label' | |
.html "<input type='checkbox'>Hide empty" | |
@hide_empty_input = label.select 'input' | |
.on 'click', () => | |
@filters.hide_empty = not @filters.hide_empty | |
@redraw() | |
render: () => | |
@recompute_size() | |
matrix_space_width = 0.8 * @width | |
matrix_space_height = 0.8 * @height | |
@cell = Math.min(matrix_space_width / @bigraph.data_b.length, matrix_space_height / @bigraph.data_a.length) | |
@matrix_width = @cell * @bigraph.data_b.length | |
@matrix_height = @cell * @bigraph.data_a.length | |
@matrix | |
.attr | |
transform: "translate(#{@width/2-@matrix_width/2+50},#{@height/2-@matrix_height/2})" | |
@redraw() | |
redraw: () => | |
filtered_data_cells = @bigraph.data_cells | |
filtered_data_a = @bigraph.data_a | |
filtered_data_b = @bigraph.data_b | |
if @filters.hide_unselected | |
filtered_data_cells = filtered_data_cells.filter (d) -> d.selected | |
filtered_data_a = filtered_data_a.filter (d) -> d.selected | |
filtered_data_b = filtered_data_b.filter (d) -> d.selected | |
# update pointers from headers to cells | |
@bigraph.data_a.forEach (d) -> d.cells = [] | |
@bigraph.data_b.forEach (d) -> d.cells = [] | |
filtered_data_cells.forEach (d) -> | |
d.a.cells.push d | |
d.b.cells.push d | |
if @filters.hide_empty | |
filtered_data_a = filtered_data_a.filter (d) -> d.cells.length > 0 | |
filtered_data_b = filtered_data_b.filter (d) -> d.cells.length > 0 | |
# LAYOUT | |
matrix_width = @cell * filtered_data_b.length | |
matrix_height = @cell * filtered_data_a.length | |
x = d3.scale.ordinal() | |
.domain(filtered_data_b.map (d) -> d.id) | |
.rangeBands([0, matrix_width]) | |
y = d3.scale.ordinal() | |
.domain(filtered_data_a.map (d) -> d.id) | |
.rangeBands([0, matrix_height]) | |
# radius = d3.scale.sqrt() | |
# .domain([0, d3.max data_cells, (d) -> d.weight]) | |
# .range([0, cell/2]) | |
# VIS | |
cells = @matrix.selectAll(".cell") | |
.data filtered_data_cells, (d) -> "#{d.a.id}__#{d.b.id}" | |
enter_cells = cells.enter().append("circle") | |
.attr | |
class: "cell" | |
opacity: 0 | |
enter_cells.append 'title' | |
.text (d) -> "#{d.b.istituto}\n#{d.a.tema.trim()}" | |
cells | |
.classed 'selected', (d) -> d.selected | |
# ANIMATIONS | |
@disable_controls() | |
cells.exit().transition() | |
.duration(ANIMATION_DURATION) | |
.attr | |
opacity: 0 | |
.remove() | |
cells.transition() | |
.delay(ANIMATION_DURATION) | |
.duration(ANIMATION_DURATION) | |
.attr | |
cx: (d) => x(d.b.id)+@cell/2 | |
cy: (d) => y(d.a.id)+@cell/2 | |
r: @cell/2 | |
# r: (d) -> radius(d.weight) | |
cells.transition() | |
.delay(2*ANIMATION_DURATION) | |
.duration(ANIMATION_DURATION) | |
.attr | |
opacity: 1 | |
.each 'end', () => | |
@enable_controls() | |
# labels | |
x_labels = @matrix.selectAll(".x_label") | |
.data filtered_data_b, (d) -> d.id | |
enter_x_labels = x_labels.enter().append("text") | |
.text (d) -> d.label | |
.attr | |
class: "x_label" | |
x: 0 | |
dy: '0.35em' | |
opacity: 0 | |
.on 'click', (d) => | |
if not @filters.hide_unselected | |
@bigraph.toggle(d, 'bs') | |
enter_x_labels.append 'title' | |
.text (d) -> "#{d.istituto.trim()}" | |
x_labels | |
.classed 'selected', (d) -> d.selected | |
# ANIMATIONS | |
x_labels.exit().transition() | |
.duration(ANIMATION_DURATION) | |
.attr | |
opacity: 0 | |
.remove() | |
x_labels.transition() | |
.delay(ANIMATION_DURATION) | |
.duration(ANIMATION_DURATION) | |
.attr | |
transform: (d) => "translate(#{x(d.id)+@cell/2},#{-LABEL_PAD*@cell}) rotate(-90) scale(#{@cell})" | |
enter_x_labels.transition() | |
.delay(2*ANIMATION_DURATION) | |
.duration(ANIMATION_DURATION) | |
.attr | |
opacity: 1 | |
y_labels = @matrix.selectAll(".y_label") | |
.data filtered_data_a, (d) -> d.id | |
enter_y_labels = y_labels.enter().append("text") | |
.text (d) -> | |
if d.label.length > 30 | |
d.label.trim().substring(0,30)+'...' | |
else | |
d.label | |
.attr | |
class: "y_label" | |
dy: '0.35em' | |
opacity: 0 | |
.on 'click', (d) => | |
if not @filters.hide_unselected | |
@bigraph.toggle(d, 'as') | |
enter_y_labels.append 'title' | |
.text (d) -> "#{d.tema}" | |
y_labels | |
.classed 'selected', (d) -> d.selected | |
# ANIMATIONS | |
y_labels.exit().transition() | |
.duration(ANIMATION_DURATION) | |
.attr | |
opacity: 0 | |
.remove() | |
y_labels.transition() | |
.delay(ANIMATION_DURATION) | |
.duration(ANIMATION_DURATION) | |
.attr | |
transform: (d) => "translate(#{-LABEL_PAD*@cell},#{y(d.id)+@cell/2}) scale(#{@cell})" | |
enter_y_labels.transition() | |
.delay(2*ANIMATION_DURATION) | |
.duration(ANIMATION_DURATION) | |
.attr | |
opacity: 1 | |
enable_controls: () -> | |
@hide_unselected_input | |
.attr | |
disabled: null | |
@hide_empty_input | |
.attr | |
disabled: null | |
disable_controls: () -> | |
@hide_unselected_input | |
.attr | |
disabled: true | |
@hide_empty_input | |
.attr | |
disabled: true | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.Matrix .x_label, .Matrix .y_label { | |
font-family: sans-serif; | |
font-size: 1px; | |
cursor: pointer; | |
} | |
.Matrix .x_label { | |
text-anchor: start; | |
} | |
.Matrix .y_label { | |
text-anchor: end; | |
} | |
.Matrix .cell, .Matrix .x_label, .Matrix .y_label { | |
fill: #BBB; | |
} | |
.Matrix .selected { | |
fill: black; | |
} | |
.Matrix { | |
position: relative; | |
} | |
.Matrix .filter_controls { | |
position: absolute; | |
top: 10px; | |
left: 10px; | |
font-family: sans-serif; | |
font-size: 12px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.10.0 | |
(function() { | |
var ANIMATION_DURATION, LABEL_PAD, Matrix, | |
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, | |
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, | |
hasProp = {}.hasOwnProperty; | |
LABEL_PAD = 0.5; | |
ANIMATION_DURATION = 700; | |
global(Matrix = (function(superClass) { | |
extend(Matrix, superClass); | |
function Matrix(conf) { | |
this.redraw = bind(this.redraw, this); | |
this.render = bind(this.render, this); | |
var filter_controls, label, svg, zoom, zoomable_layer; | |
Matrix.__super__.constructor.call(this, conf); | |
this.bigraph = conf.bigraph; | |
this.listen_to(this.bigraph, 'ready', this.render); | |
this.listen_to(this.bigraph, 'select', this.redraw); | |
this.filters = { | |
hide_unselected: false, | |
hide_empty: false | |
}; | |
svg = this.d3el.append('svg'); | |
zoomable_layer = svg.append('g'); | |
zoom = d3.behavior.zoom().scaleExtent([0, Infinity]).on('zoom', function() { | |
return zoomable_layer.attr({ | |
transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")" | |
}); | |
}); | |
svg.call(zoom); | |
this.matrix = zoomable_layer.append('g'); | |
filter_controls = this.d3el.append('div').attr('class', 'filter_controls'); | |
label = filter_controls.append('label').html("<input type='checkbox'>Hide unselected <br/>"); | |
this.hide_unselected_input = label.select('input').on('click', (function(_this) { | |
return function() { | |
_this.filters.hide_unselected = !_this.filters.hide_unselected; | |
return _this.redraw(); | |
}; | |
})(this)); | |
label = filter_controls.append('label').html("<input type='checkbox'>Hide empty"); | |
this.hide_empty_input = label.select('input').on('click', (function(_this) { | |
return function() { | |
_this.filters.hide_empty = !_this.filters.hide_empty; | |
return _this.redraw(); | |
}; | |
})(this)); | |
} | |
Matrix.prototype.render = function() { | |
var matrix_space_height, matrix_space_width; | |
this.recompute_size(); | |
matrix_space_width = 0.8 * this.width; | |
matrix_space_height = 0.8 * this.height; | |
this.cell = Math.min(matrix_space_width / this.bigraph.data_b.length, matrix_space_height / this.bigraph.data_a.length); | |
this.matrix_width = this.cell * this.bigraph.data_b.length; | |
this.matrix_height = this.cell * this.bigraph.data_a.length; | |
this.matrix.attr({ | |
transform: "translate(" + (this.width / 2 - this.matrix_width / 2 + 50) + "," + (this.height / 2 - this.matrix_height / 2) + ")" | |
}); | |
return this.redraw(); | |
}; | |
Matrix.prototype.redraw = function() { | |
var cells, enter_cells, enter_x_labels, enter_y_labels, filtered_data_a, filtered_data_b, filtered_data_cells, matrix_height, matrix_width, x, x_labels, y, y_labels; | |
filtered_data_cells = this.bigraph.data_cells; | |
filtered_data_a = this.bigraph.data_a; | |
filtered_data_b = this.bigraph.data_b; | |
if (this.filters.hide_unselected) { | |
filtered_data_cells = filtered_data_cells.filter(function(d) { | |
return d.selected; | |
}); | |
filtered_data_a = filtered_data_a.filter(function(d) { | |
return d.selected; | |
}); | |
filtered_data_b = filtered_data_b.filter(function(d) { | |
return d.selected; | |
}); | |
} | |
this.bigraph.data_a.forEach(function(d) { | |
return d.cells = []; | |
}); | |
this.bigraph.data_b.forEach(function(d) { | |
return d.cells = []; | |
}); | |
filtered_data_cells.forEach(function(d) { | |
d.a.cells.push(d); | |
return d.b.cells.push(d); | |
}); | |
if (this.filters.hide_empty) { | |
filtered_data_a = filtered_data_a.filter(function(d) { | |
return d.cells.length > 0; | |
}); | |
filtered_data_b = filtered_data_b.filter(function(d) { | |
return d.cells.length > 0; | |
}); | |
} | |
matrix_width = this.cell * filtered_data_b.length; | |
matrix_height = this.cell * filtered_data_a.length; | |
x = d3.scale.ordinal().domain(filtered_data_b.map(function(d) { | |
return d.id; | |
})).rangeBands([0, matrix_width]); | |
y = d3.scale.ordinal().domain(filtered_data_a.map(function(d) { | |
return d.id; | |
})).rangeBands([0, matrix_height]); | |
cells = this.matrix.selectAll(".cell").data(filtered_data_cells, function(d) { | |
return d.a.id + "__" + d.b.id; | |
}); | |
enter_cells = cells.enter().append("circle").attr({ | |
"class": "cell", | |
opacity: 0 | |
}); | |
enter_cells.append('title').text(function(d) { | |
return d.b.istituto + "\n" + (d.a.tema.trim()); | |
}); | |
cells.classed('selected', function(d) { | |
return d.selected; | |
}); | |
this.disable_controls(); | |
cells.exit().transition().duration(ANIMATION_DURATION).attr({ | |
opacity: 0 | |
}).remove(); | |
cells.transition().delay(ANIMATION_DURATION).duration(ANIMATION_DURATION).attr({ | |
cx: (function(_this) { | |
return function(d) { | |
return x(d.b.id) + _this.cell / 2; | |
}; | |
})(this), | |
cy: (function(_this) { | |
return function(d) { | |
return y(d.a.id) + _this.cell / 2; | |
}; | |
})(this), | |
r: this.cell / 2 | |
}); | |
cells.transition().delay(2 * ANIMATION_DURATION).duration(ANIMATION_DURATION).attr({ | |
opacity: 1 | |
}).each('end', (function(_this) { | |
return function() { | |
return _this.enable_controls(); | |
}; | |
})(this)); | |
x_labels = this.matrix.selectAll(".x_label").data(filtered_data_b, function(d) { | |
return d.id; | |
}); | |
enter_x_labels = x_labels.enter().append("text").text(function(d) { | |
return d.label; | |
}).attr({ | |
"class": "x_label", | |
x: 0, | |
dy: '0.35em', | |
opacity: 0 | |
}).on('click', (function(_this) { | |
return function(d) { | |
if (!_this.filters.hide_unselected) { | |
return _this.bigraph.toggle(d, 'bs'); | |
} | |
}; | |
})(this)); | |
enter_x_labels.append('title').text(function(d) { | |
return "" + (d.istituto.trim()); | |
}); | |
x_labels.classed('selected', function(d) { | |
return d.selected; | |
}); | |
x_labels.exit().transition().duration(ANIMATION_DURATION).attr({ | |
opacity: 0 | |
}).remove(); | |
x_labels.transition().delay(ANIMATION_DURATION).duration(ANIMATION_DURATION).attr({ | |
transform: (function(_this) { | |
return function(d) { | |
return "translate(" + (x(d.id) + _this.cell / 2) + "," + (-LABEL_PAD * _this.cell) + ") rotate(-90) scale(" + _this.cell + ")"; | |
}; | |
})(this) | |
}); | |
enter_x_labels.transition().delay(2 * ANIMATION_DURATION).duration(ANIMATION_DURATION).attr({ | |
opacity: 1 | |
}); | |
y_labels = this.matrix.selectAll(".y_label").data(filtered_data_a, function(d) { | |
return d.id; | |
}); | |
enter_y_labels = y_labels.enter().append("text").text(function(d) { | |
if (d.label.length > 30) { | |
return d.label.trim().substring(0, 30) + '...'; | |
} else { | |
return d.label; | |
} | |
}).attr({ | |
"class": "y_label", | |
dy: '0.35em', | |
opacity: 0 | |
}).on('click', (function(_this) { | |
return function(d) { | |
if (!_this.filters.hide_unselected) { | |
return _this.bigraph.toggle(d, 'as'); | |
} | |
}; | |
})(this)); | |
enter_y_labels.append('title').text(function(d) { | |
return "" + d.tema; | |
}); | |
y_labels.classed('selected', function(d) { | |
return d.selected; | |
}); | |
y_labels.exit().transition().duration(ANIMATION_DURATION).attr({ | |
opacity: 0 | |
}).remove(); | |
y_labels.transition().delay(ANIMATION_DURATION).duration(ANIMATION_DURATION).attr({ | |
transform: (function(_this) { | |
return function(d) { | |
return "translate(" + (-LABEL_PAD * _this.cell) + "," + (y(d.id) + _this.cell / 2) + ") scale(" + _this.cell + ")"; | |
}; | |
})(this) | |
}); | |
return enter_y_labels.transition().delay(2 * ANIMATION_DURATION).duration(ANIMATION_DURATION).attr({ | |
opacity: 1 | |
}); | |
}; | |
Matrix.prototype.enable_controls = function() { | |
this.hide_unselected_input.attr({ | |
disabled: null | |
}); | |
return this.hide_empty_input.attr({ | |
disabled: null | |
}); | |
}; | |
Matrix.prototype.disable_controls = function() { | |
this.hide_unselected_input.attr({ | |
disabled: true | |
}); | |
return this.hide_empty_input.attr({ | |
disabled: true | |
}); | |
}; | |
return Matrix; | |
})(View)); | |
}).call(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global class SelectionControls extends View | |
constructor: (conf) -> | |
super(conf) | |
@ms_ap = @d3el.append 'select' | |
.attr | |
multiple: 'multiple' | |
@ms_institutes = @d3el.append 'select' | |
.attr | |
multiple: 'multiple' | |
@bigraph = conf.bigraph | |
@listen_to @bigraph, 'ready', @draw | |
@listen_to @bigraph, 'select', @select | |
draw: () => | |
# AP | |
ap_groups = @ms_ap.selectAll 'optgroup' | |
.data @bigraph.areas | |
ap_groups.enter().append 'optgroup' | |
.attr | |
label: (d) -> d.values[0].ap | |
thematics = ap_groups.selectAll 'option' | |
.data (d) -> d.values | |
thematics.enter().append 'option' | |
.text (d) -> d.label | |
.attr | |
value: (d) -> d.id | |
on_ap_selection_changed = () => | |
so_values = [] | |
for so in @ms_ap.node().selectedOptions | |
so_values.push so.value | |
@bigraph.set_selected_as(so_values) | |
$(@ms_ap.node()).multiselect | |
buttonWidth: '300px' | |
maxHeight: 350 | |
enableClickableOptGroups: true | |
enableCollapsibleOptGroups: true | |
enableFiltering: true | |
enableCaseInsensitiveFiltering: true | |
filterPlaceholder: 'Cerca' | |
includeSelectAllOption: true | |
selectAllJustVisible: false | |
selectAllText: 'Seleziona tutto' | |
nSelectedText: ' temi selezionati' | |
allSelectedText: 'Tutti i temi selezionati' | |
nonSelectedText: 'Selezione temi' | |
onChange: on_ap_selection_changed | |
onSelectAll: on_ap_selection_changed | |
onDeselectAll: on_ap_selection_changed | |
# Institutes | |
institutes_groups = @ms_institutes.selectAll 'optgroup' | |
.data @bigraph.departments | |
institutes_groups.enter().append 'optgroup' | |
.attr | |
label: (d) -> d.values[0].dip_sigla | |
institutes = institutes_groups.selectAll 'option' | |
.data (d) -> d.values | |
institutes.enter().append 'option' | |
.text (d) -> d.label | |
.attr | |
value: (d) -> d.id | |
on_institutes_selection_changed = () => | |
so_values = [] | |
for so in @ms_institutes.node().selectedOptions | |
so_values.push so.value | |
@bigraph.set_selected_bs(so_values) | |
$(@ms_institutes.node()).multiselect | |
buttonWidth: '300px' | |
maxHeight: 350 | |
enableClickableOptGroups: true | |
enableCollapsibleOptGroups: true | |
enableFiltering: true | |
enableCaseInsensitiveFiltering: true | |
filterPlaceholder: 'Cerca' | |
includeSelectAllOption: true | |
selectAllJustVisible: false | |
selectAllText: 'Seleziona tutto' | |
nSelectedText: ' istituti selezionati' | |
allSelectedText: 'Tutti gli istituti selezionati' | |
nonSelectedText: 'Selezione istituti' | |
onChange: on_institutes_selection_changed | |
onSelectAll: on_institutes_selection_changed | |
onDeselectAll: on_institutes_selection_changed | |
select: () => | |
console.log 'select' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.SelectionControls { | |
padding: 4px; | |
} | |
.SelectionControls .btn-group { | |
display: block; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by CoffeeScript 1.10.0 | |
(function() { | |
var SelectionControls, | |
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, | |
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, | |
hasProp = {}.hasOwnProperty; | |
global(SelectionControls = (function(superClass) { | |
extend(SelectionControls, superClass); | |
function SelectionControls(conf) { | |
this.select = bind(this.select, this); | |
this.draw = bind(this.draw, this); | |
SelectionControls.__super__.constructor.call(this, conf); | |
this.ms_ap = this.d3el.append('select').attr({ | |
multiple: 'multiple' | |
}); | |
this.ms_institutes = this.d3el.append('select').attr({ | |
multiple: 'multiple' | |
}); | |
this.bigraph = conf.bigraph; | |
this.listen_to(this.bigraph, 'ready', this.draw); | |
this.listen_to(this.bigraph, 'select', this.select); | |
} | |
SelectionControls.prototype.draw = function() { | |
var ap_groups, institutes, institutes_groups, on_ap_selection_changed, on_institutes_selection_changed, thematics; | |
ap_groups = this.ms_ap.selectAll('optgroup').data(this.bigraph.areas); | |
ap_groups.enter().append('optgroup').attr({ | |
label: function(d) { | |
return d.values[0].ap; | |
} | |
}); | |
thematics = ap_groups.selectAll('option').data(function(d) { | |
return d.values; | |
}); | |
thematics.enter().append('option').text(function(d) { | |
return d.label; | |
}).attr({ | |
value: function(d) { | |
return d.id; | |
} | |
}); | |
on_ap_selection_changed = (function(_this) { | |
return function() { | |
var i, len, ref, so, so_values; | |
so_values = []; | |
ref = _this.ms_ap.node().selectedOptions; | |
for (i = 0, len = ref.length; i < len; i++) { | |
so = ref[i]; | |
so_values.push(so.value); | |
} | |
return _this.bigraph.set_selected_as(so_values); | |
}; | |
})(this); | |
$(this.ms_ap.node()).multiselect({ | |
buttonWidth: '300px', | |
maxHeight: 350, | |
enableClickableOptGroups: true, | |
enableCollapsibleOptGroups: true, | |
enableFiltering: true, | |
enableCaseInsensitiveFiltering: true, | |
filterPlaceholder: 'Cerca', | |
includeSelectAllOption: true, | |
selectAllJustVisible: false, | |
selectAllText: 'Seleziona tutto', | |
nSelectedText: ' temi selezionati', | |
allSelectedText: 'Tutti i temi selezionati', | |
nonSelectedText: 'Selezione temi', | |
onChange: on_ap_selection_changed, | |
onSelectAll: on_ap_selection_changed, | |
onDeselectAll: on_ap_selection_changed | |
}); | |
institutes_groups = this.ms_institutes.selectAll('optgroup').data(this.bigraph.departments); | |
institutes_groups.enter().append('optgroup').attr({ | |
label: function(d) { | |
return d.values[0].dip_sigla; | |
} | |
}); | |
institutes = institutes_groups.selectAll('option').data(function(d) { | |
return d.values; | |
}); | |
institutes.enter().append('option').text(function(d) { | |
return d.label; | |
}).attr({ | |
value: function(d) { | |
return d.id; | |
} | |
}); | |
on_institutes_selection_changed = (function(_this) { | |
return function() { | |
var i, len, ref, so, so_values; | |
so_values = []; | |
ref = _this.ms_institutes.node().selectedOptions; | |
for (i = 0, len = ref.length; i < len; i++) { | |
so = ref[i]; | |
so_values.push(so.value); | |
} | |
return _this.bigraph.set_selected_bs(so_values); | |
}; | |
})(this); | |
return $(this.ms_institutes.node()).multiselect({ | |
buttonWidth: '300px', | |
maxHeight: 350, | |
enableClickableOptGroups: true, | |
enableCollapsibleOptGroups: true, | |
enableFiltering: true, | |
enableCaseInsensitiveFiltering: true, | |
filterPlaceholder: 'Cerca', | |
includeSelectAllOption: true, | |
selectAllJustVisible: false, | |
selectAllText: 'Seleziona tutto', | |
nSelectedText: ' istituti selezionati', | |
allSelectedText: 'Tutti gli istituti selezionati', | |
nonSelectedText: 'Selezione istituti', | |
onChange: on_institutes_selection_changed, | |
onSelectAll: on_institutes_selection_changed, | |
onDeselectAll: on_institutes_selection_changed | |
}); | |
}; | |
SelectionControls.prototype.select = function() { | |
return console.log('select'); | |
}; | |
return SelectionControls; | |
})(View)); | |
}).call(this); |
We can make this file beautiful and searchable if this error is corrected: Any value after quoted field isn't allowed in line 82.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"id","tema","area_progettuale_id","ap","position","description" | |
"86","Big data and Open Data Innovation and take-up","1","Dati, Contenuti e Media","1","Semantic Technologies and Linked Data: Semantic technologies include all methods, tools, languages, and resources that use the intended meaning of data or services as the reference system of computing. Currently, this topic typically spans across Semantic Web (including Web 3.0 and Linked Data), Natural Language Processing areas such as Semantic Parsing and Machine Reading, Ontology-Based Data Management, Semantic Interoperability, Similarity Reasoning and Conceptual Modeling. Open Data, Reusability, mutual independence of algorithms, modeling, and resources, and attention to formal aspects, are characteristic (but not necessarily co-present) features of semantic technologies. Big Data integration, analysis and visualization: Analysis and visualization of large scientific datasets, with the ITER experiment as case study. The nuclear fusion ITER experiment is one of the largest scientific experiments in the world and it is expected to be operated worldwide. The remote management of the very large amount of involved data represents a key issue in the successful exploitation of the experiment operation.E-government services: Technologies supporting interoperability and quality of service of e-government services." | |
"87","Big data – research","1","Dati, Contenuti e Media","2","Knowledge mining: -Data and social mining: Data mining aims at discovering useful information in a large data repository. Social aims at representing, analyzing, and extracting patterns generated by individuals, entities, and interactions between them to understand human behaviour. -Text mining and knowledge extraction: construction, either logical or statistical, of models for the transformation of text in one or more languages into structured data. -Mobility data mining: Methods for the privacy-aware analysis of the mobility of people, based on data coming from GPS, GSM or social networks.-Distributed algorithms for Big Data Analysis based on Meta\\Ensemble-Learning methods.-Data mining from very high spectral resolution sensors onboard geostationary satellitesData Analytics:-Information sharing and analytics: Techniques for extracting and sharing intelligible knowledge from data, typically in the form of rules or other simple structured models, even through proper markup languages (i.e. PMML) that ensure portability. -Event Log Analytics and Process Intelligence-Cloud-based data analytics-Analysis of Cloud usage dataWeb of Big Data:-Technologies for interactive visualization of big dataset on the web.-Technologies for modelling, building, integrating, linking and querying data on the webMultimedia and multidimensional data:-Image and Video Analysis-Embedded Image and Video Analytics-3D/nD data modelling and analysis-Modelling Semantic 3D content-Data Warehousing-OLAP" | |
"88","Cracking the language barrier","1","Dati, Contenuti e Media","3","Poly-lingual text classification: leveraging the availability of training data in different languages (in the form of strongly parallel corpora, or weakly parallel corpora, or comparable compora) in order to enhance the accuracy of text classification under each such language. Includes statistical natural language processing." | |
"89","Technologies for creative industries, social media and convergence","1","Dati, Contenuti e Media","4","Interactive Global Illumination: La riproduzione dell'interazione tra luce e materia, con fenomeni visivi tipo sfumature di colore, riflessioni, raggi crepuscolari e caustiche (ossia la Global Illumination), è un tema di ricerca studiato intensamente, nonché un problema ancora irrisolto.Social Media Content Analysis: Techniques for the semantic classification of web resources (Semantic Tagging), for relating contents about similar topics by relying on semantic similarity methods (Semantic Indexing), for serving personalized contents on the basis of user profiles (Semantic Routing), for defining crawling strategies driven by domain knowledge and semantic reasoning (Semantic Crawling).Social Media Analysis: Techniques for modeling, acquiring, distributing and analysing social media information for the implementation of services of open source intelligence, decision making, recommendation, user profiling, influence propagation, and more.Digital Libraries:: Semantic modelling and advanced services on collections of multimedia complex objects. Long term preservation and access of multimedia object collections and documentary material.Digital Humanities: Models and techniques for formal narratives and data-journalism. Techniques for the fruition and promotion of cultural heritage." | |
"90","Technologies for better human learning and teaching","1","Dati, Contenuti e Media","5","e-inclusion: Create and test models of inclusive situations realized with the support of digital technologies. Set the relationship between the educational system and students at risk of marginalization (the disabled, immigrant students, those with learning difficulties or unable to normal schooling) by creating situations and learning communities that can be structured on the basis of the individual characteristics and needs.New skills and ways of learning: Study of learning environments that encourage both the acquisition of emerging skills and of abilities that are not new but for which there is growing demand. This line is closely connected to the study of new educational opportunities offered by technology (eg, inquiry based learning, games-based learning) and to the assessment of their effectiveness. Scientific and technological quality of education: Development of models and tools that promote the quality of scientific knowledge and that also have an effect on the interest and motivation of students (eg. environments for exploration and discovery; for the construction and manipulation of representations; for the development of strategic thinking and reasoning processes). The education in institutional learning, informal and non-formal:The pervasive presence of technology has produced a profound transformation of interpersonal interactions and amplification of the processes that take place outside of specific institutional contexts. It is therefore necessary to study the informal and non-formal learning, its relations with the formal and their possible synergies. " | |
"91","Advanced digital gaming/gamification technologies","1","Dati, Contenuti e Media","6","Augmented Reality: the activity involves the use of the HR / VR as technological basis for the development of digital environments to support problem solving, training and dissemination of knowledge.Semantic modeling of virtual environments and game interaction in the environment: new paradigms of interaction between objects and virtual environments based on semantics to enable natural and various interactions in the game environment and to maximize the educational effectiveness.Using Mobile Social Networks for gamification in Well-being applications: solutions that harness the social profiling of users and their dynamics over time as one of the elements to be included in the serious games to support the improvement of lifestyles through gamification concepts, with particular attention to subjects with difficulty and at risk of social exclusion." | |
"92","Multimodal and Natural computer interaction","1","Dati, Contenuti e Media","7","Web Accessibility and Usability: Design, development, and evaluation of user interfaces that combine various modes (graphics, voice, gestures, ...) in order to adapt to the context of use, and make the interaction more natural and usable. Automatic support for analyzing how interactive applications meet accessibility guidelines.Analytics for improving the user's experience: analysis and modeling of user behavior, aimed at the improvement and extension of the user experience in the access to personalized content. Specific topics of interest are: log analysis of user interactions to identify usability issues, rating-based recommendations, probabilistic modeling, ranking, social media rating systems.Health and applications for personalized prevention and rehabilitation:Implementation of interfaces, tools, and persuasive systems for the empowerment of people in managing their own health." | |
"117"," Infrastrutture dati: tecnologie e servizi","2","e-Infrastructure","1","Il tema si focalizza su problematiche legate allo sviluppo di tecnologiche e servizi di supporto alla operazione efficiente di infrastrutture dati che offrono con modalità “as-a-service” funzionalità di base per supportare il ciclo di vita dei dati (acquisizione, deposito, cura, memorizzazione, preservazione, recupero, accesso, analisi/elaborazione/mining, pubblicazione e riuso). Queste funzionalità devono essere fornite in modo tale da garantire una alta qualità di servizio ed una economia di scala. L’uso di questi servizi deve consentire agli utilizzatori, siano essi ricercatori che operatori di altri settori, di ridurre i costi e i tempi necessari per sviluppare specifiche applicazioni e fornire loro le capacità computazionali di cui possono aver bisogno per eseguire elaborazioni complesse su big data. Per questa ultima caratteristica questa area è fortemente connessa con lo sviluppo dagli ambienti di calcolo HPC e Cloud. Il tema è anche correlato con lo sviluppo di infrastrutture di ricerca ESFRI." | |
"118","Infrastrutture di rete: tecnologie e servizi ","2","e-Infrastructure","2","Il tema si inquadra nell’ambito dei servizi abilitanti e applicativi per infrastrutture di rete e ha, tra i suoi obiettivi principali, il supporto dell’architettura di Internet in tutte le sue forme e componenti. La progettazione e lo sviluppo di tecnologie innovative e avanzate per la gestione di servizi Internet, conformi ai requisiti dettati dagli standard internazionali nel settore dei protocolli di rete e di comunicazione, ricopre infatti, un ruolo centrale nell’ambito dello sviluppo della rete. Una efficace, moderna e dinamica organizzazione dei servizi Internet di un soggetto pubblico e/o privato, così come la formazione tecnologica del proprio personale, costituisce, infatti, una delle condizioni necessarie per una crescita equilibrata della rete in un Paese. Il tema si propone, pertanto, di progettare, sviluppare e rendere fruibili strumenti e tecnologie innovative che possano essere di ausilio al CNR, alla Pubblica Amministrazione e, in generale, alla Internet Local Community e alla Società dell’Informazione. La conduzione di progetti di “ricerca applicata” nei settori di competenza e il trasferimento tecnologico e la formazione nei confronti delle imprese, della Pubblica Amministrazione e degli Internet Service Provider costituiscono degli elementi chiave indispensabili per il raggiungimento degli obiettivi prefissati." | |
"67","Robotica","3","Robotica e Automatica","1","Questo tema si incentra sullo studio, sviluppo e diffusione di tecnologie e metodologie robotiche innovative per applicazioni in diversi contesti, quali il manifatturiero, l’healthcare, l’agricoltura, il settore civile, commerciale e dei beni di consumo, la logistica e i trasporti. Le attività di ricerca sono in linea con la Multi-Annual Roadmap (MAR) for Robotics in Europe (aggiornata annualmente grazie al supporto dei Topic Groups di euRobotics AISBL, di cui sia ISSIA che ITIA sono soci nonché attivi partecipanti), e si inquadrano in ciascuno dei cluster tecnologici (Key Technology targets) individuati dalla MAR: sviluppo di sistemi, interazione uomo-robot, meccatronica, percezione, navigazione e cognizione. L’obiettivo è quello di sviluppare sistemi robotici dotati di capacità percettive e cognitive avanzate e autonomia decisionale, nonché di caratteristiche di affidabilità, riconfigurabilità, adattabilità e interattività (Key System Abilities), in grado di svolgere compiti complessi anche in ambienti sconosciuti o affetti da incertezza, cooperando con l’uomo in modo efficiente e sicuro. La ricerca coinvolge diverse categorie di robot (Robot Categories), sia di tipo on the ground, che aerei, e marini. " | |
"69","Automatica","3","Robotica e Automatica","2","Questo tema si concentra sullo studio di metodi per la progettazione di sistemi di controllo e osservazione dello stato, con particolare riferimento ai sistemi complessi e non lineari. I sistemi di controllo sono presenti ovunque nel mondo che ci circonda, e svolgono un ruolo essenziale per il funzionamento efficiente di vari sistemi e processi. Di conseguenza, l'ingegneria dei sistemi di controllo ha assunto un’importanza fondamentale, destinata ad aumentare con il progresso tecnologico. La ricerca in Automatica si propone di studiare sistemi complessi, anche interconnessi, nella maggior parte dei casi non lineari e dipendenti da numerosi parametri, la cui gestione efficiente richiede lo sviluppo di algoritmi di controllo costruiti partendo dai dati misurati sul campo. L’obiettivo è la progettazione di controllori che garantiscano il raggiungimento del compito prestabilito in modo efficiente ed efficace. Gli ambiti di applicazione sono diversi e multidisciplinari, e includono applicazioni in settori classici dell’ingegneria, come quelli aerospaziale, chimico, elettrico e meccanico, e nuove aree di ricerca come economia, sistemi biologici, scienze sociali. Si citano, per esempio, sistemi logistici, traffico veicolare, sistemi energetici, biochimica, medicina, sistemi multiagente, gestione di task e controllo del movimento in reti di robot, ottimizzazione di datacenter, sistemi di diagnostica predittiva di guasti, trattamento di segnali e immagini, cyberphysical systems, ecc." | |
"66","Sistemiper la produzione personalizzata ","4","Fabbrica del Futuro","1","Soluzioni e sistemi per la produzione efficiente di prodotti personalizzati ad alto valore aggiunto, in grado di continuare a supportare la crescita del Made in Italy in Europa e nel mondo. Tali sistemi dovranno essere in grado di configurarsi e riconfigurarsi in tempi ridotti per soddisfare i requisiti di produzioni personalizzate, dovranno presentare un elevato grado di integrazione con i clienti ed i loro requisiti e dovranno essere caratterizzati da nuovi modelli di gestione dei prodotto-servizio. L'adozione di tecnologie innovative per la produzione personalizzata di consumer goods ad alto valore aggiunto rappresenta una sfida che, partendo da settori tradizionali del Made in ITALY, estende le sue potenzialità sino a prodotti per il benessere e la salute del consumatore. In tal senso, la concezione e lo sviluppo di soluzioni di produzione dedicate, basate su approcci di hybrid ed additive manufacturing, risulta cruciale per lo sviluppo di componenti e parti funzionali del prodotto finale, quali oggetti caratterizzati da proprietà e comportamenti dinamici differenziati in risposta ai bisogni ed alle esigenze del consumatore. La coniugazione di tecnologie ibride/additive con approcci innovativi al processo ed al suo controllo consentiranno lo sviluppo di macchine dedicate e soluzioni distribuite a livello retail per la personalizzazione di componenti e di sistemi flessibili a livello di fabbrica per la produzione di beni, secondo il paradigma delle minifactories. " | |
"68","Strategie,metodi e strumenti per la sostenibilità industriale ","4","Fabbrica del Futuro","2","L’attuale sfida industriale, in un contesto complesso e fortemente competitivo, rende necessario concepire sistemi e modelli e realizzare soluzioni che migliorino la sostenibilità dei processi e dei prodotti, tenendo in considerazione sia l’intero ciclo di vita, sia l’evoluzione futura dei bisogni e della disponibilità di risorse.Per affrontare questa sfida, è necessario riprogettare i prodotti, ripensare i processi e gli impianti, migliorare le tecnologie e le macchine, aumentare l’efficienza energetica e ridurre gli scarti. Perché queste attività abbiano l’efficacia già oggi necessaria, devono essere inserite in un contesto generale di economia circolare, reso possibile dall’adozione di filiere chiuse e di modelli di business con esse coerenti, e devono sfruttare tutte le potenzialità di incremento e gestione della conoscenza offerte dai sistemi della fabbrica intelligente. In particolare, è urgente che le imprese condividano le informazioni attraverso l’integrazione di macchine, operatori e fabbriche, in modo da migliorare la propria flessibilità, riconfigurabilità e reattività alle richieste dinamiche del mercato. " | |
"70","Sistemiper la valorizzazione delle persone nelle fabbriche","4","Fabbrica del Futuro","3","Partendo dalla sfida specifica derivante dai trend demografici e sociali e delle esigenze di tutte le categorie di lavoratori, l’obiettivo è la concezione e lo sviluppo di sistemi produttivi in grado di accogliere le persone e valorizzare le loro competenze al fine di contribuire alla soddisfazione e al benessere dei lavoratori. La fabbrica nel futuro si troverà infatti sempre più a fronteggiare problemi legati per esempio all'invecchiamento della popolazione che, riflettendosi in una estensione della vita lavorativa, rende necessario mettere le persone nella condizione di svolgere il proprio lavoro compatibilmente con l'evoluzione ed il cambiamento delle proprie capacità cognitive e fisiche. Tutto questo richiede uno sforzo elevato sia dal punto di vista tecnologico che organizzativo. Le fabbriche innovative dovranno quindi essere sempre più inclusive, ovvero fortemente orientate al coinvolgimento e alla partecipazione delle persone (utenti, operatori, manager) che potranno esplicare attività complesse ad elevato valore aggiunto con il supporto di strumenti e dispositivi innovativi. Ne risulta che le persone e le macchine dovranno essere nella condizione di poter cooperare sinergicamente, condividendo attività in modo efficiente e sicuro. Il posto di lavoro dovrà essere riprogettato sulla base di specifiche regole di ergonomia ed organizzato in base a ritmi di lavoro adattabili per fornire un ambiente e condizioni di lavoro adeguato alle diverse persone, per dare la possibilità di operare in modo produttivo indipendentemente dalle caratteristiche in termini di età, sesso e stato fisiologico o patologico. Allo stesso modo l'uso di tecnologie abilitanti volte alla rappresentazione digitale della fabbrica favoriscono l'integrazionea livello di informazione e conoscenza. La persona deve quindi essere ritenuta elemento centrale rispetto a tutti i livelli e tutte le dimensioni attraverso cui è definita la fabbrica. In un contesto caratterizzato da fabbriche nelle quali prodotti, processi e tecnologie evolvono attraverso dinamiche articolate, la conoscenza e la capacità di interpretare fenomeni produttivi complessi e identificare soluzioni basate sull'esperienza, rappresenta una sfida fondamentale. E' quindi essenziale investire strategicamente anche nelle tecnologie abilitanti a supportodi una interazione intuitiva e diretta delle persone con le risorse stesse, così come nella formalizzazione e riutilizzo di tali esperienze attraverso rappresentazioni opportune dell'informazione e della conoscenza (ad esempio semantiche ed ontologiche)" | |
"71","Sistemidi produzione evolutivi e adattativi ad alta efficienza","4","Fabbrica del Futuro","4","L’obiettivo è da un lato lo sviluppo di sistemi produttivi ad alta efficienza che consentano di minimizzare i costi di produzione, migliorare la produttività e la qualità del prodotto.Dall’altro lato è lo sviluppo di una nuova generazione di sistemi produttivi in grado di evolvere nel tempo e di adattarsi dinamicamente alle mutevoli condizioni di contesto, determinate dalla turbolenza della domanda, dalla rapidità dei cicli tecnologici e dalle dinamiche della situazione competitiva, vista anche nella sua evoluzione temporale. Tale tema verrà strutturato nelle seguenti sottoaree: Sistemi di controllo avanzato ed ottimizzazione in tempo reale per linee e sistemi di produzione; sistemi di comunicazione industriali; metodi formali per la sicurezza dei sistemi industriali, cyber-physical e safety-critical (Formal Methods for the Security of Industrial, Cyber Physical and Safety Critical Systems); componenti, sensori e macchine intelligenti per la produzione adattativa ed evolutiva; processi produttivi innovativi; tecnologie ICT per l’intelligenza, l’interoperabilità, l’agilità e la servitizzazione della Fabbrica del Futuro" | |
"100","Tema B1. Nanomateriali per dispositivi e processiindustriali (sensori, sistemi optoelettronici, acustici fotonici,fluidici, …)","5","Nanotecnologie e materiali avanzati","1","Il tema riguarda lo studio di micro-dispositivi acusto-opto-elettronici e sensori di grandezze chimiche e fisiche, lo sviluppo di nanostrutture di semiconduttori III-V realizzate mediante MBE, sistemi 2D di dicalcogenuri di metalli di transizione cresciuti per CVD e PED, nanostrutture e fluidi complessi impieganti nano materiali, sistemi catalitici in polvere e strutturati per applicazioni in ambito industriale. Tra i sensori chimici investigati assumono particolare rilevanza quelli per la rilevazione di gas tossici e i biosensori di sostanze volatili. Si studiano reti di sensori per trasporti, per protezione da eventi naturali catastrofici, per salvaguardia degli edifici e dei beni culturali. Nel campo della sensoristica biomedicale si sviluppano ossidi semiconduttori nanostrutturati e a matrice polimerica.Per ciò che riguarda le nanostrutture di semiconduttori, si studiano punti quantici, multi-layer, nanotubi e nanomembrane di semiconduttori III-V per applicazioni in fotonica e sensoristica. I dicalcogenuri 2D sono studiati per dispositivistica ottica.Le nanostrutture e i fluidi complessi impieganti nano materiali sono di particolare interesse tecnologico e industriale. Nello specifico, si studiano strutture polimeriche e impasti di gomme contenenti nanoinclusioni a stato solido, vernici protettive e coating anti-wear, strutture e dispositivi per l’accumulo del calore.Si studiano inoltre formulazioni catalitiche innovative utilizzate in processi di produzione di intermedi per l’industria chimica, quali olefine, alcoli, acidi carbossilici a basso peso molecolare da fonti fossili o rinnovabili. Gli obiettivi sono l’incremento di attività e selettività e la possibilità di operare in condizioni operative più vantaggiose. " | |
"101","B.2 Nanomateriali perenergetica","5","Nanotecnologie e materiali avanzati","2","L’attività riguarda ad ampio spettro lo sviluppo di materiali avanzati, in particolare materiali compositi e nanostrutture, per applicazioni energetiche. Le tematiche includono lo sviluppo, la preparazione, le tecniche di deposizione e il testing di catalizzatori innovativi in processi di produzione di energia e di fine chemicals. La tematica comprende la messa a punto e la caratterizzazione di nano-fluidi per applicazioni relative ad impianti di condizionamento dell’aria, riscaldamento e refrigerazione, per pompe di calore ad adsorbimento e nuovi materiali per celle solari di ultima generazione e di materiali a cambiamento di fase, (nano-PCM, materiali a cambiamento di fase nanostrutturati) da impiegare nei processi di accumulo termico). Le formulazioni più avanzate riguardano materiali grafenici, perovskiti ibride, nanostrutture metalliche, catalizzatori a base di metalli di transizione supportati su ossidi o su sistemi carboniosi, zeoliti etc.In questo settore si inquadra anche la ricerca sulle celle a combustibile alimentate ad idrogeno e con combustibili alternativi quali metanolo, gas naturale e bio-gas, e su sistemi di elettrolisi. Lo sviluppo di materiali nanostrutturati per elettro-catalizzatori e per il fuel processing ha permesso di migliorare le prestazioni e la stabilità dei dispositivi. Per queste applicazioni sono stati messi a punto sistemi core-shell, compositi e multifunzionali. Vengono studiati nanofiller a base di silice, titania, zirconia etc. dispersi in matrici polimeriche al fine di migliorare le proprietà meccaniche e la conducibilità ionica di membrane polimeriche, per ridurre la permeazione o agire come scavengers di specie radicaliche. Materiali avanzati sono attivamente studiati anche per l’applicazione in sistemi di accumulo elettrico come batterie e supercapacitori, in sistemi per l’accumulo di idrogeno e in processi per la conversione della CO2." | |
"102","B3. Nano materiali per impiegobio-medico","5","Nanotecnologie e materiali avanzati","3","La nanotecnologia offre alternative radicali per numerosi problemi medici, in particolare nel contesto oncologico e biosensoristico. I materiali spaziano da agenti di contrasto multifunzionali ottici e/o magnetici in grado di riconoscere lesioni maligne per via sistemica e di consentirne l’imaging diagnostico e il trattamento ipertermico, a nanopunte in silice per indagini ottiche non-invasive di singole cellule per la valutazione dell’effetto di farmaci innovativi, a un ventaglio di soluzioni ibride per la veicolazione intracellulare di nanosonde per la manipolazione e l’analisi dei parametri biochimici di cellule maligne, a substrati metallici nanostrutturati e compositi per l’identificazione di biomarcatori di malattie neurodegenerative. L’attività è particolarmente rivolta alla messa a punto di nanosistemi ibridi con funzionalità ottiche e/o magnetiche e diverse componenti organiche per combinare imaging fotoacustico e/o MRI e ipertermia ottica e/o magnetica del cancro.Gli altri materiali innovativi riguardano sistemi per ingegnerizzazione tissutale basati su polimeri naturali (collagene, alginato) e sintetici (PCL, PLA, PVA) per realizzare scaffold 3D porosi bioattivi, nanosistemi a base di SiC, ZnO ed Fe3O4 diversamente funzionalizzati per trattamenti antitumorali basati su ipetermia magnetica e terapia fotodinamica indotta da raggi X. Sono inoltre studiate attivamente superfici nanostrutturate con effetto battericida, capsule polimeriche nanoingegnerizzate per targeted delivery e rilascio intelligente di farmaci. La tematiche di bioelettronica e biosensoristica quì studiate comprendono rivelatori di biomarkers, sensori elettrochimici, interfacce neuronali, dispositivi e sistemi memristivi." | |
"103","B4. Modellistica e simulazionenumerica","5","Nanotecnologie e materiali avanzati","4","L’attività condotta nel settore della modellistica e simulazione numerica applicata ai materiali riguarda diverse tematiche. In questo ambito la ricerca è rivolta alla modellizzazione di architetture per ingegneria tissutale, al trasporto fononico, al modeling di refrigeranti alternativi a basso effetto serra e di nanostrutture di carbonio, alle leghe a memoria di forma. Vengono progettate e modellizzate architetture porose 3D interne (alla macro-micro-nano scala) mentre la ricerca offre importanti linee guida sulla dimensione dei pori, l’interconnessione ed altri parametri geometrici chiave.Si sviluppano modelli numerici avanzati per simulazioni di dispositivi nanoelettronici caratterizzati da forte confinamento quantistico, per applicazioni in transistor con switch ad alta velocità e basso voltaggio, o per la generazione di frequenze ultra-alte.Il settore della fluidodinamica sta man mano acquisendo un ruolo dominante nel quadro delle moderne scienze applicative. Tradizionalmente, la dinamica dei fluidi si rivolge ai settori macroscopici dell'ingegneria, ma sempre più spinta ad interfacciarsi con altre discipline, principalmente la scienza dei materiali e la biologia. Questo interfacciamento richiede sostanziali estensioni della scienza dei fluidi, sia sul piano concettuale che su quello modellistico e applicativo. " | |
"119","Renewable electricityand heating and cooling technologies ","6","Tecnologie energetiche a basse emissioni","1","Questo tema riguarda lo sviluppo di tecnologie innovative per la conversione efficiente di energie rinnovabili.Nel campo dell’energia marina ed eolica le attività riguardano i sistemi di conversione e l’ottimizzazione del sistema integrato di generazione elettrica. Nel settore della biomassa/biocombustibili, la ricerca è focalizzata sui processi e tecnologie per la valorizzazione di biomasse e rifiuti, la produzione e l’utilizzo di biocombustibili di seconda-terza generazione per la generazione di energia in sistemi stazionari e nel trasporto. Nell’ambito del solare fotovoltaico gli obiettivi sono lo sviluppo di processi di produzione low-cost, la riduzione del costo dell'energia e l'aumento della potenza specifica. Nell’ambito del solare termico, le ricerche riguardano le tecnologie per l’accumulo e lo sfruttamento dell’energia solare, anche accoppiata a combustione di biomasse e biofuels, e l’impiego di energia solare per lo sviluppo di macchine ad assorbimento per il solar cooling. Gli obiettivi della ricerca nel settore delle celle a combustibile sono volti ad aumentare l’efficienza del processo di conversione elettrochimica e migliorare l’affidabilità. Sono inoltre allo studio sistemi avanzati per l’accumulo termico basati su materiali a cambiamento di fase e reazioni termochimiche. Sono, infine, allo studio modelli numerici per la gestione e controllo dei flussi energetici di smart grid basate sull'integrazione ed ibridizzazione di fonti rinnovabili e fossili." | |
"120","Providing the energysystem with flexibility through enhanced energy storage technologies ","6","Tecnologie energetiche a basse emissioni","2","Questo tema comprende la ricerca nel settore della generazione di idrogeno mediante elettrolisi e riconversione elettrochimica della CO2 in feed-stock chemicals per l’accumulo su un orizzonte temporale a lungo termine del surplus di energia da fonti rinnovabili ed in contesti di grid-balancing service. Sono studiati attivamente i sistemi di accumulo elettrochimico come supercapacitori e batterie di nuova generazione. In particolare l’attività è focalizzata su batterie ad alta temperatura, metallo-aria e batterie al Litio. Gli obiettivi sono rivolti a migliorare l’efficienza, le prestazioni, la durata dei sistemi e a ridurre I costi." | |
"121","Sustainablebiofuels and alternative fuels for the European transport fuel mix ","6","Tecnologie energetiche a basse emissioni","3","Le attività svolte in tale tema riguardano la produzione e l’utilizzo di biocombustibili liquidi per il trasporto, lo studio biocombustibili gassosi e rinnovabili quali syngas, biometano e miscele biometano idrogeno in motori ad accensione comandata e dual-fuel, lo sviluppo di celle a combustibile ad elettrolita polimerico alimentate ad idrogeno ad elevata efficienza." | |
"122","Enabling thedecarbonisation of the use of fossil fuels during transition to a low-carboneconomy","6","Tecnologie energetiche a basse emissioni","4","L’Italia ha aderito pienamente alla politica europea di riduzione delle emissioni di CO2 e incentiva lo sviluppo di tecnologie per la produzione di energia da fonti rinnovabili, la diversificazione e distribuzione dei sistemi di produzione di energia sul territorio. Tuttavia, la necessità di garantire al Paese la sicurezza e la continuità dell’approvvigionamento energetico non può ancora prescindere dall’utilizzo delle fonti fossili. In tale ambito, sono svolte attività finalizzate all’uso pulito di combustibili fossili, come le azioni di supporto all’industria termoelettrica in relazione all’ottimizzazione dei processi esistenti e alla soluzione di problemi tecnologici, gli studi sui sistemi di diagnostica e abbattimento degli inquinanti e degli aspetti di sicurezza connessi ai processi di produzione di energia. Parallelamente sono in corso attività relative a processi innovativi di combustione di tipo capture ready (CCS), quali l’ossicombustione, chemical looping, combustione mild, nonché alla cattura della CO2 mediante una varietà di tecnologie (calcium looping, adsorbimento su sorbenti innovativi, cattura per via enzimatica) e alla sua valorizzazione per produzione di chemicals e combustibili. Altri sottotemi mirano allo sviluppo di sistemi di cogenerazione per uso locale/micro-grid, tra questi anche sistemi ibridi di piccola taglia che integrano il contributo di differenti energie rinnovabili, quali il solare e le biomasse." | |
"123","Tecnologie HVAC&R (Heating, Ventilating and Air-Conditioning& Refrigeration) e risparmio di energia negli edifici","6","Tecnologie energetiche a basse emissioni","5","Nell’ambito delle tecnologie HVAC&R le ricerche riguardano nuovi fluidi operativi primari e secondari (refrigeranti alternativi e nanofluidi) e fluidi frigorigeni naturali che rispettano le nuove normative europee (F-gas). Oltre alla tradizionale ottimizzazione termofluidodinamica di componenti e sistemi, le attività affrontano le esigenze di regolazione e controllo, oltre che di monitoraggio e analisi energetica. Nell’ambito dell’efficienza energetica di edifici e impianti, sono allo studio tecniche ottiche di monitoraggio e diagnostica basate sulla termografia infrarossa e sulla Particle Image Velocimetry. Sono inoltre investigati nuovi materiali adatti all’accumulo termico, quali i PCM. Ulteriore tema di ricerca è la tecnologia di produzione dei geopolimeri come efficace alternativa al cemento Portland con notevole riduzione di emissioni di CO2. Per lo sviluppo di prodotti utilizzabili e commerciabili sono, infatti, necessarie attività di studio finalizzate all’ottimizzazione dei processi produttivi, dei materiali ottenuti e dei costi di produzione. Per quanto concerne la refrigerazione, le attività riguardano nuove leghe intermetalliche con effetto magnetocalorico gigante per la refrigerazione magnetica. Gli studi sono focalizzati sulla ottimizzazione della microstruttura e composizione di materiali magnetocalorici commerciali e sulla modelizzazione del comportamento termico ed ottimizzazione della configurazione magnetica per dispositivi refrigeranti." | |
"59","Dispositivie tecnologie a microonde ed onde millimetriche","7","Dispositivi e Sistemi ICT","1","I Dispositivi attivi e passivi e le tecnologie a microonde ed onde millimetriche (da qualche centinaio di MHz fino a 220 GHz) sviluppati in questo ambito trovano applicazione in diversi campi, quali le telecomunicazioni, la sensoristica industriale, la diagnostica elettromagnetica, la fusione e la strumentazione scientifica (e.g., osservazione della Terra, radio-astronomia). L’indagine sull’applicabilità di nuove tecnologie, quali l’additive manufacturing, e di nuovi materiali in questi settori applicativi riveste particolare importanza. Le attività eseguite coprono tutto il ciclo di sviluppo dei componenti a radio-frequenza, a partire dalla modellizzazione fino alla loro caratterizzazione sperimentale ed utilizzo nell’ambito applicativo di interesse. Con riferimento al programma quadro H2020, le tematiche di ricerca rientrano nelle LEIT ICT e Space e sono di interesse, tra le altre, per le social challenges Health, Food Security, Smart Transport, Secure Societies. " | |
"60","Tecnologiemicro e nano-elettroniche","7","Dispositivi e Sistemi ICT","3","Nel settore delle Tecnologie micro e nano-elettroniche si stanno sviluppando sensori che trovano importanti applicazioni nelle social challenges (Health, Smart Transport, Secure Societies) e che sono basati su diverse tecnologie, i.e. MEMS piezoelettrici, micro e nano-elettronica, transistor elettrochimici, dispositivi bioinspired, onde acustiche superficiali, tecnologie magnetiche integrate con tecnologie al Si, nanofibre elettrofilate da polimeri conduttori, a trasduzione elettrica e/o elettrochimica. Le attività sono riconducibili alle LEIT ICT sotto le call “Smart System Integration” e “Generic micro- and nano-electronic technologies”. Alcuni campi applicativi delle tecnologie sviluppate sono la rivelazione di radiazioni, la bioelettronica, la misura di piccole concentrazioni di sostanze volatili, la rilevazione di biomolecole, l’ingegneria tissutale. " | |
"77","Fotonica","7","Dispositivi e Sistemi ICT","2","Nel campo della Fotonica sono sviluppati sia componenti di base, come sorgenti di luce innovative e dispositivi ottici micro e nano strutturati, che dispositivi più maturi tecnologicamente, estremamente rilevanti per la LEIT ICT e con applicazioni nelle social challenges (Health, Food security, Secure Societies). Lo sviluppo di sorgenti laser innovative include la progettazione e l’analisi di laser ad emissione verticale superficiale (VCSEL) e la messa a punto di sistemi laser ceramici operanti nel vicino e medio infrarosso. Altra linea di attività riguarda la sintesi di QD metamorfici per sorgenti di singolo fotone. Le applicazioni vanno dalla sensoristica al telecom, dalla crittografia alle telecomunicazioni quantistiche.Dispositivi micro e nano strutturati in fibra ottica e in microottica vengono messi a punto per sensori biologici (label-free e non) o meccanici, e per fotonica a microonde. Tecnologie innovative consentono di realizzare nanoprobes in silice, micro-risonatori ottici ad alto fattore di qualità in materiali cristallini e micro/nano-oscillatori optomeccanici a bassa dissipazione meccanica ed ottica per sistemi interferometrici.Dispositivi fotonici con maturità tecnologica più avanzata vengono sviluppati per applicazioni nelle social challenges. Si tratta di sensori ottici microfluidici e optofluidici, di sensori distribuiti in fibra ottica basati su scattering (Rayleigh e Brillouin), di sensori basati su reticoli in fibra, e di LED blu ad alta potenza." | |
"78","Tecnologie ed architetture di comunicazione e networking per il Future Internet","8","Internet del futuro","1","Il tema del Future Internet è un aspetto caratterizzante il settore delle reti e TLC e riveste un ruolo fondamentale nel panorama di Horizon 2020. Le tematiche sono estremamente ampie ed articolate. Le tecnologie di comunicazione e networking rivestono un ruolo fondamentale. L’integrazione di dispositivi mobili è una sfida significativa per vari motivi. Da un lato, devono ancora essere risolte problematiche di efficienza, sia energetica che spettrale, a livello di tecnologia trasmissiva e di accesso al mezzo. Dall’altro, si studiano soluzioni architetturali scalabili ed energicamente efficienti per la comunicazione e condivisione dati anche in mobilità, anche nell’ambito delle reti 5G. Questo è particolarmente vero per l’Internet of Things, che richiede soluzioni efficienti per l’integrazione di una quantità enorme di piccoli dispositivi nell’architettura complessiva Internet. Essendo “vicine all’utente”, le soluzioni per reti mobili permettono lo sviluppo di architetture, protocolli e middleware per applicazioni specifiche, con notevoli ricadute potenziali in termini di innovazione. Nell’ottica dell’integrazione tra mondo fisico e cyber, un’area emergente è l’Internet of People, dove il comportamento individuale e sociale degli utenti è un componente essenziale delle funzioni di rete. Infine, il Cloud Computing pone notevoli sfide anche in ambito di networking, sia per quanto riguarda il “core” della rete, che per quanto riguarda l’accesso a servizi cloud in ambiente mobile." | |
"79","Distributed, High Performance and Parallel Systems","8","Internet del futuro","2","L’area scientifica dei sistemi di elaborazione parallela e distribuita delle informazioni ha vissuto un notevole cambiamento negli ultimi anni. Il fulcro della ricerca e dello sviluppo si è progressivamente spostato dalle tecniche di aggregazione di potenza di calcolo per la risoluzione di grandi problemi della scienza e dell'ingegneria, sempre più verso lo studio e la progettazione di sistemi e strumenti per la gestione, analisi, e sintesi di grandi quantità di dati caratteristici delle nuove applicazioni della Data Science e del mondo Business. Contemporaneamente, la crescita del numero di core del processore e dei coprocessori grafici ha stimolato la ricerca nel settore degli strumenti di programmazione e degli algoritmi per sfruttare adeguatamente tali architetture, anche eterogenee, ad alte prestazioni. Questi cambiamenti hanno comportato una fertilizzazione incrociata delle tematiche del calcolo parallelo e distribuito con altre (software engineering, security, knowledge discovery, information retrieval, machine learning, ecc.), e una focalizzazione della ricerca su problematiche legate ad esempio a: virtualizzazione, interoperabilità e gestione dei sistemi Cloud e delle architetture orientate ai servizi, paradigmi e modelli di programmazione data-parallel, bio-inspired, agent-based. gestione ed analisi di big data, efficienza energetica, infrastrutture distribuite per e-science." | |
"80","Software Engineering","8","Internet del futuro","3","I moderni sistemi software sono spesso costituiti da elementi computazionali che collaborano tra loro per il controllo di entità di varia natura per fornire un’ampia collezione di servizi e applicazioni innovative che garantiscano un comportamento affidabile anche a fronte di eventi non sempre predicibili ed allo stesso tempo siano user friendly. L'uso di un buon processo di sviluppo del software è ritenuto essenziale al fine di garantire lo sviluppo di applicazioni e servizi che rispettino i suddetti requisiti di affidabilità, usabilità ed adattabilità. Tale processo può essere creato ad hoc secondo l’approccio proposto dalla situational method engineering oppure, nel caso in cui i sistemi da sviluppare siano particolarmente critici mediante l'uso di metodi formali.La ricerca sui sistemi software complessi è recentemente caratterizzata dagli studi sui sistemi adattativi e auto-organizzanti. In tale ambito si collocano anche i sistemi di workflow adattativo che affrontano le necessità di un processo di lavoro flessibile e l’uso di simulazioni che permettono la valutazione di scenari alternativi e la messa a punto di sistemi che sarebbe costoso o pericoloso sperimentare nella realtà." | |
"55","Nuovi approcci bioinformatici a supporto di esigenze cliniche, mediche e biotecnologiche","9","Biotecnologie","1","Questo tema include lo sviluppo di modelli matematici e statistici, lo sviluppo di nuovi algoritmi computazionali e di strumenti open-source, la gestione, l’analisi e l’integrazione di grandi moli di dati. Aspetti specifici riguardano 1) la bioinformatica, attraverso lo sviluppo di metodologie per l’analisi e l’integrazione di dati omici con particolare riferimento a quelli prodotti dai sequenziatori massivi di nuova generazione, 2) la system biology, attraverso lo sviluppo di modellistica per la ricostruzioni di reti e studio della relativa dinamica, 3) i sistemi di supporto delle decisioni, attraverso lo sviluppo sti strumenti di estrazione di conoscenza. I diversi sotto-temi di ricerca hanno applicazioni legate alla ricerca biomolecolare, biomedica e/o agroalimentare e sono mirate a far comprendere, attraverso strumenti e modelli computazionali, il funzionamento di sistemi biologici, anche complessi, la fisiologia delle cellule, l’insorgenza ed evoluzione di patologie, la risposta a stress o trattamenti farmacologici.Il tema integra competenze multidisciplinari in ambito sia modellistico e tecnologico che di scienze biomediche. Inoltre all’interno del presente tema sono sviluppati aspetti specifici legati alla creazione di soluzioni IT per la gestione di Bigdata." | |
"56","Processi biotecnologici industriali","9","Biotecnologie","4","Il tema affronta due processi biotecnologici basati su trasformazioni enzimatiche: i) cattura della CO2 da fumi di combustione assistita dall’enzima anidrasi carbonica; ii) pretrattamento di biomasse lignocellulosiche attraverso enzimi ossidativi e idrolitici (laccasi e cellulasi) per la rimozione della lignina e il recupero di zuccheri fermentabili per la produzione di biocombustibili (etanolo, butanolo) e altri chemicals. Entrambi i processi hanno interesse per il settore energetico in particolare il primo riguarda le tecnologie per la combustione pulita di combustibili fossili nonché la riduzione delle emissioni di CO2 attraverso processi di post-combustione innovativi che permettan il riutilizzo della CO2 come fonte di carbonio. Il secondo riguarda la produzione di biocombustibili di seconda generazione per via fermentativa da fonti rinnovabili quali biomasse lignocellulosiche contenute in scarti dell’industria agro-alimentare." | |
"57","Tools e tecnologie per terapie avanzate","9","Biotecnologie","2","Questo tema include la progettazione e realizzazione di bioreattori per l’ingegneria dei tessuti, ovvero dispositivi ad alto livello di innovazione tecnologica in grado di coltivare cellule su supporti tridimensionali (biomateriali), mimando la complessità del microambiente fisiologico del tessuto naturale da rigenerare. La realizzazione di questi modelli artificiali 3D che riproducano in vitro il processo di crescita tissutale è un aspetto cruciale non solo per lo studio delle condizioni fisiologiche (applicazioni di medicina rigenerativa), ma anche per studiare i meccanismi di crescita tumorale, testare nuovi approcci terapeutici, studiare l’insorgenza metastatica in un ambiente 3D più realistico rispetto alle tradizionali colture su piastra ed eticamente preferibile ai modelli animali. Questo tema affronta anche tematiche di drug design e delivery, attraverso l’analisi e sviluppo di metodologie geometriche per la definizione di superfici molecolari e la valutazione della similarità tra forme (docking molecolare), modelli per lo studio della dinamica del farmaco che diffonde da una matrice polimerica verso un tessuto biologico per ottimizzarne l’efficacia terapeutica. Infine, ci si occupa anche dello sviluppo di metodi avanzati ed innovativi per l’acquisizione dell’informazione, anatomica e funzionale, specifica del paziente a partire dalla quale sviluppare tecniche biomeccaniche per la fabbricazione della protesi customizzata." | |
"58","Biofotonica","9","Biotecnologie","5","Il tema è incentrato su diagnostica e terapia per applicazioni biomedicali. Per la diagnostica, le attività sono relative a:-progettazione, realizzazione e caratterizzazione di strutture ottiche risonanti ultrasensibili per la rivelazione di biomarker di interesse clinico, in particolare reticoli LPG e micrororisonatori optofluidici (a cristallo fotonico, a bolle e ad anello)-progettazione e realizzazione di sensori a fibra ottica e biochip funzionanti per luminescenza-messa a punto di tecniche di microscopia avanzata inclusa microscopia di generazione di seconda armonica (SHG) per diagnostica di tessuto connettivale e spettroscopia, microscopia e tomografia fotoacustica per la rivelazione precoce di lesioni tumorali-sviluppo di metodi basati su microscopia Raman e spettroscopia Raman amplificata da superfici per diagnosi di malattie neurodegenerative.Per la terapia, le attività sono relative allo sviluppo di metodi, tecnologie e procedure terapeutiche e chirurgiche in ambito preclinico e clinico, basate sull'impiego di laser, LED, biopolimeri e agenti di contrasto laser-attivabili per le seguenti applicazioni: -riparazione laser-indotta di tessuti biologici (oculistica, microvascolare, neuro) -emostasi indotta da blue-LED di alta potenza (dermatol., vascolare) -tecniche di Nanomedicina laser-assistita con nanoparticelle plasmoniche e vettori cellulari (teranostica tumorale) -dispositivi biopolimerici impiantabili per il rilascio di farmaci con attivazione laser." | |
"94","Synthetic biology","9","Biotecnologie","3","La synthetic biology ha l’obiettivo di riuscire a creare e costruire sistemi di bioingegneria che processino e manipolino informazioni, fabbrichino materiali e strutture, e mantengano ed aumentino la salute umana. In particolare, questo tema include (i) la definizione di framework computazionali per il design o ingegnerizzazione di reti che riproducano comportamenti desiderati, (ii) l’individuazione di strutture di rete che esibiscano un prefissato comportamento desiderato tramite esperimenti in silico, cioè tramite simulazione di modelli di reti di regolazione genica che si ipotizzano in grado di riprodurre la dinamica desiderata, (iii) metodi di ottimizzazione dello spazio dei parametri affinché il comportamento desiderato si verifichi con una alta probabilità, (iv) ranking delle reti/modelli in base all’aderenza agli obiettivi prefissati e alla facilità di realizzazione in vitro e in vivo." | |
"72","Tecnologie per l’Aerospazio e la Sicurezza nelloSpazio","10","Tecnologie per l'Aerospazio e l'Osservazione della Terra","1","Le attività spaziali sono sempre state rischiose ed estremamente complicate a causa delle enormi energie per unità di massa da erogare, controllare e gestire perché i voli spaziali possano realizzarsi, partendo dalla superficie di un pianeta che li rende solo marginalmente possibili. Non sorprende quindi che i temi legati alla sicurezza e alla necessità di sviluppare tecnologie di avanguardia siano da sempre inestricabilmente legati alle imprese spaziali. Data la molteplicità di discipline e di competenze necessarie per coprire anche solo una parte di questi aspetti, non deve dunque sorprendere che il CNR, con l’ampio spettro della sua rete scientifica e l’interdisciplinarietà che lo caratterizza, svolga un ruolo da protagonista anche in questo campo. Il tema riguarda la sicurezza delle attività spaziali, sia in orbita che nei casi di rientro incontrollato sulla Terra, e le tecnologie abilitanti per l’utilizzazione e l’esplorazione dello spazio. Le attività concernono: la modellazione e la mitigazione dei detriti orbitali; le previsioni di rientro incontrollato in atmosfera ai fini di protezione civile; l’ammaraggio di veicoli spaziali; l’astrodinamica applicata al supporto di missioni spaziali, esperimenti scientifici, sistemi di tracking e determinazioni orbitali; le tecnologie per la produzione e l’accumulo di energia e per l’osservazione dello spazio nello spettro fino ai raggi gamma; le tecnologie i sensori e dispositivi optoelettronici per l’osservazione dello spazio." | |
"73","Tecnologie per l’Osservazione della Terra","10","Tecnologie per l'Aerospazio e l'Osservazione della Terra","2","L’osservazione della Terra è un argomento di ricerca in cui il CNR è riconosciuto come eccellenza in campo internazionale. Il tema riguarda lo sviluppo e la caratterizzazione di sensori operanti sia da piattaforma aerea che da satellite e le tecniche di elaborazione ed integrazione di dati acquisiti sia da strumenti ottici come scanner multi/iperspettrali, interferometri ad immagine, Lidar, che a microonde come radiometri e radar ad apertura sintetica (SAR). Riguardo al SAR le attività sono strettamente connesse allo sviluppo tecnologico della costellazione italiana COSMO-SKYMED (CSK), attualmente in orbita, ed al programma CSK Second Generation (CSG). Nel campo iperspettrale il tema è prioritariamente rivolto alla missione PRISMA. In ambito europeo si sviluppano tecnologie di elaborazione relative ai dati acquisiti dai sensori del programma Copernicus (in particolare le 5 Sentinelle) e della missione FLEX volta allo studio della fotosintesi della vegetazione attraverso la fluorescenza indotta dal sole. Vengono considerati programmi Europei di medio termine per la messa in orbita di sensori a basso costo e, oltre l’ambito Europeo, programmi come SMAP con NASA, AMSR2 e ALOS2 con JAXA, RADARSAT2 con CSA, SAOCOM con CONAE, VENUS. Il tema affronta, inoltre, le problematiche relative all’integrazione di dati e di tecnologie di remote sensing in situ attraverso la conduzione di campagne di misura, la realizzazione di attività CalVal e la gestione di siti di test attrezzati." | |
"74","Modellistica Elettromagnetica e Statistica di dati diOsservazione della Terra","10","Tecnologie per l'Aerospazio e l'Osservazione della Terra","3","Le attività sono fortemente orientate alle applicazioni e riguardano lo sviluppo di metodi di analisi statistica dei dati, di algoritmi di data fusion, di approcci per l’interpretazione di dati OT, e di modelli elettromagnetici finalizzati all’estrazione di parametri bio-geofisici direttamente fruibili per il monitoraggio del territorio. Le attività sono in linea con i programmi spaziali nazionali di OT e con le priorità definite dal programma Copernicus. " | |
"75","Tecnologie ed infrastrutture ICT per la gestione,elaborazione e rappresentazione di dati OT","10","Tecnologie per l'Aerospazio e l'Osservazione della Terra","4","Le infrastrutture ICT hanno determinato progressi tecnologici disruptive che hanno avuto importanti risvolti sociali. Il tema riguarda lo studio e lo sviluppo di tecniche per la fruizione, l’analisi ed il trattamento dei dati OT e delle informazioni geospaziali estratte basate sull’utilizzo di piattaforme avanzate ICT. In particolare, la recente disponibilità di ingenti moli di dati satellitari (con particolare riferimento a quelli acquisiti a scala globale dai sensori Sentinel) e la disponibilità di dati provenienti da sensori a terra ha aperto nuovi scenari di ricerca incentrati sulla elaborazione efficace ed efficiente del dato OT per ottenere informazioni della superficie terrestre a larghissima scala spaziale e in tempi estremamente ridotti. A tal fine, il ricorso ad infrastrutture di calcolo ad alte prestazioni, nonché lo sviluppo di algoritmi per il trattamento del dato OT, ma anche la possibilità di condividere questi dati attraverso l'uso di servizi standardizzati capaci di sfruttarle in maniera efficiente, risulta di primaria importanza." | |
"76","Tecnologie per le telecomunicazioni spaziali, l’aeronauticae la navigazione","10","Tecnologie per l'Aerospazio e l'Osservazione della Terra","5","Il tema concerne lo sviluppo di tecnologie per le comunicazioni satellitari, la propulsione, la sicurezza in aeronautica e la navigazione. Le attività di ricerca, di natura sia software sia hardware, sono organizzate in due sottotemi.Il primo sottotema è incentrato sullo sviluppo di tecnologie per payload satellitari, con particolare riferimento alle reti di telecomunicazioni High Throughput Satellite di prossima generazione. In questo settore, le attività coprono, grazie all’interdisciplinarità delle competenze degli istituti CNR coinvolti, i diversi livelli di rete, dallo studio delle architetture e dei protocolli fino alla modellizzazione del canale trasmissivo ed alla progettazione, realizzazione e caratterizzazione sperimentale di componentistica a microonde ed onde millimetriche passiva ed attiva. Relativamente alle tecnologie SW, vengono presi in esame:- Protocolli di accesso multiplo a satellite, protocolli per delay e disruptive tolerant networks (DTN)- Future web technologies- Protocolli M2M via satellite e paradigmi di Information Centric Networking per applicazioni di sensor web- Reti di droni, UAV e RPAS e protocolli di comunicazione in Line of Sight e beyond Line of Sight.Il secondo sottotema è dedicato alle tecnologie per l’aerospazio, con particolare riferimento ai sistemi di generazione di potenza a basso impatto ambientale, al monitoraggio strutturale, alla sicurezza in aeronautica, all’ammaraggio, ed alla manutenzione e gestione dell’end of life." | |
"104","Sensori per la sicurezza agro-alimentare basati su dispositivi MEMS","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","1","Fabbricazione di micro dispositivi piezoelettrici per l’implementazione di sensori chimici e biologici per applicazioni in ambiente liquido ed in aria. In questo contesto vengono utilizzate le tecniche di micro-fabbricazione tipiche dei MEMS (Micro-Electro-Mechanical-System) per la realizzazione dei dispositivi. In base all’applicazione specifica verrà impiegato il trasduttore più idoneo (es. dispositivi ad onde acustiche superficiali o di volume) funzionalizzato con un mediatore di tipo chimico o biologico." | |
"106","Ottimizzazionedi supply-chain alimentari ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","2","La ricerca mira alla modellizzazione, all'analisi ed all'ottimizzazione di reti di distribuzione e catene di produzione decentrate nel settore alimentare mediante modellizzazione di processi di produzione e della tracciabilità dei prodotti" | |
"107","Fotonica ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","3","Realizzazione di dispositivi per spettroscopia miniaturizzati e di basso costo, particolarmente adatti ad operare sia in campo agronomico sia in varie filiere alimentari, per valutare le proprietà nutraceutiche di molti alimenti comuni e di nicchia.Applicazione di metodi spettroscopici direttamente in campo mediante sensori per la valutazione dell’eterogeneità spaziale dello stato fisiologico delle piante e della qualità dei prodotti." | |
"108","Tuteladel suolo e delle acque superficiali ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","4","Attività sperimentali di monitoraggio e analisi dell’impatto delle attività agricole sulla conservazione del suolo, in particolare in relazione ai rischi di erosione del suolo e compattamento, delle sue funzionalità e sul ciclo idrologico" | |
"109","Usosostenibile della frazione solida deireflui zootecnici ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","5","Utilizzare la frazione solida separata del liquame zootecnico come fertilizzante organico risulta la soluzione più logica ed economica. Tuttavia, i reflui zootecnici, qualora non siano gestiti in maniera idonea, sono fonte di inquinamento per aria (emissione di gas serra e di cattivi odori), suolo (accumulo nel terreno di elementi minerali poco solubili, metalli pesanti e fosforo) ed acque superficiali e di falda (rilascio di nutrienti solubili in eccesso, in particolare nitrati, con possibile compromissione della potabilità e aumento del grado di eutrofizzazione). Per assicurare la sostenibilità ambientale del suo impiego, la distribuzione di questo materiale deve essere eseguita in modo che gli elementi nutritivi, in particolare l’azoto, presente per lo più in forma organica, siano resi disponibili in modo commisurato all’assorbimento delle colture." | |
"110","Earth Observation andgeographic information systems for natural resource for remote monitoring and agro-ecosystemmanagement ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","6","L'attività si colloca in un settore emergente, che ancora si deve sviluppare appieno, volto alla realizzazione di servizi a valore aggiunto per l’agricoltura e il monitoraggio delle risorse naturali che beneficiano dell’utilizzo di tecnologie satellitari. Se dal punto di vista tecnologico e strumentale (satelliti, droni, sensori, macchinari agricoli, software ecc) lo sviluppo è oggigiorno molto avanzato, dal punto della generazione di informazioni a valore aggiunto e del loro utilizzo operativo nei processi decisionali (tanto degli enti preposti a definire politiche e azioni di controllo quanto dei singoli agricoltori nella gestione delle loro aziende e colture) ci sono ancora molti passi da percorrere. Il completamento della filiera dato-informazione- servizio risulta perciò fondamentale ed è per questo che è stato posto come obiettivo primario di questo tema" | |
"111","Use of remote sensed data for sustainableagriculture ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","7","SAR and optical data fusion for developing high resolution agricultural monitoring services" | |
"112","Analisidelle prestazioni di mezzi coibentati per il trasporto di merci deperibili ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","8","Il trasporto refrigerato del cibo è un anello fondamentale della catena alimentare, non solo in termini di sicurezza, mantenendo correttamente la temperatura delle merci trasportate, e di riduzione delle perdite post-raccolto (attualmente stimate in totale intorno al 25%), ma anche per il suo significativo consumo di energia (principalmente fossile) e l’impatto ambientale a questo associato. Tra l’altro, la riduzione dei consumi energetici può determinare la diffusione del trasporto refrigerato anche ai prodotti ortofrutticoli, per il quali attualmente non vige l’obbligo del trasporto in condizioni controllate." | |
"113","Analisi delle prestazioni di apparecchiature e impianti per laconservazione e l’esposizione di prodotti alimentari ","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","9","Nonostante esistano diverse tecnologie per ridurre le perdite del cibo dopo il raccolto (essiccamento, inscatolamento, salatura, ecc.), nessuna sembra in grado di combinare l’estensione della vita del prodotto col mantenimento di tutte le caratteristiche fisiche, chimiche, nutrizionali e sensoriali quanto la refrigerazione." | |
"116","Gestionedi specie invasive per la riduzione dei trattamenti fitosanitari","11","Tecnologie per l'Agricoltura Sostenibile e la Sicurezza del Cibo","10","I parassiti rappresentano una minaccia per le colture, in quanto possono arrecare gravi danni alla produzione. Per debellare questi parassiti si impiegano pesticidi il cui uso è, attualmente, soggetto alla direttiva sull’uso sostenibile dei prodotti fitosanitari, che prevede la riduzione dei trattamenti chimici. La conoscenza della dinamica della specie invasiva risulta quindi fondamentale per sapere se e quando intervenire con trattamenti mirati a stadi specifici della popolazione. Questo permette di ridurre i trattamenti fitosanitari, andando verso una produzione biologica con una riduzione dell’impatto ambientale." | |
"95","Edilizia sostenibile","12","Costruzioni sostenibili","1","Valutazione del comfort ambientale indoor e delle prestazioni termiche ed acustiche di materiali, componenti e sistemi di involucro e di impianto. Valutazione delle prestazioni idro-termo-energetiche dei substrati per verde pensile, finalizzato alla strutturazione del relativo laboratorio prove ed alla presentazione di linee guida internazionali in ambito UEAtc. Valutazione delle prestazioni energetiche di componenti di involucro opaco e trasparente attraverso analisi svolte con modelli previsionali, in edifici sperimentali o nelle reali condizioni di utilizzo" | |
"96","Ediliziaper le smart cities","12","Costruzioni sostenibili","2","Monitoraggio ambientale outdoor, analisi dei consumi energetici degli edifici su scala sub-urbana ‘nZED’ e studio di sistemi smart monitoring per la diminuzione dell’esposizione al rumore." | |
"97","Efficienzaenergetica dei sistemi elettrici in Smart Buildings","12","Costruzioni sostenibili","3","Elettronica di potenza dedicata per la conversione energetica in edifici. Distribuzione e gestione intelligente dell’energia elettrica in edifici. Tecniche per l’efficientamento energetico di azionamenti elettici per sistemi HVAC (Heating, Ventilation & Air Conditioning)" | |
"98","LCA, ecodesign e carbon footprint di elementiedilizi e tecnologie innovative abilitanti lo smart building","12","Costruzioni sostenibili","5","LCA, ecodesign e carbon footprint di elementi edilizi e tecnologie innovative abilitanti lo smart building." | |
"99","Tecnologie Innovative per lo Smart Building","12","Costruzioni sostenibili","4","Sviluppo di sistemi integrati di generazione e accumulo di energia per l’abilitazione dello Smart Building. Sviluppo di Energy Mangement Systems a scala edificio e integrazione con domotica." | |
"28","SMARTMOBILITY ","13","Smart City","1","Questo tema di ricerca include lo sviluppo di sistemi di trasporto intelligente (ITS) al fine di fornire servizi integrati di mobilità multimodale per le persone e per le merci, e di favorire lo sviluppo di un modello di mobilità urbano più sostenibile, personalizzato e sicuro. Il raggiungimento di questo obiettivo richiede diverse azioni tra loro complementari. Da un lato, lo sviluppo di una infrastruttura ICT affidabile che renda possibile le comunicazioni tra veicoli (V2V) e con le infrastrutture di trasporto (V2I), sensori a bordo strada e centri gestionali del traffico. Tale infrastruttura è necessaria per raccogliere in tempo reale informazioni relative alle strade, al traffico e alla mobilità, ma anche come tecnologia abilitante per sistemi di guida assistita, cooperativa ed autonoma. Dall’altro lato, è necessario incentivare l’adozione di paradigmi di trasporto più flessibili, che permettano un uso sempre più collettivo e condiviso dei mezzi di trasporto (car e bike sharing, car pooling, ecc.), anche attraverso lo sviluppo di sistemi di predizione, controllo ed ottimizzazione del traffico, dei sistemi logicisti cittadini e dei flussi di persone. Infine, condizione abilitante di una mobilità a basso impatto ambientale è la realizzazione di veicoli a basse emissioni (elettrici, ad idrogeno, ibridi) e lo sviluppo di infrastrutture cittadine di ricarica veloce e la loro integrazione efficiente con la rete elettrica." | |
"29","SMART BUILDING","13","Smart City","2","I moderni edifici sono sistemi complessi costituiti da agglomerati di strutture fisiche ed impianti tecnologici (elettrico, riscaldamento/raffrescamento, idrico, sicurezza, accumulo energetico, ecc.) ad elevata automazione. Un edificio intelligente sfrutta le tecnologie ICT per interconnettere i diversi impianti, monitorare il loro stato, condividere le informazioni operative, ed ottimizzare le prestazioni del sistema edificio nel suo complesso, ad esempio per ridurre i consumi energetici e favorire il riciclo dei surplus energetici generati. Quindi un edificio intelligente dovrà essere “sostenibile”, cioè con un fabbisogno energetico molto basso (anche grazie a materiali a basso impatto ambientale) coperto quasi totalmente da energia prodotta da fonti rinnovabili in loco (Net Zero Energy Building – NZEB). Inoltre un edificio intelligente interagisce con i suoi abitanti per impararne le abitudini e prevederne le necessità al fine di permettere una più efficiente e personalizzata gestione degli impianti dell’edificio e di massimizzare il confort domestico. Infine, un edificio intelligente non è un’entità indipendente ma deve essere gestito in modo integrato con gli altri edifici nelle sue vicinanze e con l’ambiente nella sua globalità, per realizzare distretti intelligenti, al fine di ridurre l’impatto ambientale, e meglio integrarsi con le reti energetiche urbane (elettrica e del calore). di sostenere la rete elettrica urbana e di avere un basso impatto ambientale." | |
"30","SMART ENVIRONMENTS","13","Smart City","3","La difesa dell’ambiente si traduce principalmente in una migliore gestione delle risorse naturali, nel controllo del ciclo dei rifiuti, e nel monitoraggio ambientale. La gestione idrica può permettere la riduzione di sprechi grazie ad un monitoraggio più attento della rete, così come attraverso un efficientamento energetico delle pompe o il riciclo delle acque non destinate a scopo potabile. Un discorso analogo riguarda i rifiuti, in particolare l’obiettivo di incrementare la percentuale di raccolta differenziata. Infine, il controllo dell’inquinamento dell’aria, anche dovuto alla congestione del traffico, mediante specifica strumentazione può stimolare decisioni finalizzate al miglioramento delle condizioni ambientali." | |
"31","SMART ENERGY","13","Smart City","4","Questo tema di ricerca include lo sviluppo delle tecnologie energetiche e degli innovativi servizi di monitoraggio, controllo e comunicazione necessari per creare infrastrutture energetiche (energia elettrica, ma anche teleriscaldamento) intelligenti (Smart Grids) al fine di: i) integrare in modo efficiente la micro-generazione distribuita da fonti rinnovabili non programmabili, da impianti di co-generazione e sistemi di accumulo innovativi, ii) fornire a cittadini strumenti per partecipare attivamente alla produzione di energia, gestire in modo flessibile la domanda ed ottimizzare i propri consumi; iii) facilitare l’elettrificazione dei sistemi di trasporto, ed iv) incrementare significativamente la resilienza e la sostenibilità ambientale della rete elettrica. Questo richiede lo sviluppo di una nuova generazione di dispositivi elettrici e di tecnologie ICT per monitorare, gestire ed ottimizzare un sistema energetico sempre più complesso di cui fanno parte un numero crescente di piccoli generatori da fonte rinnovabile, carichi controllabili e sistemi di accumulo (stazionari e mobili). Questi strumenti concorrono a realizzare un Energy Management System (EMS) che migliori l’efficienza dei flussi energetici sia tra i generatori e la rete nonché tra la rete e gli utenti finali, ed una migliore integrazione con le altre infrastrutture urbane (trasporti, edifici, ecc.)." | |
"32","SMART URBAN MONITORING","13","Smart City","5","Una città intelligente deve dotarsi di tecnologie e sistemi che le possano permettere di raccogliere in tempo reale informazioni sulle attività quotidiane dei cittadini, l’ambiente urbano che li circonda e il verificarsi di eventi di particolare rilevanza, al fine di migliorare la gestione della città. Le reti di sensori che pervadono la città intelligente possono fornire delle informazioni potenzialmente accurate ma circoscritte nel tempo e nello spazio. Al contrario, il progresso tecnologico e scientifico nella realizzazione di dispositivi di acquisizione di immagine con diversa ampiezza di campo (telecamere intelligenti, satelliti ottici, droni, ecc.) permette di sviluppare tecniche molto sofisticate di analisi automatica delle immagini al fine di realizzare una vera e propria interazione visuale con la città. Inoltre, la sempre maggiore disponibilità di telecamere sui dispositivi personali degli utenti (smartphone e tablet), e di dispositivi indossabili (ad es. i google glass) permette di coinvolgere direttamente i cittadini nel monitoraggio urbano. I campi di applicazione delle tecnologie di analisi delle immagini sono molteplici, ma particolare importanza è rivestita dalla video sorveglianza, dal monitoraggio del traffico, e dell’ambiente urbano." | |
"33","SMART GOVERNMENT","13","Smart City","6","In una smart city l’efficienza dei servizi urbani si ottiene anche attraverso la realizzazione di un nuovo modello di governance che preveda una partecipazione attiva del cittadino nei processi decisionali e nella vita amministrativa della città e, al tempo stesso, una città che si adatti in modo flessibile ed autonomo ai bisogni dei suoi cittadini al fine di migliorare i servizi offerti e ridurre i costi. Da un lato è quindi necessario sviluppare strumenti che permettano una fruizione più trasparente dei servizi offerti alla città, ad esempio tramite lo sviluppo di portali di open e linked data che forniscano accesso alle banche dati cittadine. Dall’altro lato le città si devono dotare di un centro controllo urbano (la control room cittadina), che fornisca una piattaforma di supervisione e di gestione integrata dei vari sottosistemi della città. Va sottolineato che le città intelligenti sono per loro natura sistemi molto complessi in cui sono necessarie interazioni tra diversi sotto-sistemi. I servizi offerti ai cittadini sono quindi il risultato di un processo di interazione e coordinamento tra i vari sottosistemi. L’obiettivo finale è avere un insieme di servizi cittadini flessibili che si adattino in modo autonomo e pressoché in tempo reale allo stato in continua variazione della città. " | |
"34","SMART LIVING","13","Smart City","7","Il concetto di Smart Living è trasversale a diverse tematiche ma è comunque centrato intorno ai cittadini ed al miglioramento della qualità della loro vita attraverso l’uso di una serie di servizi ed applicazioni che investono i quotidiani bisogni. Ad esempio, lo Smart Living è correlato con la valorizzazione paesaggistica, ambientale, culturale e turistica della città, per renderla facilmente fruibile come patrimonio comune, per migliorare la conoscenza del territorio e delle sue peculiarità. Smart Living è anche strettamente legato al concetto di sicurezza e salvaguardia del singolo cittadino e della popolazione nel suo complesso, ma anche delle infrastrutture, delle attività, e dei beni ambientali e culturali. Altro concetto insito in smart living è anche una moderna visione dell’educazione scolastica, attraverso nuovi approcci educativi, arricchendo e innovando metodi e strumenti, superando i sistemi classici e il tradizionale ruolo degli educatori.Questo tema si prefigge di sviluppare strumenti per gestire le situazioni di rischio e di vulnerabilità dei cittadini, migliorare la sicurezza sociale e salvaguardare i beni della comunità. Infine la città intelligente deve dotarsi di tecnologie che possano favorire la coesione economica e sociale, anche favorendo l’inclusione sociale delle persone in condizioni di fragilità (persone disabili o anziane) riducendo le barriere nella partecipazione sociale, anche attraverso la riduzione del digital divide. " | |
"35","SMART CITIES MODELING","13","Smart City","8","Nella progettazione di servizi smart per smart cities, l'enfasi viene posta soprattutto sull'importanza della raccolta dei dati e delle comunicazioni, con particolare riguardo all'Internet delle cose. Minore attenzione viene invece rivolta alle interazioni necessarie fra le varie parti (umani, cose, programmi, sistemi di comunicazione, ecc.), e alla necessità di garantire che tali interazioni concorrano alla produzione di servizi ad alta qualità e affidabilità. Si tratta di sistemi complessi, dove i servizi possono essere il risultato di comportamenti collettivi di agenti di varia natura; di sistemi con spiccate caratteristiche di adattabilità e dove, ad esempio, la qualità del servizio può essere il risultato di comportamenti emergenti. L’obiettivo principale dell’attività è creare modelli matematici di comportamento/mobilità di entità fisiche o oggetti, modelli previsionali, e modelli gestionali al fine di migliorare la progettazione e la programmazione della gestione della città e delle sue risorse." | |
"93","Motori termici","14","Veicoli a basso impatto ambientale","1","Il sistema di trasporto terrestre e navale in Europa è ancora prevalentemente basato sull’uso di motori termici. Previsioni al 2050 indicano inoltre ancora una massiccia presenza di tale tipo di propulsore nel sistema. Tale tema pertanto è focalizzato principalmente su linee di ricerca relative al miglioramento dell’efficienza energetica, della sicurezza, dell’affidabilità, del comfort, nonché alla riduzione dell’impatto ambientale dei propulsori termici. Diretti riferimenti specifici sono contenuti nel programma H2020-MG-2016-2017, in particolare alla GV-01-2017 (Optimisation of heavy duty vehicles for alternative fuels use), GV-02-2016 (Technologies for low emission light duty powertrains), GV-03-2016 (System and cost optimised hybridisation of road vehicles), GV-09-2017 (Aerodynamic and flexible trucks), GV-10-2017 (Demonstration for integration of electrified L-category vehicles), GV-11-2016 (Stimulating European research and development for the implementation of future road transport technologies), Horizon prize for the cleanest engine retrofit, Horizon prize for the cleanest engine of the future." | |
"105","Motori elettrici epropulsione ibrida","14","Veicoli a basso impatto ambientale","2","La sostituzione dei tradizionali motori termici con propulsori a zero o quasi-zero emissioni è uno degli obiettivi cruciali alla base del programma di ricerca H2020. Veicoli elettrici ed a celle a combustibile sono già in produzione, ma con costi, autonomia ed affidabilità ancora non competitivi con i motori tradizionali. Attività di ricerca sono quanto mai necessarie per incrementare efficienza (tramite il recupero delle energie dissipate e la riduzione del peso) ed autonomia (batterie), riducendo allo stesso tempo i costi di produzione ed esercizio nel lungo periodo. Simultaneamente, al fine di realizzare veicoli elettrici sempre più efficienti e a basso consumo di energia, dovranno essere adottate specifiche metodologie di progettazione e sviluppo, prevalentemente incentrate sulla funzionalità della componentistica in uso reale del veicolo; esempi di obiettivi di progettazione mirata all’utenza sono il miglioramento ed ottimizzazione del condizionamento di bordo, della rumorosità e del comfort generale, fattori fortemente condizionanti l'efficienza e l'autonomia del veicolo.Riferimenti diretti sono contenuti nel programma H2020-MG-2016-2017: ad es. GV-04-2017: Next generation electric drivetrains for fully electric vehicles, focusing on high efficiency and low cost, GV-05-2017: Electric vehicle user-centric design for optimised energy efficiency, GV-06-2017: Physical integration of hybrid and electric vehicle batteries at pack level aiming at increased energy density and efficiency." | |
"114","Infrastrutture intelligenti e trasporto ferroviario intelligente","14","Veicoli a basso impatto ambientale","3","I sistemi di trasporto intelligenti (Intelligent Transport System - ITS) sono la chiave per raggiungere la visione del trasporto senza soluzione di continuità sia in passeggeri e nel trasporti merci. ITS è anche uno degli elementi essenziali per far sì che la mobilità sia un servizio efficiente nella realtà, collegando tutti gli elementi multimodali -passeggeri, merci, veicoli, tecnologie e infrastrutture dell'informazione e della comunicazione, ecc. formando così un importante blocco di trasporto integrato digitale. Per i passeggeri, il trasporto senza soluzione di continuità tra diverse modalità e nei vari paesi permetterà di soddisfare al meglio le loro esigenze, sfruttando al meglio le risorse esistenti e riducendo il loro impatto ambientale. Specifici riferimenti nel programma H2020 si possono trovare in MG-6.1-2016: Innovative concepts, systems and services towards 'mobility as a service', MG-7.2-2017: Optimisation of transport infrastructure including terminals." | |
"115","Tematiche di impattoambientale per il trasporto marittimo","14","Veicoli a basso impatto ambientale","4","L'Europa è leader mondiale nella progettazione, produzione e gestione dei mezzi navali. Per fronteggiare una concorrenza globale sempre maggiore, è necessario sviluppare concetti e soluzioni ingegneristiche avanzate, nuovi materiali e metodi di produzione adeguati per una consegna più rapida. E' necessaria quindi l'implementazione di soluzioni dalla ricerca e l'innovazione che hanno vantaggi economici tangibili, mentre allo stesso tempo, vi è la necessità di esplorare nuove frontiere in termini di concetti di nave ed uso sostenibile delle risorse oceaniche. Riferimenti specifici in H2020 sono: MG-2.1-2017- Innovations for energy efficiency and emission control in waterborne transport, MG-2.2-2016-Development, production and use of high performance and lightweight materials for vessels and equipment, MG-2.3-2016-New and improved transport concepts in waterborne transport." | |
"50","IMPATTO AMBIENTALE ","15","Tecnologie Marittime","1","Questo tema si propone di studiare l'impatto delle attività marittime sull'ambiente marino sotto diversi punti di vista (meccanico, acustico, chimico ecc), sia in condizioni di normale operatività, sia in condizioni di eccezionalità (sversamenti di inquinanti, contaminazioni diffuse ecc), sviluppando modelli descrittivi dei fenomeni coinvolti e strategie di contenimento della segnatura antropica." | |
"51","MONITORAGGIO DELL'AMBIENTE MARINO E COSTIERO","15","Tecnologie Marittime","2","Il monitoraggio dell'ambiente marino e costiero è teso ad approntare metodologie e strumenti per la sorveglianza e lo studio del mare, che vanno dal progetto di mezzi di superficie e subacquei dedicati che costituiscono le piattaforme di misura sino allo sviluppo di particolari tecniche di rilievo di alcuni parametri." | |
"52","SISTEMI PER LA PROPULSIONE NAVALE E LA GENERAZIONE DI ENERGIA A BORDO","15","Tecnologie Marittime","3","Tale tema coinvolge lo sviluppo di motori e sistemi per la propulsione navale e la generazione dell'energia a bordo delle navi, con particolare riferimento all'incremento dell'efficienza energetica e alla riduzione dell'impatto ambientale, anche attraverso l'utilizzo di nuovi carburanti e di motori di nuova concezione." | |
"53","TECNOLOGIE NAVALI E OFFSHORE","15","Tecnologie Marittime","4","Questo tema affronta lo sviluppo delle tecnologie che sono alla base della realizzazione di navi e strutture offshore, sia in termini di strumenti progettuali e di analisi avanzata, sia in termini di sistemi esperti di supporto alla navigazione e di gestione del ciclo di vita di queste strutture, con un attenzione particolare all'efficienza e all'affidabilità." | |
"54","GESTIONE DEI PROCESSI DEL SISTEMA MARITTIMO ","15","Tecnologie Marittime","5","Questo tema si propone di studiare diversi aspetti legati alla gestione dei processi del sistema marittimo, quali ad esempio la mobilità marittima ed il soccorso in mare, secondo un approccio basato sulla raccolta di informazioni da una pluralità di fonti, il trattamento in tempo reale mediante sofisticate infrastrutture di rete e di calcolo, e l'analisi di queste in modo da poter essere disponibili ad una pluralità di soggetti." | |
"61","Advancing active and healthy ageing","17","Healthcare and Well-Being","1","Per poter raggiungere obiettivi di allungamento delle prospettive di vita, sia in termini di salute che di indipendenza, mantenendo un alto livello di qualità della vita, si definiscono in questo tema varie soluzioni ICT avanzate e personalizzate, con particolare riferimento a soggetti anziani, con disabilità e a rischio di fragilità o declino cognitivo, fisico e motorio. Tali soluzioni sono progettate per permettere alle persone la permanenza più a lungo possibile presso il proprio domicilio, in modo indipendente, minimizzando i tempi di eventuali ospedalizzazioni, utilizzando sistemi di monitoraggio e riabilitazione domiciliare, contrastando sedentarietà e cattiva alimentazione e favorendo l’inclusione sociale. " | |
"62","Integrated, sustainable, citizen-centred care","17","Healthcare and Well-Being","2","Questo tema ha come target di riferimento l’intera popolazione. Infatti, si ricercano soluzioni ICT avanzate per la gestione e il monitoraggio anche remoto delle condizioni di salute e benessere sia di soggetti sani che malati, al fine di prevenire l’insorgere di possibili patologie, fornire strumenti e dati per una diagnosi precoce, definire una medicina personalizzata per soggetti affetti da varie patologie e comorbidità, e stimolare l’empowerment del cittadino/paziente per una gestione autonoma e proattiva del proprio stato di salute. Il tema si divide tra soluzioni atte a favorire integrazione clinica, sociale e domotica per favorire un processo di cura integrato e continuativo, e soluzioni per la gestione autonoma ed il mantenimento del proprio stato di salute. " | |
"63","Improving health information and dataexploitation","17","Healthcare and Well-Being","3","Il tema di ricerca include soluzioni ICT avanzate per l’elaborazione di dati, segnali e immagini relativi ai pazienti a supporto di esigenze cliniche e biomediche, al fine di favorire comprensione e prevenzione di patologie e realizzare terapie personalizzate, per l’integrazione di informazioni sanitarie e servizi di e-health a livello regionale, nazionale e europeo, garantendo l’interoperabilità tecnica, semantica, funzionale ed organizzativa e politiche di sicurezza e privacy nella comunicazione e accesso a dati sanitari." | |
"64","Tools, technologies and devices for advanced diagnosisand therapies","17","Healthcare and Well-Being","4","Il tema è molto ampio ed abbraccia vari aspetti che fanno riferimento alla bioingegneria e alla progettazione e sviluppo di nuove tecnologie e dispositivi biomedicali. In particolare, in questo tema sono incluse le attività di interesse dei ricercatori del dipartimento in riferimento a tre particolari sottotemi: diagnostica point-of-care, ingegneria dei tessuti e dispositivi impiantabili. Nel settore dei dispositivi per applicazioni biomedicali, risulta sempre più crescente la richiesta da parte dei medici dei dispositivi “Point of Care Testing” (POCT) in grado di effettuare vicino al letto del paziente, in ambulanza o presso il medico di famiglia, misure veloci ed affidabili di parametri chimici e biochimici tali da permettere la formulazione di una diagnosi rapida e affidabile e/o la scelta della terapia più idonea, evitando di ricorrere alle analisi di laboratori centralizzati e di attendere alcune ore e talvolta un’intera giornata per ottenere i risultati. L’ingegneria dei tessuti rappresenta anch’essa un settore in continua evoluzione per la sostituzione o rigenerazione dei tessuti non più funzionali, oltre alla progettazione e sviluppo di nuovi dispositivi impiantabili ed ingegnerizzati ad hoc per terapie e/o monitoraggio." | |
"65","EMF for Health: Medical Applications,Environmental and Occupational Safety, Risk Assessment","17","Healthcare and Well-Being","5","Sono ormai innumerevoli le applicazioni dei campi elettrici, magnetici ed elettromagnetici in ambito biomedicale. Essi sono attualmente impiegati in numerosi approcci in ambito diagnostico, terapeutico e riabilitavo e nuove tecnologie e metodiche sono in corso di sviluppo. Si pensi all’evoluzione della risonanza magnetica, alle applicazioni in oncologia e oncologia chirurgica, al controllo e attivazione di nanoparticelle magnetiche per la manipolazione cellulare e il “drug delivery”. In tale ambito, non deve essere trascurato l’aspetto legato ai possibili effetti biologici derivanti dall’impiego di tali radiazioni non ionizzanti.In ambito CNR, svariati gruppi di ricerca sono impegnati su temi, quali (a) l’impiego di tecniche non invasive a microonde, elettrochemioterapia e ipertermia, in ambito oncologico, (b) l’uso della stimolazione cerebrale elettrica e magnetica, in neurofisiologia; (c) il controllo e l’attivazione di nanoparticelle magnetiche in ambito diagnostico e terapeutico (mediatori ipertermici, mezzi di contrasto, “drug-delivery”). Inoltre, vengono anche valutate l’esposizione umana e gli effetti biologici eventualmente indotti in vitro, con tecniche sia computazionali sia sperimentali. Questo tema si suddivide attualmente in due sottotemi focalizzati sullo studio ed utilizzo di EMF in medicina (sia in ambito diagnostico che terapeutico) e sulla misura dell’esposizione umana a tali campi ed i rischi collegati." | |
"47","Tecnologie per la digitalizzazione ed il monitoraggio ","18","Tecnologie per la Fruizione e Salvaguardia dei Beni Culturali","1","Nel settore delle tecnologie per la digitalizzazione ed il monitoraggio dei BBCC il CNR vanta una pluriennale consolidata esperienza a livello nazionale e internazionale in diversi settori, tra cui quelli delle tecniche avanzate di imaging 2D, delle tecnologie di digitalizzazione 3D, delle tecniche di acquisizione della riflettanza delle superfici e dei sistemi di sensing elettromagnetico per lo studio e scoperta di siti archeologici e beni monumentali. Inoltre, forte impulso è stato dato allo sviluppo di metodologie per l’elaborazione dei dati rilevati, di procedure per allineamento dati iperspettrali 2D e loro studio mediante analisi multivariata, e per la ricostruzione di modelli 3D. Applicazioni innovative per l'esplorazione archeologica sottomarina sono state sviluppate anche in funzione di evidenziare cambiamenti nel fondale e rilevare azioni di saccheggio. Notevole importanza riveste la componente di modellistica matematica e simulazione dei fenomeni di degrado su varie superfici o delle condizioni statiche di edifici. Infine, l’attività di ricerca di questi anni ha portato alla realizzazione archivi digitali e spettrali UV-Vis-IR-THz-GHz di materiali tradizionali e contemporanei impiegati in campo artistico e conservativo, allo sviluppo di tecnologia “watermarking” per la protezione dei diritti di proprietà su immagini, oltre a tecnologie per il restauro di filmati e immagini e per la sorveglianza e salvaguardia di siti archeologici." | |
"48","Tecnologie per la virtualizzazione e la fruizione digitale ","18","Tecnologie per la Fruizione e Salvaguardia dei Beni Culturali","2","Il tema delle tecnologie per la virtualizzazione e la fruizione e’ uno dei temi portanti della AP. In tale contesto il CNR ha una esperienza piu’ che ventennale e viene percepito come uno dei leader internazionali. Il tema include: le tecnologie di base per la presentazione interattiva efficiente di modelli digitali (2D, 3D) su piattaforme differenziate (locale, web o dispositivi mobili); le metodologie per la gestione della localizzazione spaziale ed il riconoscimento di points of interest; le tecnologie per la realta’ virtuale o aumentata; le metodologie per la realizzazione di applicazioni orientate alla fruizione ed al turismo; le tecnologie semantic web per la valorizzazione del patrimonio culturale (annotazione lessicale, sintattica e semantica di testi e immagini, ricerca semantica, social media); ed infine gli strumenti di analisi (analisi e classificazione di manufatti 3D/2D basati su similarità di forma, motori di ricerca, modellazione del comportamento strutturale di edifici storici ed analisi di degrado). Obiettivo di tali metodologie e’ sia di garantire la fruizione generalizzata (musei virtuali, turismo, didattica), che fornire funzionalita’ e strumenti digitali di supporto alle attivita’ di analisi e studio degli esperti o di conservazione e restauro." | |
"49","Gestione del territorio ","18","Tecnologie per la Fruizione e Salvaguardia dei Beni Culturali","3","Il tema riguarda le attività di ricerca e sviluppo con riferimento al monitoraggio ed alla gestione del territorio, che rappresenta un elemento cruciale nella pianificazione deli interventi per la gestione sostenibile e protezione dei beni culturali. In tale contesto, l’obiettivo principale è la mitigazione dei rischi naturali ed antropici che il territorio può generare rispetto ai beni culturali. Si pensi ad esempio al rischio idrogeologico, a quello sismico, agli eventi climatici estremi e alla pressione antropica, legata al fatto che i siti e i monumenti sono vicini o in aree urbane. Va inoltre considerato la problematica dei “cascading effects”, di particolare interesse nelle situazioni di crisi. La possibile risposta tecnologica rispetto allo scenario sopra descritto risiede nello sviluppo di un approccio sistemico, dove il fattore abilitante è l’integrazione di diverse macro-componenti quali:- Sistemi per il monitoraggio multi scala (spaziale e temporale) basati sull’integrazione di tecnologie osservative da satellite, da aereo (droni) e in situ per l’analisi del territorio e dei siti;- Metodologie e strategie per l’analisi e il trattamento di dati spaziali georiferiti, a supporto della conoscenza dei sistemi urbani e territoriali (analisi spaziali, change detection, pattern recognition,..)- Sistemi per l’integrazione e la restituzione di informazioni per la gestione e il supporto della pianificazione degli interventi sul territorio" | |
"82","Fight Against Crime and Terrorism","19","Sicurezza della Società","2","Una delle aree prioritarie di interesse per la sicurezza è la lotta al crimine e al terrorismo “fight against crime and terrorism”. Questo tema copre tutte le attività che vanno dallo sviluppo di nuove metodologie forensi alle attività di protezione contro gli esplosivi.L'interesse di questo tema è posto sull’attenzione ad attenuare potenziali conseguenze di incidenti o, meglio, ad evitarli. Ciò richiede nuove tecnologie e funzionalità per combattere e prevenire la criminalità (compresa la criminalità informatica), il traffico illegale e terrorismo (compreso il cyber-terrorismo). Questo richiede un’aumentata comprensione e capacità di affrontare gli sviluppi e i modi operandi del terrorismo, nel rispetto dei diritti umani e della privacy. Il crimine organizzato e le organizzazioni terroristiche sono spesso in prima linea nella innovazione tecnologica, nella pianificazione ed esecuzione delle proprie attività criminali, spesso nascondendo le entrate derivanti da queste. Le Forze dell'Ordine sono spesso in ritardo quando affrontano attività criminali supportate da tecnologie \"avanzate\"." | |
"83","Border Security and External Security","19","Sicurezza della Società","3","Il tema 3 si focalizza su tre principali sotto-temi. Il primo riguarda la sicurezza dei confini marittimi, dove l’enfasi è posta su due aspetti. Il primo riguarda lo sviluppo di piattaforme robotiche e droni per l’esplorazione di ambienti ignoti, il monitoraggio ambientale, la protezione di aree costiere e portuali. Il secondo riguarda lo sviluppo di sistemi radar attivi e passivi, allocati su diverse piattaforme osservative (satellite, aereo, droni, in-situ) per la detection e tracking di bersagli (natanti non cooperanti) ed il monitoraggio dello stato del mare. Il secondo sottotema riguarda il problema della sicurezza nell’attraversamento dei confini e/o in luoghi pubblici e/o per l’accesso ad aree limitate; in tale ambito, vengono sviluppate tecnche di modellazione analisi per il riconoscimento facciale da scansioni laser, integrate con informazioni biometriche. Infine, attenzione è posta allo sviluppo di nuovi sistemi di indagine di valigie o container basati su raggi X mediante l’uso di detectors spettroscopici." | |
"84","Ethical Societal Dimension and SocialSecurity ","19","Sicurezza della Società","4","Le tematiche della salute e della sicurezza del lavoro hanno come beneficiario finale il cittadino, e si inseriscono nel contesto più ampio della \"Dimensione sociale della Sicurezza\". Le attività del CNR sono basate su metodologie innovative, sia strumentali che computazionali, per la valutazione dell'esposizione e sullo sviluppo di modelli e di sistemi di supporto alle decisioni per la sicurezza occupazionale." | |
"85","Disaster Resilience: safeguarding and securingsociety, including adapting to climate change ","19","Sicurezza della Società","1","Questo tema mira al miglioramento della resilienza della società contro le catastrofi naturali e/o provocate dall'uomo. Le attività in cui si articola riguardano lo sviluppo di nuovi strumenti per la previsione e gestione delle crisi, l'interoperabilità delle comunicazioni degli enti istituzionali coinvolti, l'addestramento del loro personale e lo sviluppo di soluzioni innovative per la protezione delle infrastrutture critiche. In particolare la prevenzione, previsione, pianificazione e gestione delle emergenze si basano su metodi e strumenti per simulazioni ad alta definizione, elaborazione di segnali, modellazione di immagini e dati geo-spaziali eterogenei, analisi con approcci stocastici e metodi per l'interoperabilità dei sistemi radio-mobili dei mezzi di soccorso e delle forze dell'ordine basati sulle diverse tecnologie PMR (incluso LTE). Queste attività sono supportate dall’impiego di moderne ed efficienti tecnologie di osservazione e di rilevamento multi-sensing e multi-scala, di sensori in-situ (radar, sensori in fibra ottica, SWIR e TIR, Lidar, Lidar a fluorescenza), di sensori chimici di gas e in liquido, e raggi X. Tra i principali campi di applicazione si annoverano la previsione di eventi idrometeorologici estremi, il monitoraggio e la modellazione di eventi naturali (frane, incendi, terremoti), di infrastrutture di trasporto, discariche e idrocarburi in mare, la sorveglianza e tutela di beni e complessi culturali, inclusi i luoghi di interesse non presidiati." | |
"124"," Privacy","20","CyberSecurity","1","description" | |
"125","Cloud security ","20","CyberSecurity","2","L'attività di ricerca condotta per il tema Cloud Security concerne lo studio dei problemi di sicurezza relativi ai sistemi Cloud e alle Federazioni di sistemi Cloud. In particolare, vengono studiate le tecniche applicabili per mitigare tali problemi come, ad esempio, Identity Management e meccanismi di autenticazione, meccanismi per il controllo degli accessi ed il controllo dell'utilizzo (usage control) dei servizi, delle risorse e dei dati, aspetti di sicurezza della virtualizzazione in ambienti multi-tennant, aspetti di Privacy dei dati, ed aspetti di Compliance.L’attività di ricerca comprende anche lo studio dei rischi e delle problematiche di sicurezza relativi all'adozione di sistemi Cloud nell'ambito della Pubblica Amministrazione, ad esempio per la gestione del Fascicolo Sanitario Elettronico del cittadino." | |
"126","Information sharing and Analytics ","20","CyberSecurity","3","L’attività di ricerca è finalizzata allo studio ed allo sviluppo di metodi, tecniche, modelli e tecnologie per la definizione di politiche di comprehensive security. L'idea è di riconsiderare gli approcci alla gestione delle informazioni e dei dati in un contesto in cui tali approcci sono adoperati per la tutela da rischi. La nozione di rischio che ci interessa analizzare attiene a diversi livelli: rischi derivanti dagli attuali progressi nel settore del networking, rischi connessi alle infrastrutture stradali e dei trasporti, rischi derivanti da azioni terroristici, e rischi derivanti dall'accesso ad applicazioni e dati sensibili. In particolare ci si propone in particolare di studiare ed integrare varie metodologie di analisi dei dati, e allo studio di problematiche relative alla realizzazione di infrastrutture software che permettano di definire criteri adatti ad applicazioni di Homeland Security, Safety nelle infrastrutture pubbliche, Sicurezza informatica e protezione di dati sensibili garantendone l'integrità, la riservatezza e la disponibilità." | |
"127","Secure Software Assurance","20","CyberSecurity","4","Nell’ambito dei sistemi ICT è sempre più presente l’utilizzo di sistemi a servizi e meccanismi di autorizzazione degli accessi. La presenza di possibili errori o imprecisioni nell’implementazione o nell’ applicazione di questi sistemi può dare origine a gravi problemi, come ad esempio l’autorizzazione di accessi che dovrebbero essere negati, mettendo a repentaglio la sicurezza dell’intero sistema. Dato il ruolo cruciale di questi sistemi è fondamentale che essi vengano sottoposti, sia nelle fasi di sviluppo che di utilizzo, ad accurato processo di validazione che possa garantire il livello di sicurezza richiesto. Nell’ambito di questa tematica di ricerca saranno sviluppate le seguenti sottotematiche." | |
"128","Modelli formali per la cyber security di sistemicyber physical (industriali, SCADA, etc.)","20","CyberSecurity","5","Questo tema di ricerca nasce dalla constatazione che esiste un vasto universo di sistemi distribuiti che, da un lato, mutuano dalle tradizionali reti di ufficio le problematiche di cyber security ma che, dall’altro, per vincoli prestazionali (comunicazioni e schedulazione real-time), limitazioni dei dispositivi utilizzati (limitati nella potenza di calcolo, nel consumo di energia e spesso progettati senza attenzioni per le problematiche di sicurezza) e stretta connessione della security con la safety, e quindi cyber attack potenzialmente più pericolosi, richiedono specifiche attenzioni e precauzioni nella gestione della sicurezza e dei suoi meccanismi." | |
"129","Crittografia ","20","CyberSecurity","6","Negli ultimi anni si è assistito al proliferare di proposte in ambito crittografico per la soluzione dei problemi di sicurezza continuamente posti dalle nuove tecnologie, spesso con esiti controversi, a causa una scarsa applicabilità pratica o dell'inadeguatezza dei modelli di minaccia presi in considerazione rispetto ai contesti d'uso reale. L'impiego della crittografia nei sistemi reali è notoriamente difficile, sia per la complessità di individuare e caratterizzare tutte le possibili le minacce e di scegliere o progettare i meccanismi crittografici adeguati a contrastarle, che per la necessità di utilizzare primitive e protocolli che offrano efficienza e scalabilità adeguate. A ciò si aggiunga il fatto che l'implementazione sia in hardware che in software dei meccanismi richiede attenzione e competenze specifiche, che esulano dalle tecniche della semplice programmazione; prova ne sia per tutte il caso recente di Heartbleed. Obiettivo di questa area tematica è quello di offrire supporto e know-how a progetti ed attività in tema di sicurezza cibernetica, attraverso la progettazione, l'implementazione e l'integrazione in sistemi, infrastutture o servizi di meccanismi e protocolli crittografici innovativi o di tipo avanzato." | |
"130","Digital forensic ","20","CyberSecurity","7","La digital forensic affronta ed estende le problematiche relative alla investigazione forense finalizzata alla analisi del dato informatico e assume rilevanza non solo negli ambiti processuali civili e penali, o nelle indagini aziendali interne, ma anche nei contesti più generali della tutela delle informazioni, del data recovery e della analisi delle informazioni. Nell’ambito della tematica di Digital forensic vengono svolte attività legate sia alla system forensic, relativa alle tecniche e agli strumenti per l’esame dei sistemi informatici a fini probatori, che alla social and Internet forensic, con un focus specifico sulle reti e sulle infrastrutture ‘social’ OSN (Online Social Networks), oltre che sui contenuti live presenti su Internet. Queste attività sono finalizzate alla profilazione degli utenti, al supporto di attività di predizione di eventi legati a fenomeni quali orientamenti politici/culturali, intenzioni di voto, o spostamenti di persone. Analogamente, vengono svolte delle attività di analisi e navigazione automatizzata in sistemi di reti peer-to-peer per attività di tutela della proprietà intellettuale o di contrasto alla diffusione di materiale illecitoLe attività e le metodologie legate a questo tema sono state sperimentate sul campo, nell’ambito procedimenti giudiziari con varie Procure. " | |
"131","Sicurezza dei dispositivi mobili (Mobile Security) ","20","CyberSecurity","8","Questa tematica di ricerca è volta ad analizzare le problematiche di sicurezza delle tecnologie ed architetture utilizzate all’interno dei dispositivi mobili (smartphone, tablet, sensori, nodi della Internet of Things). In maggior dettaglio, l’attività si concentra sui framework di sicurezza utilizzati nei moderni OS di tipo mobile (virtual machine, hypervisors, …) con lo scopo di rilevare vulnerabilità e colli di bottiglia prestazionali, al fine di definire soluzioni innovative alle problematiche riscontrate. Inoltre, l’utilizzo sempre crescente dei dispositivi mobili per applicazioni di tipo social, e nell’ambito del paradigma Bring Your Own Device (BYOD), impone la soluzione di diverse problematiche di privacy e di accesso selettivo ai dati. Questo aspetto è inoltre importante perché può dare vita a diversi attacchi basati su “social engineering” a partire da dati molto dettagliati e raccolti su vasta scala. " | |
"132","Sicurezza delle applicazioni e dei sistemi","20","CyberSecurity","9","Questa attività si pone l’obiettivo di affrontare le problematiche legate alla sicurezza dei sistemi e delle applicazioni, intese sia nel senso più letterale del termine, ovvero i software applicativi in esecuzione sugli elaboratori elettronici che, soprattutto, secondo il concetto più ampio di ‘sistema informativo’ e quindi dell’integrazione delle varie componenti funzionali che realizzano un’infrastruttura complessa. La considerazione alla base di questo approccio è legata all’evidenza ormai consolidata che le problematiche di sicurezza non possano essere affrontate per elementi indipendenti (rete, server, applicativi, etc) ma vadano affrontate in un’ottica integrata, con un approccio che sia in grado di governare anche le interazioni tra i vari elementi funzionali, incluso il ruolo degli utenti e delle policy d’uso. L’approccio alla problematica passa quindi attraverso una fase iniziale di definizione e modellazione dei potenziali rischi (threat modelling) e una successiva di implementazione e monitoraggio dei meccanismi in grado di mitigarli o annullarli. Oltre alla definizione di modelli e strumenti per la sicurezza dei sistemi informativi, questa tematica si occupa anche delle tecniche e degli strumenti per il security and vulnerability assessment, intesa come la ricerca di vulnerabilità attraverso metodologie di penetration testing e social engineering." | |
"133","Trusted e-services e controllo accessi","20","CyberSecurity","10","Questa attivita’ riguarda lo sviluppo di servizi per la gestione della fiducia (trust in sistemi ICT) e del controllo accessi. In particulare, riguarda sia lo sviluppo di modelli di trust, sia linguaggi per esprimere politiche di trust management, che servizi per la gestione della trust, inclusi quelli di certificazione di aspetti di sicurezza dei sistemi. Questo tema riguarda lo studio di meccanismi per il controllo degli accessi e dell’uso a sistemi ICT. Si tratta di sviluppare sia meccanismi e protocolli avanzati di autenticazione (che siano anche privacy-aware) che di linguaggi e sistemi di autorizzazione. " | |
"134","CyberIntelligence ","20","CyberSecurity","11","L’attività di ricerca, particolarmente attiva negli ultimi tempi, ha come obiettivo lo studio di metodologie e strumenti integrate di recupero e analisi di dati da fonti Web (Visible e Dark Web), in particolare social media, che siano utili in azioni di intelligence volte alla prevenzione e a tutela della società. Considerati i volumi di dati coinvolti, la velocità e la varietà con cui questi dati vengono prodotti, le attività di ricerca in questa tematica sono riconducibili al mondo Big Data. Attraverso queste tecniche è possibile monitorare il tessuto sociale, individuare anomalie o casi che deviino in modo pericoloso verso episodi di natura violenta come terrorismo, vandalismo, razzismo, bullismo e comportamenti che arrechino comunque danno a cose o persone, ed intervenire tempestivamente. Sono parte di questo studio anche le tematiche e le relative limitazioni legate alle specifiche esigenze di contesti di Open Source Intelligence, nei quali cioè, il punto di partenza sono i dati disponibili solo su fonti pubblicamente accessibili." | |
"135","Network Security ","20","CyberSecurity","12","Il tema tratta la sicurezza delle reti e dei dispositivi mobili. In particolare, verrà trattato il tema delle comunicazioni di rete in un ampio spettro che comprende l’utilizzo di connessioni sicure (VPN, wireless, …), sistemi e tecnologie di monitoraggio della rete, protezione perimetrale (IPS, IDS, firewall, tecnologie anti intercettazione). In congiunzione con le attività di analisi della rete verrà trattata la sicurezza dei dispositivi connessi alla rete (vulnerability assessment)." | |
"136","Cyberattacks","20","CyberSecurity","13","Il tema tratta lo studio e sviluppo degli strumenti di attacchi informatici e relative contromisure. Verranno studiati in particolare sia minacce eseguite con lo scopo di creare un danno diretto all’utente (malware, trojan horses), sia minacce in grado di danneggiare l’utente in modo indiretto (denial of service attacks, DoS, con particolare riferimento a slow DoS, amplification, reflection, flood). Inoltre, verranno approfondite le tecniche di attacchi distribuiti(botnet per utilizzo con malware e DDoS) e tecniche utilizzate per il furto di dati sensibili(data exfiltration).Inoltre verranno studiate le metodologie di penetration testing e sviluppati innovativi strumenti di attacco, con conseguente progettazione di algoritmi di intrusion detection in grado di proteggere un sistema da tali minacce (anomaly detection)." | |
"137","Risk management for cyber security","20","CyberSecurity","14","description" | |
"138","Impiego delle tecnologiebiometriche nel contesto della cyber security (Istituti coinvolti: IBB,IIT)","20","CyberSecurity","15","Il tema proposto concerne in maniera molto specifica la gestione dell’identità che, come è noto, rappresenta una capability fondamentale per la cyber security. Le tecnologie biometriche la cui missione è il riconoscimento degli individui o la verifica dell’identità degli stessi sulla base di caratteristiche fisiche e/o comportamentali rappresentano quindi un elemento fondamentale nei sistemi orientati alla cyber security con specifico riferimento, ad esempio, alla mitigazione dei tentativi di cyber crime. Va comunque messo in chiara evidenza che l’impiego delle tecnologie biometriche implica una attenta considerazione di vari fattori importanti che, comunque rilevanti per qualsiasi contesto applicativo, possono diventare cruciali nel particolarmente critico ambito della cyber security. Ad esempio, vanno attentamente considerate le possibili vulnerabilità dei sistemi biometrici che potrebbero divenire essi stessi anelli deboli della catena della sicurezza. In seconda analisi non andrebbero sottovalutati gli aspetti legali etici e sociali correlati all’uso delle biometriche. Nonostante il crescente e globalizzato clima di incertezza geopolitica e parallela richiesta generalizzata di incremento delle misure di sicurezza, forti pregiudiziali vengono ancora poste da più parti ad un uso più capillare delle tecnologie biometriche. Uno studio quindi dei fattori inibitori, razionali e, in taluni casi decisamente irrazionali, diventa pressoché indispensabile nel disegno di un sistema biometrico inserito un contesto di sicurezza allargato alla cyber security.Non andrebbero infine tralasciati gli aspetti relativi alla accessibilità e alla standardizzazione, talora sottovalutati ma ormai ritenuti unanimemente focali nel disegno di sistemi di sicurezza che includono l’uso delle tecnologie biometriche. Nell’ambito della tematica proposta saranno sviluppate le seguenti sottotematiche:" | |
"41","La Neutral Beam Test Facility a Padova","21","Fusione Termonucleare","1","Progettazione, realizzazione, test e ottimizzazione del prototipo di iniettore di neutri per ITER: la Neutral Beam Test Facility (NBTF) è in via di completamento presso l’Area di Ricerca CNR di Padova e sono iniziate le installazioni dei componenti europei e giapponesi. La NBTF ha lo scopo di effettuare tutti i test necessari alla successiva costruzione dei due iniettori di neutri (NBI) previsti per ITER, di essere di supporto alle operazioni di ITER, di ottimizzare le prestazioni e la componentistica degli iniettori allo scopo di poterne installare un terzo su ITER (IGI) e di contribuire agli sviluppi per l’NBI per DEMO." | |
"42","Il sistema di riscaldamento a radiofrequenza di ITER","21","Fusione Termonucleare","2","Progettazione, ottimizzazione e realizzazione del sistema di riscaldamento a radiofrequenza (RF), basato sull’uso delle onde di ciclotrone elettroniche (ECRH), per ITER. Studi di fisica delle onde di ciclotrone per l’ottimizzazione degli angoli di lancio e della combinazione dei diversi fasci di radiazione emessi dai lanciatori equatoriale e superiore previsti per ITER. Nell’ambito dello sviluppo della sorgente gyrotron europea di onde di ciclotrone per ITER, sviluppo, ottimizzazione e costruzione dei carichi adattati bolometrici per la dissipazione di onde millimetriche di potenza." | |
"43","Progettazione e realizzazione di diagnostiche per ITER","21","Fusione Termonucleare","3","Nell’ambito del Work Programme di F4E si progettano diverse diagnostiche avanzate di plasmi da fusione:- sonde magnetiche per misurare il campo magnetico in ITER con sonde “in-vessel” al fine di ricostruire l’equilibrio e consentire il controllo attivo della configurazione magnetica (IGI);- sistema laser per misure di profilo di temperatura elettronica (IGI);- sistema di riflettometria per determinare la posizione del plasma di ITER (IFP);- spettroscopia a raggi gamma nell’ambito della progettazione della radial neutron camera (IFP);- High Resolution Neutron Spectroscopy (IFP)." | |
"44","Il Broader Approach","21","Fusione Termonucleare","4","Nell’ambito dell’accordo bilaterale Europa-Giappone “Broader Approach”, è previsto che IGI tramite Consorzio RFX ha realizzato per l’esperimento giapponese JT60-SA le alimentazioni dei circuiti di protezione del sistema di magneti superconduttori e sta completando le alimentazioni per le bobine “in-vessel” per il controllo delle instabilità Resistive Wall Mode." | |
"45","Programma europeo sulla fusione","21","Fusione Termonucleare","5","Partecipazione alle attività di R&D nel quadro di H2020-EURATOM e co-finanziato dalla Commissione Europea tramite Grant EJP \"Implementation of activities described in the Roadmap to Fusion during Horizon-2020 through a Joint programme of the members of the EUROfusion consortium\". l’IFP e il Consorzio RFX vi partecipano come linked Third Party dell’ENEA, membro italiano del Consorzio EUROfusion, beneficiario del Grant Agreement." | |
"36","Modellistica e Calcolo Scientifico","22","Matematica Applicata","1","Questo tema si concentra sulla modellizzazione e sulla simulazione di fenomeni complessi, procedendo a vari livelli: dalla derivazione del modello matematico, alla sua analisi, alla sua risoluzione numerica con lo sviluppo di algoritmi accurati ed efficienti fino alla loro implementazione su moderni sistemi di calcolo. L’attività svolta nell’ambito di questo tema riguarda in particolare: Modellistica matematica, differenziale, cinetica; Meccanica dei continui; Equazioni differenziali alle derivate parziali, Equazioni integrali; Calcolo delle variazioni; Problemi inversi, Regolarizzazione; Calcolo tensoriale; Soluzione numerica di equazioni alle derivate parziali, Fluidodinamica e Meccanica computazionali; Teoria dell'approssimazione; Algebra lineare numerica; Trattamento numerico della geometria; Grafica computazionale, Topologia computazionale; Modelli di sistemi dinamici non lineari, multiscala; Informatica matematica, Algoritmica, Librerie numeriche, Calcolo parallelo e distribuito; Calcolo ad alte prestazioni; Teoria dei sistemi. Le numerose applicazioni trattate includono: Aeronautica e Nautica, Biologia e Medicina, Elaborazione ed analisi di Immagini, Fisica, Beni culturali, Ambiente, Materiali avanzati, Smart mobility, Sistemi di produzione, Sicurezza e protezione dei dati (Cyber-security)." | |
"37","Teoria dei sistemi e dei controlli ","22","Matematica Applicata","4","Il tema si concentra sullo studio della teoria di controllo, osservazione dello stato ed ottimizzazione, con particolare attenzione alla analisi di sistemi incerti e complessi.Controllo, stima dello stato ed ottimizzazione per sistemi lineari e nonlineari svolgono un ruolo essenziale nello studio dei processi e sono fondamentali per l’incremento dell’efficienza. I sistemi considerati possono essere a tempo continuo o discreto, a parametri concentrati o distribuiti. In generale, le strategie di controllo e stima dello stato messe a punto devono garantire robustezza, stabilità, accuratezza, ottimalità ed essere computazionalmente efficienti. Questi sistemi includono applicazioni in settori classici dell’ingegneria, come quello aerospaziale, chimico, elettrico e meccanico, insieme a nuove aree di ricerca quali economia, sistemi biologici, scienze sociali e reti. Le attività di ricerca principali e più significative svolte nell’ambito di questo tema si focalizzano su: metodi computazionali per i sistemi dinamici; analisi e design di sistemi distribuiti ed interconnessi; networked control systems; algoritmi randomizzati e metodi probabilistici; cyberphysical systems; sistemi di sistemi; controllo e stima distribuita; consensus over networks; sistemi multiagente; opinion dynamics; controllo dell'incertezza, sistemi nonlineari e complessi; controllo robusto e nonlineare; sliding mode; misure di centralità in reti complesse; trattamento di segnali e immagini; filtraggio non lineare." | |
"38","Ottimizzazione e matematica discreta ","22","Matematica Applicata","3","Il tema dell'Ottimizzazione riguarda un'ampia varietà di problemi che presentano un numero estremamente elevato di scenari descritti da un insieme di variabili. Ad ogni scenario è associato un indice di qualità (o di costo). L'Ottimizzazione consiste nell'individuare lo scenario con il massimo indice di qualità (o con il minimo indice di costo). Solitamente i valori che le variabili possono assumere sono soggetti a vincoli, ovvero a limitazioni di varia natura. Per il numero generalmente alto delle variabili e per la complessità derivante dai vincoli, la soluzione dei problemi di ottimizzazione può presentare notevoli difficoltà e richiedere metodi molto sofisticati. Di particolare interesse sono i problemi in cui alcune o tutte le variabili possono assumere solo valori discreti. Perciò i metodi dell'Ottimizzazione spesso interagiscono con la Matematica Discreta, che si occupa dell'analisi e della costruzione di strutture discrete, ovvero di insiemi con particolari proprietà composti da un numero finito di elementi, quali per esempio i grafi o le reti.Moltissimi sono i contesti applicativi: analisi di dati, analisi delle reti sociali, Fisica Statistica, Medicina, Bioinformatica, organizzazione aziendale, traffico urbano, trasporti, progetto di sistemi informativi e di comunicazione, smart-grids, Economia, Finanza, sistemi elettorali, produzione e distribuzione di energia, produzione industriale, logistica, agricoltura e trasformazione alimentare, affidabilità di sistemi." | |
"39","Modellistica stocastica e analisi di dati ","22","Matematica Applicata","2","Questo tema si concentra sullo studio e lo sviluppo di metodi di apprendimento da dati rappresentativi di un fenomeno affetto da incertezza. Esprimendo tale incertezza in forma probabilistica, i metodi stocastici permettono di quantificare, controllare e comunicare l’incertezza e, grazie anche allo sviluppo di algoritmi efficienti, di fornire inferenza e previsione. L’attività svolta nell’ambito di questo tema riguarda in particolare: Modellazione stocastica e inferenza statistica; modellistica ed inferenza per equazioni differenziali stocastiche; Sistemi dinamici stocastici; Probabilità applicata; Analisi di dati; Apprendimento statistico; Metodologie Bayesiane; Modellazione, identificazione e stima di sistemi; Affidabilità e manutenibilità. Numerose le applicazioni in settori quali: Ambiente, Biologia, Biomedicina, Climatologia, Ecologia, Energia, Finanza, Genomica, Reti di comunicazioni, Sanità, Settore industriale, Sismologia, Trasporti." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment