{"version":3,"sources":["node_modules/typeahead.js/dist/typeahead.bundle.js","node_modules/@visualeyes/bootstrap-tokenfield/dist/bootstrap-tokenfield.js","areas/admin/Scripts/forms/chTypeAhead.js","areas/admin/Scripts/forms/chCheckboxModal.js","areas/admin/Scripts/forms/chServiceSubmit.js","areas/admin/Scripts/forms/chTimeSpan.js","areas/admin/Scripts/forms/chToggleAccordion.js","areas/admin/Scripts/forms/chTokenField.js","areas/admin/Scripts/forms/chTokenModal.js","areas/admin/Scripts/forms/dataInitialisation.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACl5EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC9gCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACvjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACrNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACzIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"forms.js","sourcesContent":["/*!\n * typeahead.js 0.11.1\n * https://github.com/twitter/typeahead.js\n * Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT\n */\n\n(function(root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define(\"bloodhound\", [ \"jquery\" ], function(a0) {\n return root[\"Bloodhound\"] = factory(a0);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(require(\"jquery\"));\n } else {\n root[\"Bloodhound\"] = factory(jQuery);\n }\n})(this, function($) {\n var _ = function() {\n \"use strict\";\n return {\n isMsie: function() {\n return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\\d+(.\\d+)?)/i)[2] : false;\n },\n isBlankString: function(str) {\n return !str || /^\\s*$/.test(str);\n },\n escapeRegExChars: function(str) {\n return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\");\n },\n isString: function(obj) {\n return typeof obj === \"string\";\n },\n isNumber: function(obj) {\n return typeof obj === \"number\";\n },\n isArray: $.isArray,\n isFunction: $.isFunction,\n isObject: $.isPlainObject,\n isUndefined: function(obj) {\n return typeof obj === \"undefined\";\n },\n isElement: function(obj) {\n return !!(obj && obj.nodeType === 1);\n },\n isJQuery: function(obj) {\n return obj instanceof $;\n },\n toStr: function toStr(s) {\n return _.isUndefined(s) || s === null ? \"\" : s + \"\";\n },\n bind: $.proxy,\n each: function(collection, cb) {\n $.each(collection, reverseArgs);\n function reverseArgs(index, value) {\n return cb(value, index);\n }\n },\n map: $.map,\n filter: $.grep,\n every: function(obj, test) {\n var result = true;\n if (!obj) {\n return result;\n }\n $.each(obj, function(key, val) {\n if (!(result = test.call(null, val, key, obj))) {\n return false;\n }\n });\n return !!result;\n },\n some: function(obj, test) {\n var result = false;\n if (!obj) {\n return result;\n }\n $.each(obj, function(key, val) {\n if (result = test.call(null, val, key, obj)) {\n return false;\n }\n });\n return !!result;\n },\n mixin: $.extend,\n identity: function(x) {\n return x;\n },\n clone: function(obj) {\n return $.extend(true, {}, obj);\n },\n getIdGenerator: function() {\n var counter = 0;\n return function() {\n return counter++;\n };\n },\n templatify: function templatify(obj) {\n return $.isFunction(obj) ? obj : template;\n function template() {\n return String(obj);\n }\n },\n defer: function(fn) {\n setTimeout(fn, 0);\n },\n debounce: function(func, wait, immediate) {\n var timeout, result;\n return function() {\n var context = this, args = arguments, later, callNow;\n later = function() {\n timeout = null;\n if (!immediate) {\n result = func.apply(context, args);\n }\n };\n callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n result = func.apply(context, args);\n }\n return result;\n };\n },\n throttle: function(func, wait) {\n var context, args, timeout, result, previous, later;\n previous = 0;\n later = function() {\n previous = new Date();\n timeout = null;\n result = func.apply(context, args);\n };\n return function() {\n var now = new Date(), remaining = wait - (now - previous);\n context = this;\n args = arguments;\n if (remaining <= 0) {\n clearTimeout(timeout);\n timeout = null;\n previous = now;\n result = func.apply(context, args);\n } else if (!timeout) {\n timeout = setTimeout(later, remaining);\n }\n return result;\n };\n },\n stringify: function(val) {\n return _.isString(val) ? val : JSON.stringify(val);\n },\n noop: function() {}\n };\n }();\n var VERSION = \"0.11.1\";\n var tokenizers = function() {\n \"use strict\";\n return {\n nonword: nonword,\n whitespace: whitespace,\n obj: {\n nonword: getObjTokenizer(nonword),\n whitespace: getObjTokenizer(whitespace)\n }\n };\n function whitespace(str) {\n str = _.toStr(str);\n return str ? str.split(/\\s+/) : [];\n }\n function nonword(str) {\n str = _.toStr(str);\n return str ? str.split(/\\W+/) : [];\n }\n function getObjTokenizer(tokenizer) {\n return function setKey(keys) {\n keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);\n return function tokenize(o) {\n var tokens = [];\n _.each(keys, function(k) {\n tokens = tokens.concat(tokenizer(_.toStr(o[k])));\n });\n return tokens;\n };\n };\n }\n }();\n var LruCache = function() {\n \"use strict\";\n function LruCache(maxSize) {\n this.maxSize = _.isNumber(maxSize) ? maxSize : 100;\n this.reset();\n if (this.maxSize <= 0) {\n this.set = this.get = $.noop;\n }\n }\n _.mixin(LruCache.prototype, {\n set: function set(key, val) {\n var tailItem = this.list.tail, node;\n if (this.size >= this.maxSize) {\n this.list.remove(tailItem);\n delete this.hash[tailItem.key];\n this.size--;\n }\n if (node = this.hash[key]) {\n node.val = val;\n this.list.moveToFront(node);\n } else {\n node = new Node(key, val);\n this.list.add(node);\n this.hash[key] = node;\n this.size++;\n }\n },\n get: function get(key) {\n var node = this.hash[key];\n if (node) {\n this.list.moveToFront(node);\n return node.val;\n }\n },\n reset: function reset() {\n this.size = 0;\n this.hash = {};\n this.list = new List();\n }\n });\n function List() {\n this.head = this.tail = null;\n }\n _.mixin(List.prototype, {\n add: function add(node) {\n if (this.head) {\n node.next = this.head;\n this.head.prev = node;\n }\n this.head = node;\n this.tail = this.tail || node;\n },\n remove: function remove(node) {\n node.prev ? node.prev.next = node.next : this.head = node.next;\n node.next ? node.next.prev = node.prev : this.tail = node.prev;\n },\n moveToFront: function(node) {\n this.remove(node);\n this.add(node);\n }\n });\n function Node(key, val) {\n this.key = key;\n this.val = val;\n this.prev = this.next = null;\n }\n return LruCache;\n }();\n var PersistentStorage = function() {\n \"use strict\";\n var LOCAL_STORAGE;\n try {\n LOCAL_STORAGE = window.localStorage;\n LOCAL_STORAGE.setItem(\"~~~\", \"!\");\n LOCAL_STORAGE.removeItem(\"~~~\");\n } catch (err) {\n LOCAL_STORAGE = null;\n }\n function PersistentStorage(namespace, override) {\n this.prefix = [ \"__\", namespace, \"__\" ].join(\"\");\n this.ttlKey = \"__ttl__\";\n this.keyMatcher = new RegExp(\"^\" + _.escapeRegExChars(this.prefix));\n this.ls = override || LOCAL_STORAGE;\n !this.ls && this._noop();\n }\n _.mixin(PersistentStorage.prototype, {\n _prefix: function(key) {\n return this.prefix + key;\n },\n _ttlKey: function(key) {\n return this._prefix(key) + this.ttlKey;\n },\n _noop: function() {\n this.get = this.set = this.remove = this.clear = this.isExpired = _.noop;\n },\n _safeSet: function(key, val) {\n try {\n this.ls.setItem(key, val);\n } catch (err) {\n if (err.name === \"QuotaExceededError\") {\n this.clear();\n this._noop();\n }\n }\n },\n get: function(key) {\n if (this.isExpired(key)) {\n this.remove(key);\n }\n return decode(this.ls.getItem(this._prefix(key)));\n },\n set: function(key, val, ttl) {\n if (_.isNumber(ttl)) {\n this._safeSet(this._ttlKey(key), encode(now() + ttl));\n } else {\n this.ls.removeItem(this._ttlKey(key));\n }\n return this._safeSet(this._prefix(key), encode(val));\n },\n remove: function(key) {\n this.ls.removeItem(this._ttlKey(key));\n this.ls.removeItem(this._prefix(key));\n return this;\n },\n clear: function() {\n var i, keys = gatherMatchingKeys(this.keyMatcher);\n for (i = keys.length; i--; ) {\n this.remove(keys[i]);\n }\n return this;\n },\n isExpired: function(key) {\n var ttl = decode(this.ls.getItem(this._ttlKey(key)));\n return _.isNumber(ttl) && now() > ttl ? true : false;\n }\n });\n return PersistentStorage;\n function now() {\n return new Date().getTime();\n }\n function encode(val) {\n return JSON.stringify(_.isUndefined(val) ? null : val);\n }\n function decode(val) {\n return $.parseJSON(val);\n }\n function gatherMatchingKeys(keyMatcher) {\n var i, key, keys = [], len = LOCAL_STORAGE.length;\n for (i = 0; i < len; i++) {\n if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) {\n keys.push(key.replace(keyMatcher, \"\"));\n }\n }\n return keys;\n }\n }();\n var Transport = function() {\n \"use strict\";\n var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10);\n function Transport(o) {\n o = o || {};\n this.cancelled = false;\n this.lastReq = null;\n this._send = o.transport;\n this._get = o.limiter ? o.limiter(this._get) : this._get;\n this._cache = o.cache === false ? new LruCache(0) : sharedCache;\n }\n Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {\n maxPendingRequests = num;\n };\n Transport.resetCache = function resetCache() {\n sharedCache.reset();\n };\n _.mixin(Transport.prototype, {\n _fingerprint: function fingerprint(o) {\n o = o || {};\n return o.url + o.type + $.param(o.data || {});\n },\n _get: function(o, cb) {\n var that = this, fingerprint, jqXhr;\n fingerprint = this._fingerprint(o);\n if (this.cancelled || fingerprint !== this.lastReq) {\n return;\n }\n if (jqXhr = pendingRequests[fingerprint]) {\n jqXhr.done(done).fail(fail);\n } else if (pendingRequestsCount < maxPendingRequests) {\n pendingRequestsCount++;\n pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);\n } else {\n this.onDeckRequestArgs = [].slice.call(arguments, 0);\n }\n function done(resp) {\n cb(null, resp);\n that._cache.set(fingerprint, resp);\n }\n function fail() {\n cb(true);\n }\n function always() {\n pendingRequestsCount--;\n delete pendingRequests[fingerprint];\n if (that.onDeckRequestArgs) {\n that._get.apply(that, that.onDeckRequestArgs);\n that.onDeckRequestArgs = null;\n }\n }\n },\n get: function(o, cb) {\n var resp, fingerprint;\n cb = cb || $.noop;\n o = _.isString(o) ? {\n url: o\n } : o || {};\n fingerprint = this._fingerprint(o);\n this.cancelled = false;\n this.lastReq = fingerprint;\n if (resp = this._cache.get(fingerprint)) {\n cb(null, resp);\n } else {\n this._get(o, cb);\n }\n },\n cancel: function() {\n this.cancelled = true;\n }\n });\n return Transport;\n }();\n var SearchIndex = window.SearchIndex = function() {\n \"use strict\";\n var CHILDREN = \"c\", IDS = \"i\";\n function SearchIndex(o) {\n o = o || {};\n if (!o.datumTokenizer || !o.queryTokenizer) {\n $.error(\"datumTokenizer and queryTokenizer are both required\");\n }\n this.identify = o.identify || _.stringify;\n this.datumTokenizer = o.datumTokenizer;\n this.queryTokenizer = o.queryTokenizer;\n this.reset();\n }\n _.mixin(SearchIndex.prototype, {\n bootstrap: function bootstrap(o) {\n this.datums = o.datums;\n this.trie = o.trie;\n },\n add: function(data) {\n var that = this;\n data = _.isArray(data) ? data : [ data ];\n _.each(data, function(datum) {\n var id, tokens;\n that.datums[id = that.identify(datum)] = datum;\n tokens = normalizeTokens(that.datumTokenizer(datum));\n _.each(tokens, function(token) {\n var node, chars, ch;\n node = that.trie;\n chars = token.split(\"\");\n while (ch = chars.shift()) {\n node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode());\n node[IDS].push(id);\n }\n });\n });\n },\n get: function get(ids) {\n var that = this;\n return _.map(ids, function(id) {\n return that.datums[id];\n });\n },\n search: function search(query) {\n var that = this, tokens, matches;\n tokens = normalizeTokens(this.queryTokenizer(query));\n _.each(tokens, function(token) {\n var node, chars, ch, ids;\n if (matches && matches.length === 0) {\n return false;\n }\n node = that.trie;\n chars = token.split(\"\");\n while (node && (ch = chars.shift())) {\n node = node[CHILDREN][ch];\n }\n if (node && chars.length === 0) {\n ids = node[IDS].slice(0);\n matches = matches ? getIntersection(matches, ids) : ids;\n } else {\n matches = [];\n return false;\n }\n });\n return matches ? _.map(unique(matches), function(id) {\n return that.datums[id];\n }) : [];\n },\n all: function all() {\n var values = [];\n for (var key in this.datums) {\n values.push(this.datums[key]);\n }\n return values;\n },\n reset: function reset() {\n this.datums = {};\n this.trie = newNode();\n },\n serialize: function serialize() {\n return {\n datums: this.datums,\n trie: this.trie\n };\n }\n });\n return SearchIndex;\n function normalizeTokens(tokens) {\n tokens = _.filter(tokens, function(token) {\n return !!token;\n });\n tokens = _.map(tokens, function(token) {\n return token.toLowerCase();\n });\n return tokens;\n }\n function newNode() {\n var node = {};\n node[IDS] = [];\n node[CHILDREN] = {};\n return node;\n }\n function unique(array) {\n var seen = {}, uniques = [];\n for (var i = 0, len = array.length; i < len; i++) {\n if (!seen[array[i]]) {\n seen[array[i]] = true;\n uniques.push(array[i]);\n }\n }\n return uniques;\n }\n function getIntersection(arrayA, arrayB) {\n var ai = 0, bi = 0, intersection = [];\n arrayA = arrayA.sort();\n arrayB = arrayB.sort();\n var lenArrayA = arrayA.length, lenArrayB = arrayB.length;\n while (ai < lenArrayA && bi < lenArrayB) {\n if (arrayA[ai] < arrayB[bi]) {\n ai++;\n } else if (arrayA[ai] > arrayB[bi]) {\n bi++;\n } else {\n intersection.push(arrayA[ai]);\n ai++;\n bi++;\n }\n }\n return intersection;\n }\n }();\n var Prefetch = function() {\n \"use strict\";\n var keys;\n keys = {\n data: \"data\",\n protocol: \"protocol\",\n thumbprint: \"thumbprint\"\n };\n function Prefetch(o) {\n this.url = o.url;\n this.ttl = o.ttl;\n this.cache = o.cache;\n this.prepare = o.prepare;\n this.transform = o.transform;\n this.transport = o.transport;\n this.thumbprint = o.thumbprint;\n this.storage = new PersistentStorage(o.cacheKey);\n }\n _.mixin(Prefetch.prototype, {\n _settings: function settings() {\n return {\n url: this.url,\n type: \"GET\",\n dataType: \"json\"\n };\n },\n store: function store(data) {\n if (!this.cache) {\n return;\n }\n this.storage.set(keys.data, data, this.ttl);\n this.storage.set(keys.protocol, location.protocol, this.ttl);\n this.storage.set(keys.thumbprint, this.thumbprint, this.ttl);\n },\n fromCache: function fromCache() {\n var stored = {}, isExpired;\n if (!this.cache) {\n return null;\n }\n stored.data = this.storage.get(keys.data);\n stored.protocol = this.storage.get(keys.protocol);\n stored.thumbprint = this.storage.get(keys.thumbprint);\n isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol;\n return stored.data && !isExpired ? stored.data : null;\n },\n fromNetwork: function(cb) {\n var that = this, settings;\n if (!cb) {\n return;\n }\n settings = this.prepare(this._settings());\n this.transport(settings).fail(onError).done(onResponse);\n function onError() {\n cb(true);\n }\n function onResponse(resp) {\n cb(null, that.transform(resp));\n }\n },\n clear: function clear() {\n this.storage.clear();\n return this;\n }\n });\n return Prefetch;\n }();\n var Remote = function() {\n \"use strict\";\n function Remote(o) {\n this.url = o.url;\n this.prepare = o.prepare;\n this.transform = o.transform;\n this.transport = new Transport({\n cache: o.cache,\n limiter: o.limiter,\n transport: o.transport\n });\n }\n _.mixin(Remote.prototype, {\n _settings: function settings() {\n return {\n url: this.url,\n type: \"GET\",\n dataType: \"json\"\n };\n },\n get: function get(query, cb) {\n var that = this, settings;\n if (!cb) {\n return;\n }\n query = query || \"\";\n settings = this.prepare(query, this._settings());\n return this.transport.get(settings, onResponse);\n function onResponse(err, resp) {\n err ? cb([]) : cb(that.transform(resp));\n }\n },\n cancelLastRequest: function cancelLastRequest() {\n this.transport.cancel();\n }\n });\n return Remote;\n }();\n var oParser = function() {\n \"use strict\";\n return function parse(o) {\n var defaults, sorter;\n defaults = {\n initialize: true,\n identify: _.stringify,\n datumTokenizer: null,\n queryTokenizer: null,\n sufficient: 5,\n sorter: null,\n local: [],\n prefetch: null,\n remote: null\n };\n o = _.mixin(defaults, o || {});\n !o.datumTokenizer && $.error(\"datumTokenizer is required\");\n !o.queryTokenizer && $.error(\"queryTokenizer is required\");\n sorter = o.sorter;\n o.sorter = sorter ? function(x) {\n return x.sort(sorter);\n } : _.identity;\n o.local = _.isFunction(o.local) ? o.local() : o.local;\n o.prefetch = parsePrefetch(o.prefetch);\n o.remote = parseRemote(o.remote);\n return o;\n };\n function parsePrefetch(o) {\n var defaults;\n if (!o) {\n return null;\n }\n defaults = {\n url: null,\n ttl: 24 * 60 * 60 * 1e3,\n cache: true,\n cacheKey: null,\n thumbprint: \"\",\n prepare: _.identity,\n transform: _.identity,\n transport: null\n };\n o = _.isString(o) ? {\n url: o\n } : o;\n o = _.mixin(defaults, o);\n !o.url && $.error(\"prefetch requires url to be set\");\n o.transform = o.filter || o.transform;\n o.cacheKey = o.cacheKey || o.url;\n o.thumbprint = VERSION + o.thumbprint;\n o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;\n return o;\n }\n function parseRemote(o) {\n var defaults;\n if (!o) {\n return;\n }\n defaults = {\n url: null,\n cache: true,\n prepare: null,\n replace: null,\n wildcard: null,\n limiter: null,\n rateLimitBy: \"debounce\",\n rateLimitWait: 300,\n transform: _.identity,\n transport: null\n };\n o = _.isString(o) ? {\n url: o\n } : o;\n o = _.mixin(defaults, o);\n !o.url && $.error(\"remote requires url to be set\");\n o.transform = o.filter || o.transform;\n o.prepare = toRemotePrepare(o);\n o.limiter = toLimiter(o);\n o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;\n delete o.replace;\n delete o.wildcard;\n delete o.rateLimitBy;\n delete o.rateLimitWait;\n return o;\n }\n function toRemotePrepare(o) {\n var prepare, replace, wildcard;\n prepare = o.prepare;\n replace = o.replace;\n wildcard = o.wildcard;\n if (prepare) {\n return prepare;\n }\n if (replace) {\n prepare = prepareByReplace;\n } else if (o.wildcard) {\n prepare = prepareByWildcard;\n } else {\n prepare = idenityPrepare;\n }\n return prepare;\n function prepareByReplace(query, settings) {\n settings.url = replace(settings.url, query);\n return settings;\n }\n function prepareByWildcard(query, settings) {\n settings.url = settings.url.replace(wildcard, encodeURIComponent(query));\n return settings;\n }\n function idenityPrepare(query, settings) {\n return settings;\n }\n }\n function toLimiter(o) {\n var limiter, method, wait;\n limiter = o.limiter;\n method = o.rateLimitBy;\n wait = o.rateLimitWait;\n if (!limiter) {\n limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait);\n }\n return limiter;\n function debounce(wait) {\n return function debounce(fn) {\n return _.debounce(fn, wait);\n };\n }\n function throttle(wait) {\n return function throttle(fn) {\n return _.throttle(fn, wait);\n };\n }\n }\n function callbackToDeferred(fn) {\n return function wrapper(o) {\n var deferred = $.Deferred();\n fn(o, onSuccess, onError);\n return deferred;\n function onSuccess(resp) {\n _.defer(function() {\n deferred.resolve(resp);\n });\n }\n function onError(err) {\n _.defer(function() {\n deferred.reject(err);\n });\n }\n };\n }\n }();\n var Bloodhound = function() {\n \"use strict\";\n var old;\n old = window && window.Bloodhound;\n function Bloodhound(o) {\n o = oParser(o);\n this.sorter = o.sorter;\n this.identify = o.identify;\n this.sufficient = o.sufficient;\n this.local = o.local;\n this.remote = o.remote ? new Remote(o.remote) : null;\n this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;\n this.index = new SearchIndex({\n identify: this.identify,\n datumTokenizer: o.datumTokenizer,\n queryTokenizer: o.queryTokenizer\n });\n o.initialize !== false && this.initialize();\n }\n Bloodhound.noConflict = function noConflict() {\n window && (window.Bloodhound = old);\n return Bloodhound;\n };\n Bloodhound.tokenizers = tokenizers;\n _.mixin(Bloodhound.prototype, {\n __ttAdapter: function ttAdapter() {\n var that = this;\n return this.remote ? withAsync : withoutAsync;\n function withAsync(query, sync, async) {\n return that.search(query, sync, async);\n }\n function withoutAsync(query, sync) {\n return that.search(query, sync);\n }\n },\n _loadPrefetch: function loadPrefetch() {\n var that = this, deferred, serialized;\n deferred = $.Deferred();\n if (!this.prefetch) {\n deferred.resolve();\n } else if (serialized = this.prefetch.fromCache()) {\n this.index.bootstrap(serialized);\n deferred.resolve();\n } else {\n this.prefetch.fromNetwork(done);\n }\n return deferred.promise();\n function done(err, data) {\n if (err) {\n return deferred.reject();\n }\n that.add(data);\n that.prefetch.store(that.index.serialize());\n deferred.resolve();\n }\n },\n _initialize: function initialize() {\n var that = this, deferred;\n this.clear();\n (this.initPromise = this._loadPrefetch()).done(addLocalToIndex);\n return this.initPromise;\n function addLocalToIndex() {\n that.add(that.local);\n }\n },\n initialize: function initialize(force) {\n return !this.initPromise || force ? this._initialize() : this.initPromise;\n },\n add: function add(data) {\n this.index.add(data);\n return this;\n },\n get: function get(ids) {\n ids = _.isArray(ids) ? ids : [].slice.call(arguments);\n return this.index.get(ids);\n },\n search: function search(query, sync, async) {\n var that = this, local;\n local = this.sorter(this.index.search(query));\n sync(this.remote ? local.slice() : local);\n if (this.remote && local.length < this.sufficient) {\n this.remote.get(query, processRemote);\n } else if (this.remote) {\n this.remote.cancelLastRequest();\n }\n return this;\n function processRemote(remote) {\n var nonDuplicates = [];\n _.each(remote, function(r) {\n !_.some(local, function(l) {\n return that.identify(r) === that.identify(l);\n }) && nonDuplicates.push(r);\n });\n async && async(nonDuplicates);\n }\n },\n all: function all() {\n return this.index.all();\n },\n clear: function clear() {\n this.index.reset();\n return this;\n },\n clearPrefetchCache: function clearPrefetchCache() {\n this.prefetch && this.prefetch.clear();\n return this;\n },\n clearRemoteCache: function clearRemoteCache() {\n Transport.resetCache();\n return this;\n },\n ttAdapter: function ttAdapter() {\n return this.__ttAdapter();\n }\n });\n return Bloodhound;\n }();\n return Bloodhound;\n});\n\n(function(root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define(\"typeahead.js\", [ \"jquery\" ], function(a0) {\n return factory(a0);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(require(\"jquery\"));\n } else {\n factory(jQuery);\n }\n})(this, function($) {\n var _ = function() {\n \"use strict\";\n return {\n isMsie: function() {\n return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\\d+(.\\d+)?)/i)[2] : false;\n },\n isBlankString: function(str) {\n return !str || /^\\s*$/.test(str);\n },\n escapeRegExChars: function(str) {\n return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\");\n },\n isString: function(obj) {\n return typeof obj === \"string\";\n },\n isNumber: function(obj) {\n return typeof obj === \"number\";\n },\n isArray: $.isArray,\n isFunction: $.isFunction,\n isObject: $.isPlainObject,\n isUndefined: function(obj) {\n return typeof obj === \"undefined\";\n },\n isElement: function(obj) {\n return !!(obj && obj.nodeType === 1);\n },\n isJQuery: function(obj) {\n return obj instanceof $;\n },\n toStr: function toStr(s) {\n return _.isUndefined(s) || s === null ? \"\" : s + \"\";\n },\n bind: $.proxy,\n each: function(collection, cb) {\n $.each(collection, reverseArgs);\n function reverseArgs(index, value) {\n return cb(value, index);\n }\n },\n map: $.map,\n filter: $.grep,\n every: function(obj, test) {\n var result = true;\n if (!obj) {\n return result;\n }\n $.each(obj, function(key, val) {\n if (!(result = test.call(null, val, key, obj))) {\n return false;\n }\n });\n return !!result;\n },\n some: function(obj, test) {\n var result = false;\n if (!obj) {\n return result;\n }\n $.each(obj, function(key, val) {\n if (result = test.call(null, val, key, obj)) {\n return false;\n }\n });\n return !!result;\n },\n mixin: $.extend,\n identity: function(x) {\n return x;\n },\n clone: function(obj) {\n return $.extend(true, {}, obj);\n },\n getIdGenerator: function() {\n var counter = 0;\n return function() {\n return counter++;\n };\n },\n templatify: function templatify(obj) {\n return $.isFunction(obj) ? obj : template;\n function template() {\n return String(obj);\n }\n },\n defer: function(fn) {\n setTimeout(fn, 0);\n },\n debounce: function(func, wait, immediate) {\n var timeout, result;\n return function() {\n var context = this, args = arguments, later, callNow;\n later = function() {\n timeout = null;\n if (!immediate) {\n result = func.apply(context, args);\n }\n };\n callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) {\n result = func.apply(context, args);\n }\n return result;\n };\n },\n throttle: function(func, wait) {\n var context, args, timeout, result, previous, later;\n previous = 0;\n later = function() {\n previous = new Date();\n timeout = null;\n result = func.apply(context, args);\n };\n return function() {\n var now = new Date(), remaining = wait - (now - previous);\n context = this;\n args = arguments;\n if (remaining <= 0) {\n clearTimeout(timeout);\n timeout = null;\n previous = now;\n result = func.apply(context, args);\n } else if (!timeout) {\n timeout = setTimeout(later, remaining);\n }\n return result;\n };\n },\n stringify: function(val) {\n return _.isString(val) ? val : JSON.stringify(val);\n },\n noop: function() {}\n };\n }();\n var WWW = function() {\n \"use strict\";\n var defaultClassNames = {\n wrapper: \"twitter-typeahead\",\n input: \"tt-input\",\n hint: \"tt-hint\",\n menu: \"tt-menu\",\n dataset: \"tt-dataset\",\n suggestion: \"tt-suggestion\",\n selectable: \"tt-selectable\",\n empty: \"tt-empty\",\n open: \"tt-open\",\n cursor: \"tt-cursor\",\n highlight: \"tt-highlight\"\n };\n return build;\n function build(o) {\n var www, classes;\n classes = _.mixin({}, defaultClassNames, o);\n www = {\n css: buildCss(),\n classes: classes,\n html: buildHtml(classes),\n selectors: buildSelectors(classes)\n };\n return {\n css: www.css,\n html: www.html,\n classes: www.classes,\n selectors: www.selectors,\n mixin: function(o) {\n _.mixin(o, www);\n }\n };\n }\n function buildHtml(c) {\n return {\n wrapper: '',\n menu: '
'\n };\n }\n function buildSelectors(classes) {\n var selectors = {};\n _.each(classes, function(v, k) {\n selectors[k] = \".\" + v;\n });\n return selectors;\n }\n function buildCss() {\n var css = {\n wrapper: {\n position: \"relative\",\n display: \"inline-block\"\n },\n hint: {\n position: \"absolute\",\n top: \"0\",\n left: \"0\",\n borderColor: \"transparent\",\n boxShadow: \"none\",\n opacity: \"1\"\n },\n input: {\n position: \"relative\",\n verticalAlign: \"top\",\n backgroundColor: \"transparent\"\n },\n inputWithNoHint: {\n position: \"relative\",\n verticalAlign: \"top\"\n },\n menu: {\n position: \"absolute\",\n top: \"100%\",\n left: \"0\",\n zIndex: \"100\",\n display: \"none\"\n },\n ltr: {\n left: \"0\",\n right: \"auto\"\n },\n rtl: {\n left: \"auto\",\n right: \" 0\"\n }\n };\n if (_.isMsie()) {\n _.mixin(css.input, {\n backgroundImage: \"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)\"\n });\n }\n return css;\n }\n }();\n var EventBus = function() {\n \"use strict\";\n var namespace, deprecationMap;\n namespace = \"typeahead:\";\n deprecationMap = {\n render: \"rendered\",\n cursorchange: \"cursorchanged\",\n select: \"selected\",\n autocomplete: \"autocompleted\"\n };\n function EventBus(o) {\n if (!o || !o.el) {\n $.error(\"EventBus initialized without el\");\n }\n this.$el = $(o.el);\n }\n _.mixin(EventBus.prototype, {\n _trigger: function(type, args) {\n var $e;\n $e = $.Event(namespace + type);\n (args = args || []).unshift($e);\n this.$el.trigger.apply(this.$el, args);\n return $e;\n },\n before: function(type) {\n var args, $e;\n args = [].slice.call(arguments, 1);\n $e = this._trigger(\"before\" + type, args);\n return $e.isDefaultPrevented();\n },\n trigger: function(type) {\n var deprecatedType;\n this._trigger(type, [].slice.call(arguments, 1));\n if (deprecatedType = deprecationMap[type]) {\n this._trigger(deprecatedType, [].slice.call(arguments, 1));\n }\n }\n });\n return EventBus;\n }();\n var EventEmitter = function() {\n \"use strict\";\n var splitter = /\\s+/, nextTick = getNextTick();\n return {\n onSync: onSync,\n onAsync: onAsync,\n off: off,\n trigger: trigger\n };\n function on(method, types, cb, context) {\n var type;\n if (!cb) {\n return this;\n }\n types = types.split(splitter);\n cb = context ? bindContext(cb, context) : cb;\n this._callbacks = this._callbacks || {};\n while (type = types.shift()) {\n this._callbacks[type] = this._callbacks[type] || {\n sync: [],\n async: []\n };\n this._callbacks[type][method].push(cb);\n }\n return this;\n }\n function onAsync(types, cb, context) {\n return on.call(this, \"async\", types, cb, context);\n }\n function onSync(types, cb, context) {\n return on.call(this, \"sync\", types, cb, context);\n }\n function off(types) {\n var type;\n if (!this._callbacks) {\n return this;\n }\n types = types.split(splitter);\n while (type = types.shift()) {\n delete this._callbacks[type];\n }\n return this;\n }\n function trigger(types) {\n var type, callbacks, args, syncFlush, asyncFlush;\n if (!this._callbacks) {\n return this;\n }\n types = types.split(splitter);\n args = [].slice.call(arguments, 1);\n while ((type = types.shift()) && (callbacks = this._callbacks[type])) {\n syncFlush = getFlush(callbacks.sync, this, [ type ].concat(args));\n asyncFlush = getFlush(callbacks.async, this, [ type ].concat(args));\n syncFlush() && nextTick(asyncFlush);\n }\n return this;\n }\n function getFlush(callbacks, context, args) {\n return flush;\n function flush() {\n var cancelled;\n for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) {\n cancelled = callbacks[i].apply(context, args) === false;\n }\n return !cancelled;\n }\n }\n function getNextTick() {\n var nextTickFn;\n if (window.setImmediate) {\n nextTickFn = function nextTickSetImmediate(fn) {\n setImmediate(function() {\n fn();\n });\n };\n } else {\n nextTickFn = function nextTickSetTimeout(fn) {\n setTimeout(function() {\n fn();\n }, 0);\n };\n }\n return nextTickFn;\n }\n function bindContext(fn, context) {\n return fn.bind ? fn.bind(context) : function() {\n fn.apply(context, [].slice.call(arguments, 0));\n };\n }\n }();\n var highlight = function(doc) {\n \"use strict\";\n var defaults = {\n node: null,\n pattern: null,\n tagName: \"strong\",\n className: null,\n wordsOnly: false,\n caseSensitive: false\n };\n return function hightlight(o) {\n var regex;\n o = _.mixin({}, defaults, o);\n if (!o.node || !o.pattern) {\n return;\n }\n o.pattern = _.isArray(o.pattern) ? o.pattern : [ o.pattern ];\n regex = getRegex(o.pattern, o.caseSensitive, o.wordsOnly);\n traverse(o.node, hightlightTextNode);\n function hightlightTextNode(textNode) {\n var match, patternNode, wrapperNode;\n if (match = regex.exec(textNode.data)) {\n wrapperNode = doc.createElement(o.tagName);\n o.className && (wrapperNode.className = o.className);\n patternNode = textNode.splitText(match.index);\n patternNode.splitText(match[0].length);\n wrapperNode.appendChild(patternNode.cloneNode(true));\n textNode.parentNode.replaceChild(wrapperNode, patternNode);\n }\n return !!match;\n }\n function traverse(el, hightlightTextNode) {\n var childNode, TEXT_NODE_TYPE = 3;\n for (var i = 0; i < el.childNodes.length; i++) {\n childNode = el.childNodes[i];\n if (childNode.nodeType === TEXT_NODE_TYPE) {\n i += hightlightTextNode(childNode) ? 1 : 0;\n } else {\n traverse(childNode, hightlightTextNode);\n }\n }\n }\n };\n function getRegex(patterns, caseSensitive, wordsOnly) {\n var escapedPatterns = [], regexStr;\n for (var i = 0, len = patterns.length; i < len; i++) {\n escapedPatterns.push(_.escapeRegExChars(patterns[i]));\n }\n regexStr = wordsOnly ? \"\\\\b(\" + escapedPatterns.join(\"|\") + \")\\\\b\" : \"(\" + escapedPatterns.join(\"|\") + \")\";\n return caseSensitive ? new RegExp(regexStr) : new RegExp(regexStr, \"i\");\n }\n }(window.document);\n var Input = function() {\n \"use strict\";\n var specialKeyCodeMap;\n specialKeyCodeMap = {\n 9: \"tab\",\n 27: \"esc\",\n 37: \"left\",\n 39: \"right\",\n 13: \"enter\",\n 38: \"up\",\n 40: \"down\"\n };\n function Input(o, www) {\n o = o || {};\n if (!o.input) {\n $.error(\"input is missing\");\n }\n www.mixin(this);\n this.$hint = $(o.hint);\n this.$input = $(o.input);\n this.query = this.$input.val();\n this.queryWhenFocused = this.hasFocus() ? this.query : null;\n this.$overflowHelper = buildOverflowHelper(this.$input);\n this._checkLanguageDirection();\n if (this.$hint.length === 0) {\n this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop;\n }\n }\n Input.normalizeQuery = function(str) {\n return _.toStr(str).replace(/^\\s*/g, \"\").replace(/\\s{2,}/g, \" \");\n };\n _.mixin(Input.prototype, EventEmitter, {\n _onBlur: function onBlur() {\n this.resetInputValue();\n this.trigger(\"blurred\");\n },\n _onFocus: function onFocus() {\n this.queryWhenFocused = this.query;\n this.trigger(\"focused\");\n },\n _onKeydown: function onKeydown($e) {\n var keyName = specialKeyCodeMap[$e.which || $e.keyCode];\n this._managePreventDefault(keyName, $e);\n if (keyName && this._shouldTrigger(keyName, $e)) {\n this.trigger(keyName + \"Keyed\", $e);\n }\n },\n _onInput: function onInput() {\n this._setQuery(this.getInputValue());\n this.clearHintIfInvalid();\n this._checkLanguageDirection();\n },\n _managePreventDefault: function managePreventDefault(keyName, $e) {\n var preventDefault;\n switch (keyName) {\n case \"up\":\n case \"down\":\n preventDefault = !withModifier($e);\n break;\n\n default:\n preventDefault = false;\n }\n preventDefault && $e.preventDefault();\n },\n _shouldTrigger: function shouldTrigger(keyName, $e) {\n var trigger;\n switch (keyName) {\n case \"tab\":\n trigger = !withModifier($e);\n break;\n\n default:\n trigger = true;\n }\n return trigger;\n },\n _checkLanguageDirection: function checkLanguageDirection() {\n var dir = (this.$input.css(\"direction\") || \"ltr\").toLowerCase();\n if (this.dir !== dir) {\n this.dir = dir;\n this.$hint.attr(\"dir\", dir);\n this.trigger(\"langDirChanged\", dir);\n }\n },\n _setQuery: function setQuery(val, silent) {\n var areEquivalent, hasDifferentWhitespace;\n areEquivalent = areQueriesEquivalent(val, this.query);\n hasDifferentWhitespace = areEquivalent ? this.query.length !== val.length : false;\n this.query = val;\n if (!silent && !areEquivalent) {\n this.trigger(\"queryChanged\", this.query);\n } else if (!silent && hasDifferentWhitespace) {\n this.trigger(\"whitespaceChanged\", this.query);\n }\n },\n bind: function() {\n var that = this, onBlur, onFocus, onKeydown, onInput;\n onBlur = _.bind(this._onBlur, this);\n onFocus = _.bind(this._onFocus, this);\n onKeydown = _.bind(this._onKeydown, this);\n onInput = _.bind(this._onInput, this);\n this.$input.on(\"blur.tt\", onBlur).on(\"focus.tt\", onFocus).on(\"keydown.tt\", onKeydown);\n if (!_.isMsie() || _.isMsie() > 9) {\n this.$input.on(\"input.tt\", onInput);\n } else {\n this.$input.on(\"keydown.tt keypress.tt cut.tt paste.tt\", function($e) {\n if (specialKeyCodeMap[$e.which || $e.keyCode]) {\n return;\n }\n _.defer(_.bind(that._onInput, that, $e));\n });\n }\n return this;\n },\n focus: function focus() {\n this.$input.focus();\n },\n blur: function blur() {\n this.$input.blur();\n },\n getLangDir: function getLangDir() {\n return this.dir;\n },\n getQuery: function getQuery() {\n return this.query || \"\";\n },\n setQuery: function setQuery(val, silent) {\n this.setInputValue(val);\n this._setQuery(val, silent);\n },\n hasQueryChangedSinceLastFocus: function hasQueryChangedSinceLastFocus() {\n return this.query !== this.queryWhenFocused;\n },\n getInputValue: function getInputValue() {\n return this.$input.val();\n },\n setInputValue: function setInputValue(value) {\n this.$input.val(value);\n this.clearHintIfInvalid();\n this._checkLanguageDirection();\n },\n resetInputValue: function resetInputValue() {\n this.setInputValue(this.query);\n },\n getHint: function getHint() {\n return this.$hint.val();\n },\n setHint: function setHint(value) {\n this.$hint.val(value);\n },\n clearHint: function clearHint() {\n this.setHint(\"\");\n },\n clearHintIfInvalid: function clearHintIfInvalid() {\n var val, hint, valIsPrefixOfHint, isValid;\n val = this.getInputValue();\n hint = this.getHint();\n valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0;\n isValid = val !== \"\" && valIsPrefixOfHint && !this.hasOverflow();\n !isValid && this.clearHint();\n },\n hasFocus: function hasFocus() {\n return this.$input.is(\":focus\");\n },\n hasOverflow: function hasOverflow() {\n var constraint = this.$input.width() - 2;\n this.$overflowHelper.text(this.getInputValue());\n return this.$overflowHelper.width() >= constraint;\n },\n isCursorAtEnd: function() {\n var valueLength, selectionStart, range;\n valueLength = this.$input.val().length;\n selectionStart = this.$input[0].selectionStart;\n if (_.isNumber(selectionStart)) {\n return selectionStart === valueLength;\n } else if (document.selection) {\n range = document.selection.createRange();\n range.moveStart(\"character\", -valueLength);\n return valueLength === range.text.length;\n }\n return true;\n },\n destroy: function destroy() {\n this.$hint.off(\".tt\");\n this.$input.off(\".tt\");\n this.$overflowHelper.remove();\n this.$hint = this.$input = this.$overflowHelper = $(\"
\");\n }\n });\n return Input;\n function buildOverflowHelper($input) {\n return $('
').css({\n                position: \"absolute\",\n                visibility: \"hidden\",\n                whiteSpace: \"pre\",\n                fontFamily: $input.css(\"font-family\"),\n                fontSize: $input.css(\"font-size\"),\n                fontStyle: $input.css(\"font-style\"),\n                fontVariant: $input.css(\"font-variant\"),\n                fontWeight: $input.css(\"font-weight\"),\n                wordSpacing: $input.css(\"word-spacing\"),\n                letterSpacing: $input.css(\"letter-spacing\"),\n                textIndent: $input.css(\"text-indent\"),\n                textRendering: $input.css(\"text-rendering\"),\n                textTransform: $input.css(\"text-transform\")\n            }).insertAfter($input);\n        }\n        function areQueriesEquivalent(a, b) {\n            return Input.normalizeQuery(a) === Input.normalizeQuery(b);\n        }\n        function withModifier($e) {\n            return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey;\n        }\n    }();\n    var Dataset = function() {\n        \"use strict\";\n        var keys, nameGenerator;\n        keys = {\n            val: \"tt-selectable-display\",\n            obj: \"tt-selectable-object\"\n        };\n        nameGenerator = _.getIdGenerator();\n        function Dataset(o, www) {\n            o = o || {};\n            o.templates = o.templates || {};\n            o.templates.notFound = o.templates.notFound || o.templates.empty;\n            if (!o.source) {\n                $.error(\"missing source\");\n            }\n            if (!o.node) {\n                $.error(\"missing node\");\n            }\n            if (o.name && !isValidName(o.name)) {\n                $.error(\"invalid dataset name: \" + o.name);\n            }\n            www.mixin(this);\n            this.highlight = !!o.highlight;\n            this.name = o.name || nameGenerator();\n            this.limit = o.limit || 5;\n            this.displayFn = getDisplayFn(o.display || o.displayKey);\n            this.templates = getTemplates(o.templates, this.displayFn);\n            this.source = o.source.__ttAdapter ? o.source.__ttAdapter() : o.source;\n            this.async = _.isUndefined(o.async) ? this.source.length > 2 : !!o.async;\n            this._resetLastSuggestion();\n            this.$el = $(o.node).addClass(this.classes.dataset).addClass(this.classes.dataset + \"-\" + this.name);\n        }\n        Dataset.extractData = function extractData(el) {\n            var $el = $(el);\n            if ($el.data(keys.obj)) {\n                return {\n                    val: $el.data(keys.val) || \"\",\n                    obj: $el.data(keys.obj) || null\n                };\n            }\n            return null;\n        };\n        _.mixin(Dataset.prototype, EventEmitter, {\n            _overwrite: function overwrite(query, suggestions) {\n                suggestions = suggestions || [];\n                if (suggestions.length) {\n                    this._renderSuggestions(query, suggestions);\n                } else if (this.async && this.templates.pending) {\n                    this._renderPending(query);\n                } else if (!this.async && this.templates.notFound) {\n                    this._renderNotFound(query);\n                } else {\n                    this._empty();\n                }\n                this.trigger(\"rendered\", this.name, suggestions, false);\n            },\n            _append: function append(query, suggestions) {\n                suggestions = suggestions || [];\n                if (suggestions.length && this.$lastSuggestion.length) {\n                    this._appendSuggestions(query, suggestions);\n                } else if (suggestions.length) {\n                    this._renderSuggestions(query, suggestions);\n                } else if (!this.$lastSuggestion.length && this.templates.notFound) {\n                    this._renderNotFound(query);\n                }\n                this.trigger(\"rendered\", this.name, suggestions, true);\n            },\n            _renderSuggestions: function renderSuggestions(query, suggestions) {\n                var $fragment;\n                $fragment = this._getSuggestionsFragment(query, suggestions);\n                this.$lastSuggestion = $fragment.children().last();\n                this.$el.html($fragment).prepend(this._getHeader(query, suggestions)).append(this._getFooter(query, suggestions));\n            },\n            _appendSuggestions: function appendSuggestions(query, suggestions) {\n                var $fragment, $lastSuggestion;\n                $fragment = this._getSuggestionsFragment(query, suggestions);\n                $lastSuggestion = $fragment.children().last();\n                this.$lastSuggestion.after($fragment);\n                this.$lastSuggestion = $lastSuggestion;\n            },\n            _renderPending: function renderPending(query) {\n                var template = this.templates.pending;\n                this._resetLastSuggestion();\n                template && this.$el.html(template({\n                    query: query,\n                    dataset: this.name\n                }));\n            },\n            _renderNotFound: function renderNotFound(query) {\n                var template = this.templates.notFound;\n                this._resetLastSuggestion();\n                template && this.$el.html(template({\n                    query: query,\n                    dataset: this.name\n                }));\n            },\n            _empty: function empty() {\n                this.$el.empty();\n                this._resetLastSuggestion();\n            },\n            _getSuggestionsFragment: function getSuggestionsFragment(query, suggestions) {\n                var that = this, fragment;\n                fragment = document.createDocumentFragment();\n                _.each(suggestions, function getSuggestionNode(suggestion) {\n                    var $el, context;\n                    context = that._injectQuery(query, suggestion);\n                    $el = $(that.templates.suggestion(context)).data(keys.obj, suggestion).data(keys.val, that.displayFn(suggestion)).addClass(that.classes.suggestion + \" \" + that.classes.selectable);\n                    fragment.appendChild($el[0]);\n                });\n                this.highlight && highlight({\n                    className: this.classes.highlight,\n                    node: fragment,\n                    pattern: query\n                });\n                return $(fragment);\n            },\n            _getFooter: function getFooter(query, suggestions) {\n                return this.templates.footer ? this.templates.footer({\n                    query: query,\n                    suggestions: suggestions,\n                    dataset: this.name\n                }) : null;\n            },\n            _getHeader: function getHeader(query, suggestions) {\n                return this.templates.header ? this.templates.header({\n                    query: query,\n                    suggestions: suggestions,\n                    dataset: this.name\n                }) : null;\n            },\n            _resetLastSuggestion: function resetLastSuggestion() {\n                this.$lastSuggestion = $();\n            },\n            _injectQuery: function injectQuery(query, obj) {\n                return _.isObject(obj) ? _.mixin({\n                    _query: query\n                }, obj) : obj;\n            },\n            update: function update(query) {\n                var that = this, canceled = false, syncCalled = false, rendered = 0;\n                this.cancel();\n                this.cancel = function cancel() {\n                    canceled = true;\n                    that.cancel = $.noop;\n                    that.async && that.trigger(\"asyncCanceled\", query);\n                };\n                this.source(query, sync, async);\n                !syncCalled && sync([]);\n                function sync(suggestions) {\n                    if (syncCalled) {\n                        return;\n                    }\n                    syncCalled = true;\n                    suggestions = (suggestions || []).slice(0, that.limit);\n                    rendered = suggestions.length;\n                    that._overwrite(query, suggestions);\n                    if (rendered < that.limit && that.async) {\n                        that.trigger(\"asyncRequested\", query);\n                    }\n                }\n                function async(suggestions) {\n                    suggestions = suggestions || [];\n                    if (!canceled && rendered < that.limit) {\n                        that.cancel = $.noop;\n                        rendered += suggestions.length;\n                        that._append(query, suggestions.slice(0, that.limit - rendered));\n                        that.async && that.trigger(\"asyncReceived\", query);\n                    }\n                }\n            },\n            cancel: $.noop,\n            clear: function clear() {\n                this._empty();\n                this.cancel();\n                this.trigger(\"cleared\");\n            },\n            isEmpty: function isEmpty() {\n                return this.$el.is(\":empty\");\n            },\n            destroy: function destroy() {\n                this.$el = $(\"
\");\n }\n });\n return Dataset;\n function getDisplayFn(display) {\n display = display || _.stringify;\n return _.isFunction(display) ? display : displayFn;\n function displayFn(obj) {\n return obj[display];\n }\n }\n function getTemplates(templates, displayFn) {\n return {\n notFound: templates.notFound && _.templatify(templates.notFound),\n pending: templates.pending && _.templatify(templates.pending),\n header: templates.header && _.templatify(templates.header),\n footer: templates.footer && _.templatify(templates.footer),\n suggestion: templates.suggestion || suggestionTemplate\n };\n function suggestionTemplate(context) {\n return $(\"
\").text(displayFn(context));\n }\n }\n function isValidName(str) {\n return /^[_a-zA-Z0-9-]+$/.test(str);\n }\n }();\n var Menu = function() {\n \"use strict\";\n function Menu(o, www) {\n var that = this;\n o = o || {};\n if (!o.node) {\n $.error(\"node is required\");\n }\n www.mixin(this);\n this.$node = $(o.node);\n this.query = null;\n this.datasets = _.map(o.datasets, initializeDataset);\n function initializeDataset(oDataset) {\n var node = that.$node.find(oDataset.node).first();\n oDataset.node = node.length ? node : $(\"
\").appendTo(that.$node);\n return new Dataset(oDataset, www);\n }\n }\n _.mixin(Menu.prototype, EventEmitter, {\n _onSelectableClick: function onSelectableClick($e) {\n this.trigger(\"selectableClicked\", $($e.currentTarget));\n },\n _onRendered: function onRendered(type, dataset, suggestions, async) {\n this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());\n this.trigger(\"datasetRendered\", dataset, suggestions, async);\n },\n _onCleared: function onCleared() {\n this.$node.toggleClass(this.classes.empty, this._allDatasetsEmpty());\n this.trigger(\"datasetCleared\");\n },\n _propagate: function propagate() {\n this.trigger.apply(this, arguments);\n },\n _allDatasetsEmpty: function allDatasetsEmpty() {\n return _.every(this.datasets, isDatasetEmpty);\n function isDatasetEmpty(dataset) {\n return dataset.isEmpty();\n }\n },\n _getSelectables: function getSelectables() {\n return this.$node.find(this.selectors.selectable);\n },\n _removeCursor: function _removeCursor() {\n var $selectable = this.getActiveSelectable();\n $selectable && $selectable.removeClass(this.classes.cursor);\n },\n _ensureVisible: function ensureVisible($el) {\n var elTop, elBottom, nodeScrollTop, nodeHeight;\n elTop = $el.position().top;\n elBottom = elTop + $el.outerHeight(true);\n nodeScrollTop = this.$node.scrollTop();\n nodeHeight = this.$node.height() + parseInt(this.$node.css(\"paddingTop\"), 10) + parseInt(this.$node.css(\"paddingBottom\"), 10);\n if (elTop < 0) {\n this.$node.scrollTop(nodeScrollTop + elTop);\n } else if (nodeHeight < elBottom) {\n this.$node.scrollTop(nodeScrollTop + (elBottom - nodeHeight));\n }\n },\n bind: function() {\n var that = this, onSelectableClick;\n onSelectableClick = _.bind(this._onSelectableClick, this);\n this.$node.on(\"click.tt\", this.selectors.selectable, onSelectableClick);\n _.each(this.datasets, function(dataset) {\n dataset.onSync(\"asyncRequested\", that._propagate, that).onSync(\"asyncCanceled\", that._propagate, that).onSync(\"asyncReceived\", that._propagate, that).onSync(\"rendered\", that._onRendered, that).onSync(\"cleared\", that._onCleared, that);\n });\n return this;\n },\n isOpen: function isOpen() {\n return this.$node.hasClass(this.classes.open);\n },\n open: function open() {\n this.$node.addClass(this.classes.open);\n },\n close: function close() {\n this.$node.removeClass(this.classes.open);\n this._removeCursor();\n },\n setLanguageDirection: function setLanguageDirection(dir) {\n this.$node.attr(\"dir\", dir);\n },\n selectableRelativeToCursor: function selectableRelativeToCursor(delta) {\n var $selectables, $oldCursor, oldIndex, newIndex;\n $oldCursor = this.getActiveSelectable();\n $selectables = this._getSelectables();\n oldIndex = $oldCursor ? $selectables.index($oldCursor) : -1;\n newIndex = oldIndex + delta;\n newIndex = (newIndex + 1) % ($selectables.length + 1) - 1;\n newIndex = newIndex < -1 ? $selectables.length - 1 : newIndex;\n return newIndex === -1 ? null : $selectables.eq(newIndex);\n },\n setCursor: function setCursor($selectable) {\n this._removeCursor();\n if ($selectable = $selectable && $selectable.first()) {\n $selectable.addClass(this.classes.cursor);\n this._ensureVisible($selectable);\n }\n },\n getSelectableData: function getSelectableData($el) {\n return $el && $el.length ? Dataset.extractData($el) : null;\n },\n getActiveSelectable: function getActiveSelectable() {\n var $selectable = this._getSelectables().filter(this.selectors.cursor).first();\n return $selectable.length ? $selectable : null;\n },\n getTopSelectable: function getTopSelectable() {\n var $selectable = this._getSelectables().first();\n return $selectable.length ? $selectable : null;\n },\n update: function update(query) {\n var isValidUpdate = query !== this.query;\n if (isValidUpdate) {\n this.query = query;\n _.each(this.datasets, updateDataset);\n }\n return isValidUpdate;\n function updateDataset(dataset) {\n dataset.update(query);\n }\n },\n empty: function empty() {\n _.each(this.datasets, clearDataset);\n this.query = null;\n this.$node.addClass(this.classes.empty);\n function clearDataset(dataset) {\n dataset.clear();\n }\n },\n destroy: function destroy() {\n this.$node.off(\".tt\");\n this.$node = $(\"
\");\n _.each(this.datasets, destroyDataset);\n function destroyDataset(dataset) {\n dataset.destroy();\n }\n }\n });\n return Menu;\n }();\n var DefaultMenu = function() {\n \"use strict\";\n var s = Menu.prototype;\n function DefaultMenu() {\n Menu.apply(this, [].slice.call(arguments, 0));\n }\n _.mixin(DefaultMenu.prototype, Menu.prototype, {\n open: function open() {\n !this._allDatasetsEmpty() && this._show();\n return s.open.apply(this, [].slice.call(arguments, 0));\n },\n close: function close() {\n this._hide();\n return s.close.apply(this, [].slice.call(arguments, 0));\n },\n _onRendered: function onRendered() {\n if (this._allDatasetsEmpty()) {\n this._hide();\n } else {\n this.isOpen() && this._show();\n }\n return s._onRendered.apply(this, [].slice.call(arguments, 0));\n },\n _onCleared: function onCleared() {\n if (this._allDatasetsEmpty()) {\n this._hide();\n } else {\n this.isOpen() && this._show();\n }\n return s._onCleared.apply(this, [].slice.call(arguments, 0));\n },\n setLanguageDirection: function setLanguageDirection(dir) {\n this.$node.css(dir === \"ltr\" ? this.css.ltr : this.css.rtl);\n return s.setLanguageDirection.apply(this, [].slice.call(arguments, 0));\n },\n _hide: function hide() {\n this.$node.hide();\n },\n _show: function show() {\n this.$node.css(\"display\", \"block\");\n }\n });\n return DefaultMenu;\n }();\n var Typeahead = function() {\n \"use strict\";\n function Typeahead(o, www) {\n var onFocused, onBlurred, onEnterKeyed, onTabKeyed, onEscKeyed, onUpKeyed, onDownKeyed, onLeftKeyed, onRightKeyed, onQueryChanged, onWhitespaceChanged;\n o = o || {};\n if (!o.input) {\n $.error(\"missing input\");\n }\n if (!o.menu) {\n $.error(\"missing menu\");\n }\n if (!o.eventBus) {\n $.error(\"missing event bus\");\n }\n www.mixin(this);\n this.eventBus = o.eventBus;\n this.minLength = _.isNumber(o.minLength) ? o.minLength : 1;\n this.input = o.input;\n this.menu = o.menu;\n this.enabled = true;\n this.active = false;\n this.input.hasFocus() && this.activate();\n this.dir = this.input.getLangDir();\n this._hacks();\n this.menu.bind().onSync(\"selectableClicked\", this._onSelectableClicked, this).onSync(\"asyncRequested\", this._onAsyncRequested, this).onSync(\"asyncCanceled\", this._onAsyncCanceled, this).onSync(\"asyncReceived\", this._onAsyncReceived, this).onSync(\"datasetRendered\", this._onDatasetRendered, this).onSync(\"datasetCleared\", this._onDatasetCleared, this);\n onFocused = c(this, \"activate\", \"open\", \"_onFocused\");\n onBlurred = c(this, \"deactivate\", \"_onBlurred\");\n onEnterKeyed = c(this, \"isActive\", \"isOpen\", \"_onEnterKeyed\");\n onTabKeyed = c(this, \"isActive\", \"isOpen\", \"_onTabKeyed\");\n onEscKeyed = c(this, \"isActive\", \"_onEscKeyed\");\n onUpKeyed = c(this, \"isActive\", \"open\", \"_onUpKeyed\");\n onDownKeyed = c(this, \"isActive\", \"open\", \"_onDownKeyed\");\n onLeftKeyed = c(this, \"isActive\", \"isOpen\", \"_onLeftKeyed\");\n onRightKeyed = c(this, \"isActive\", \"isOpen\", \"_onRightKeyed\");\n onQueryChanged = c(this, \"_openIfActive\", \"_onQueryChanged\");\n onWhitespaceChanged = c(this, \"_openIfActive\", \"_onWhitespaceChanged\");\n this.input.bind().onSync(\"focused\", onFocused, this).onSync(\"blurred\", onBlurred, this).onSync(\"enterKeyed\", onEnterKeyed, this).onSync(\"tabKeyed\", onTabKeyed, this).onSync(\"escKeyed\", onEscKeyed, this).onSync(\"upKeyed\", onUpKeyed, this).onSync(\"downKeyed\", onDownKeyed, this).onSync(\"leftKeyed\", onLeftKeyed, this).onSync(\"rightKeyed\", onRightKeyed, this).onSync(\"queryChanged\", onQueryChanged, this).onSync(\"whitespaceChanged\", onWhitespaceChanged, this).onSync(\"langDirChanged\", this._onLangDirChanged, this);\n }\n _.mixin(Typeahead.prototype, {\n _hacks: function hacks() {\n var $input, $menu;\n $input = this.input.$input || $(\"
\");\n $menu = this.menu.$node || $(\"
\");\n $input.on(\"blur.tt\", function($e) {\n var active, isActive, hasActive;\n active = document.activeElement;\n isActive = $menu.is(active);\n hasActive = $menu.has(active).length > 0;\n if (_.isMsie() && (isActive || hasActive)) {\n $e.preventDefault();\n $e.stopImmediatePropagation();\n _.defer(function() {\n $input.focus();\n });\n }\n });\n $menu.on(\"mousedown.tt\", function($e) {\n $e.preventDefault();\n });\n },\n _onSelectableClicked: function onSelectableClicked(type, $el) {\n this.select($el);\n },\n _onDatasetCleared: function onDatasetCleared() {\n this._updateHint();\n },\n _onDatasetRendered: function onDatasetRendered(type, dataset, suggestions, async) {\n this._updateHint();\n this.eventBus.trigger(\"render\", suggestions, async, dataset);\n },\n _onAsyncRequested: function onAsyncRequested(type, dataset, query) {\n this.eventBus.trigger(\"asyncrequest\", query, dataset);\n },\n _onAsyncCanceled: function onAsyncCanceled(type, dataset, query) {\n this.eventBus.trigger(\"asynccancel\", query, dataset);\n },\n _onAsyncReceived: function onAsyncReceived(type, dataset, query) {\n this.eventBus.trigger(\"asyncreceive\", query, dataset);\n },\n _onFocused: function onFocused() {\n this._minLengthMet() && this.menu.update(this.input.getQuery());\n },\n _onBlurred: function onBlurred() {\n if (this.input.hasQueryChangedSinceLastFocus()) {\n this.eventBus.trigger(\"change\", this.input.getQuery());\n }\n },\n _onEnterKeyed: function onEnterKeyed(type, $e) {\n var $selectable;\n if ($selectable = this.menu.getActiveSelectable()) {\n this.select($selectable) && $e.preventDefault();\n }\n },\n _onTabKeyed: function onTabKeyed(type, $e) {\n var $selectable;\n if ($selectable = this.menu.getActiveSelectable()) {\n this.select($selectable) && $e.preventDefault();\n } else if ($selectable = this.menu.getTopSelectable()) {\n this.autocomplete($selectable) && $e.preventDefault();\n }\n },\n _onEscKeyed: function onEscKeyed() {\n this.close();\n },\n _onUpKeyed: function onUpKeyed() {\n this.moveCursor(-1);\n },\n _onDownKeyed: function onDownKeyed() {\n this.moveCursor(+1);\n },\n _onLeftKeyed: function onLeftKeyed() {\n if (this.dir === \"rtl\" && this.input.isCursorAtEnd()) {\n this.autocomplete(this.menu.getTopSelectable());\n }\n },\n _onRightKeyed: function onRightKeyed() {\n if (this.dir === \"ltr\" && this.input.isCursorAtEnd()) {\n this.autocomplete(this.menu.getTopSelectable());\n }\n },\n _onQueryChanged: function onQueryChanged(e, query) {\n this._minLengthMet(query) ? this.menu.update(query) : this.menu.empty();\n },\n _onWhitespaceChanged: function onWhitespaceChanged() {\n this._updateHint();\n },\n _onLangDirChanged: function onLangDirChanged(e, dir) {\n if (this.dir !== dir) {\n this.dir = dir;\n this.menu.setLanguageDirection(dir);\n }\n },\n _openIfActive: function openIfActive() {\n this.isActive() && this.open();\n },\n _minLengthMet: function minLengthMet(query) {\n query = _.isString(query) ? query : this.input.getQuery() || \"\";\n return query.length >= this.minLength;\n },\n _updateHint: function updateHint() {\n var $selectable, data, val, query, escapedQuery, frontMatchRegEx, match;\n $selectable = this.menu.getTopSelectable();\n data = this.menu.getSelectableData($selectable);\n val = this.input.getInputValue();\n if (data && !_.isBlankString(val) && !this.input.hasOverflow()) {\n query = Input.normalizeQuery(val);\n escapedQuery = _.escapeRegExChars(query);\n frontMatchRegEx = new RegExp(\"^(?:\" + escapedQuery + \")(.+$)\", \"i\");\n match = frontMatchRegEx.exec(data.val);\n match && this.input.setHint(val + match[1]);\n } else {\n this.input.clearHint();\n }\n },\n isEnabled: function isEnabled() {\n return this.enabled;\n },\n enable: function enable() {\n this.enabled = true;\n },\n disable: function disable() {\n this.enabled = false;\n },\n isActive: function isActive() {\n return this.active;\n },\n activate: function activate() {\n if (this.isActive()) {\n return true;\n } else if (!this.isEnabled() || this.eventBus.before(\"active\")) {\n return false;\n } else {\n this.active = true;\n this.eventBus.trigger(\"active\");\n return true;\n }\n },\n deactivate: function deactivate() {\n if (!this.isActive()) {\n return true;\n } else if (this.eventBus.before(\"idle\")) {\n return false;\n } else {\n this.active = false;\n this.close();\n this.eventBus.trigger(\"idle\");\n return true;\n }\n },\n isOpen: function isOpen() {\n return this.menu.isOpen();\n },\n open: function open() {\n if (!this.isOpen() && !this.eventBus.before(\"open\")) {\n this.menu.open();\n this._updateHint();\n this.eventBus.trigger(\"open\");\n }\n return this.isOpen();\n },\n close: function close() {\n if (this.isOpen() && !this.eventBus.before(\"close\")) {\n this.menu.close();\n this.input.clearHint();\n this.input.resetInputValue();\n this.eventBus.trigger(\"close\");\n }\n return !this.isOpen();\n },\n setVal: function setVal(val) {\n this.input.setQuery(_.toStr(val));\n },\n getVal: function getVal() {\n return this.input.getQuery();\n },\n select: function select($selectable) {\n var data = this.menu.getSelectableData($selectable);\n if (data && !this.eventBus.before(\"select\", data.obj)) {\n this.input.setQuery(data.val, true);\n this.eventBus.trigger(\"select\", data.obj);\n this.close();\n return true;\n }\n return false;\n },\n autocomplete: function autocomplete($selectable) {\n var query, data, isValid;\n query = this.input.getQuery();\n data = this.menu.getSelectableData($selectable);\n isValid = data && query !== data.val;\n if (isValid && !this.eventBus.before(\"autocomplete\", data.obj)) {\n this.input.setQuery(data.val);\n this.eventBus.trigger(\"autocomplete\", data.obj);\n return true;\n }\n return false;\n },\n moveCursor: function moveCursor(delta) {\n var query, $candidate, data, payload, cancelMove;\n query = this.input.getQuery();\n $candidate = this.menu.selectableRelativeToCursor(delta);\n data = this.menu.getSelectableData($candidate);\n payload = data ? data.obj : null;\n cancelMove = this._minLengthMet() && this.menu.update(query);\n if (!cancelMove && !this.eventBus.before(\"cursorchange\", payload)) {\n this.menu.setCursor($candidate);\n if (data) {\n this.input.setInputValue(data.val);\n } else {\n this.input.resetInputValue();\n this._updateHint();\n }\n this.eventBus.trigger(\"cursorchange\", payload);\n return true;\n }\n return false;\n },\n destroy: function destroy() {\n this.input.destroy();\n this.menu.destroy();\n }\n });\n return Typeahead;\n function c(ctx) {\n var methods = [].slice.call(arguments, 1);\n return function() {\n var args = [].slice.call(arguments);\n _.each(methods, function(method) {\n return ctx[method].apply(ctx, args);\n });\n };\n }\n }();\n (function() {\n \"use strict\";\n var old, keys, methods;\n old = $.fn.typeahead;\n keys = {\n www: \"tt-www\",\n attrs: \"tt-attrs\",\n typeahead: \"tt-typeahead\"\n };\n methods = {\n initialize: function initialize(o, datasets) {\n var www;\n datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 1);\n o = o || {};\n www = WWW(o.classNames);\n return this.each(attach);\n function attach() {\n var $input, $wrapper, $hint, $menu, defaultHint, defaultMenu, eventBus, input, menu, typeahead, MenuConstructor;\n _.each(datasets, function(d) {\n d.highlight = !!o.highlight;\n });\n $input = $(this);\n $wrapper = $(www.html.wrapper);\n $hint = $elOrNull(o.hint);\n $menu = $elOrNull(o.menu);\n defaultHint = o.hint !== false && !$hint;\n defaultMenu = o.menu !== false && !$menu;\n defaultHint && ($hint = buildHintFromInput($input, www));\n defaultMenu && ($menu = $(www.html.menu).css(www.css.menu));\n $hint && $hint.val(\"\");\n $input = prepInput($input, www);\n if (defaultHint || defaultMenu) {\n $wrapper.css(www.css.wrapper);\n $input.css(defaultHint ? www.css.input : www.css.inputWithNoHint);\n $input.wrap($wrapper).parent().prepend(defaultHint ? $hint : null).append(defaultMenu ? $menu : null);\n }\n MenuConstructor = defaultMenu ? DefaultMenu : Menu;\n eventBus = new EventBus({\n el: $input\n });\n input = new Input({\n hint: $hint,\n input: $input\n }, www);\n menu = new MenuConstructor({\n node: $menu,\n datasets: datasets\n }, www);\n typeahead = new Typeahead({\n input: input,\n menu: menu,\n eventBus: eventBus,\n minLength: o.minLength\n }, www);\n $input.data(keys.www, www);\n $input.data(keys.typeahead, typeahead);\n }\n },\n isEnabled: function isEnabled() {\n var enabled;\n ttEach(this.first(), function(t) {\n enabled = t.isEnabled();\n });\n return enabled;\n },\n enable: function enable() {\n ttEach(this, function(t) {\n t.enable();\n });\n return this;\n },\n disable: function disable() {\n ttEach(this, function(t) {\n t.disable();\n });\n return this;\n },\n isActive: function isActive() {\n var active;\n ttEach(this.first(), function(t) {\n active = t.isActive();\n });\n return active;\n },\n activate: function activate() {\n ttEach(this, function(t) {\n t.activate();\n });\n return this;\n },\n deactivate: function deactivate() {\n ttEach(this, function(t) {\n t.deactivate();\n });\n return this;\n },\n isOpen: function isOpen() {\n var open;\n ttEach(this.first(), function(t) {\n open = t.isOpen();\n });\n return open;\n },\n open: function open() {\n ttEach(this, function(t) {\n t.open();\n });\n return this;\n },\n close: function close() {\n ttEach(this, function(t) {\n t.close();\n });\n return this;\n },\n select: function select(el) {\n var success = false, $el = $(el);\n ttEach(this.first(), function(t) {\n success = t.select($el);\n });\n return success;\n },\n autocomplete: function autocomplete(el) {\n var success = false, $el = $(el);\n ttEach(this.first(), function(t) {\n success = t.autocomplete($el);\n });\n return success;\n },\n moveCursor: function moveCursoe(delta) {\n var success = false;\n ttEach(this.first(), function(t) {\n success = t.moveCursor(delta);\n });\n return success;\n },\n val: function val(newVal) {\n var query;\n if (!arguments.length) {\n ttEach(this.first(), function(t) {\n query = t.getVal();\n });\n return query;\n } else {\n ttEach(this, function(t) {\n t.setVal(newVal);\n });\n return this;\n }\n },\n destroy: function destroy() {\n ttEach(this, function(typeahead, $input) {\n revert($input);\n typeahead.destroy();\n });\n return this;\n }\n };\n $.fn.typeahead = function(method) {\n if (methods[method]) {\n return methods[method].apply(this, [].slice.call(arguments, 1));\n } else {\n return methods.initialize.apply(this, arguments);\n }\n };\n $.fn.typeahead.noConflict = function noConflict() {\n $.fn.typeahead = old;\n return this;\n };\n function ttEach($els, fn) {\n $els.each(function() {\n var $input = $(this), typeahead;\n (typeahead = $input.data(keys.typeahead)) && fn(typeahead, $input);\n });\n }\n function buildHintFromInput($input, www) {\n return $input.clone().addClass(www.classes.hint).removeData().css(www.css.hint).css(getBackgroundStyles($input)).prop(\"readonly\", true).removeAttr(\"id name placeholder required\").attr({\n autocomplete: \"off\",\n spellcheck: \"false\",\n tabindex: -1\n });\n }\n function prepInput($input, www) {\n $input.data(keys.attrs, {\n dir: $input.attr(\"dir\"),\n autocomplete: $input.attr(\"autocomplete\"),\n spellcheck: $input.attr(\"spellcheck\"),\n style: $input.attr(\"style\")\n });\n $input.addClass(www.classes.input).attr({\n autocomplete: \"off\",\n spellcheck: false\n });\n try {\n !$input.attr(\"dir\") && $input.attr(\"dir\", \"auto\");\n } catch (e) {}\n return $input;\n }\n function getBackgroundStyles($el) {\n return {\n backgroundAttachment: $el.css(\"background-attachment\"),\n backgroundClip: $el.css(\"background-clip\"),\n backgroundColor: $el.css(\"background-color\"),\n backgroundImage: $el.css(\"background-image\"),\n backgroundOrigin: $el.css(\"background-origin\"),\n backgroundPosition: $el.css(\"background-position\"),\n backgroundRepeat: $el.css(\"background-repeat\"),\n backgroundSize: $el.css(\"background-size\")\n };\n }\n function revert($input) {\n var www, $wrapper;\n www = $input.data(keys.www);\n $wrapper = $input.parent().filter(www.selectors.wrapper);\n _.each($input.data(keys.attrs), function(val, key) {\n _.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val);\n });\n $input.removeData(keys.typeahead).removeData(keys.www).removeData(keys.attr).removeClass(www.classes.input);\n if ($wrapper.length) {\n $input.detach().insertAfter($wrapper);\n $wrapper.remove();\n }\n }\n function $elOrNull(obj) {\n var isValid, $el;\n isValid = _.isJQuery(obj) || _.isElement(obj);\n $el = isValid ? $(obj).first() : [];\n return $el.length ? $el : null;\n }\n })();\n});","/*!\r\n * bootstrap-tokenfield\r\n * https://github.com/sliptree/bootstrap-tokenfield\r\n * Copyright 2013-2014 Sliptree and other contributors; Licensed MIT\r\n */\r\n\r\n(function (factory) {\r\n if (typeof define === 'function' && define.amd) {\r\n // AMD. Register as an anonymous module.\r\n define(['jquery'], factory);\r\n } else if (typeof exports === 'object') {\r\n // For CommonJS and CommonJS-like environments where a window with jQuery\r\n // is present, execute the factory with the jQuery instance from the window object\r\n // For environments that do not inherently posses a window with a document\r\n // (such as Node.js), expose a Tokenfield-making factory as module.exports\r\n // This accentuates the need for the creation of a real window or passing in a jQuery instance\r\n // e.g. require(\"bootstrap-tokenfield\")(window); or require(\"bootstrap-tokenfield\")($);\r\n module.exports = global.window && global.window.$ ?\r\n factory( global.window.$ ) :\r\n function( input ) {\r\n if ( !input.$ && !input.fn ) {\r\n throw new Error( \"Tokenfield requires a window object with jQuery or a jQuery instance\" );\r\n }\r\n return factory( input.$ || input );\r\n };\r\n } else {\r\n // Browser globals\r\n factory(jQuery, window);\r\n }\r\n}(function ($, window) {\r\n\r\n \"use strict\"; // jshint ;_;\r\n\r\n /* TOKENFIELD PUBLIC CLASS DEFINITION\r\n * ============================== */\r\n\r\n var Tokenfield = function (element, options) {\r\n var _self = this\r\n\r\n this.$element = $(element)\r\n this.textDirection = this.$element.css('direction');\r\n\r\n // Extend options\r\n this.options = $.extend(true, {}, $.fn.tokenfield.defaults, { tokens: this.$element.val() }, this.$element.data(), options)\r\n\r\n // Setup delimiters and trigger keys\r\n this._delimiters = (typeof this.options.delimiter === 'string') ? [this.options.delimiter] : this.options.delimiter\r\n this._triggerKeys = $.map(this._delimiters, function (delimiter) {\r\n return delimiter.charCodeAt(0);\r\n });\r\n this._firstDelimiter = this._delimiters[0];\r\n\r\n // Check for whitespace, dash and special characters\r\n var whitespace = $.inArray(' ', this._delimiters)\r\n , dash = $.inArray('-', this._delimiters)\r\n\r\n if (whitespace >= 0)\r\n this._delimiters[whitespace] = '\\\\s'\r\n\r\n if (dash >= 0) {\r\n delete this._delimiters[dash]\r\n this._delimiters.unshift('-')\r\n }\r\n\r\n var specialCharacters = ['\\\\', '$', '[', '{', '^', '.', '|', '?', '*', '+', '(', ')']\r\n $.each(this._delimiters, function (index, character) {\r\n var pos = $.inArray(character, specialCharacters)\r\n if (pos >= 0) _self._delimiters[index] = '\\\\' + character;\r\n });\r\n\r\n // Store original input width\r\n var elRules = (window && typeof window.getMatchedCSSRules === 'function') ? window.getMatchedCSSRules( element ) : null\r\n , elStyleWidth = element.style.width\r\n , elCSSWidth\r\n , elWidth = this.$element.width()\r\n\r\n if (elRules) {\r\n $.each( elRules, function (i, rule) {\r\n if (rule.style.width) {\r\n elCSSWidth = rule.style.width;\r\n }\r\n });\r\n }\r\n\r\n // Move original input out of the way\r\n var hidingPosition = $('body').css('direction') === 'rtl' ? 'right' : 'left',\r\n originalStyles = { position: this.$element.css('position') };\r\n originalStyles[hidingPosition] = this.$element.css(hidingPosition);\r\n\r\n this.$element\r\n .data('original-styles', originalStyles)\r\n .data('original-tabindex', this.$element.prop('tabindex'))\r\n .css('position', 'absolute')\r\n .css(hidingPosition, '-10000px')\r\n .prop('tabindex', -1)\r\n\r\n // Create a wrapper\r\n this.$wrapper = $('
')\r\n if (this.$element.hasClass('input-lg')) this.$wrapper.addClass('input-lg')\r\n if (this.$element.hasClass('input-sm')) this.$wrapper.addClass('input-sm')\r\n if (this.textDirection === 'rtl') this.$wrapper.addClass('rtl')\r\n\r\n // Create a new input\r\n var id = this.$element.prop('id') || new Date().getTime() + '' + Math.floor((1 + Math.random()) * 100)\r\n this.$input = $('')\r\n .appendTo( this.$wrapper )\r\n .prop( 'placeholder', this.$element.prop('placeholder') )\r\n .prop( 'id', id + '-tokenfield' )\r\n .prop( 'tabindex', this.$element.data('original-tabindex') )\r\n\r\n // Re-route original input label to new input\r\n var $label = $( 'label[for=\"' + this.$element.prop('id') + '\"]' )\r\n if ( $label.length ) {\r\n $label.prop( 'for', this.$input.prop('id') )\r\n }\r\n\r\n // Set up a copy helper to handle copy & paste\r\n this.$copyHelper = $('').css('position', 'absolute').css(hidingPosition, '-10000px').prop('tabindex', -1).prependTo( this.$wrapper )\r\n\r\n // Set wrapper width\r\n if (elStyleWidth) {\r\n this.$wrapper.css('width', elStyleWidth);\r\n }\r\n else if (elCSSWidth) {\r\n this.$wrapper.css('width', elCSSWidth);\r\n }\r\n // If input is inside inline-form with no width set, set fixed width\r\n else if (this.$element.parents('.form-inline').length) {\r\n this.$wrapper.width( elWidth )\r\n }\r\n\r\n // Set tokenfield disabled, if original or fieldset input is disabled\r\n if (this.$element.prop('disabled') || this.$element.parents('fieldset[disabled]').length) {\r\n this.disable();\r\n }\r\n\r\n // Set tokenfield readonly, if original input is readonly\r\n if (this.$element.prop('readonly')) {\r\n this.readonly();\r\n }\r\n\r\n // Set up mirror for input auto-sizing\r\n this.$mirror = $('');\r\n this.$input.css('min-width', this.options.minWidth + 'px')\r\n $.each([\r\n 'fontFamily',\r\n 'fontSize',\r\n 'fontWeight',\r\n 'fontStyle',\r\n 'letterSpacing',\r\n 'textTransform',\r\n 'wordSpacing',\r\n 'textIndent'\r\n ], function (i, val) {\r\n _self.$mirror[0].style[val] = _self.$input.css(val);\r\n });\r\n this.$mirror.appendTo( 'body' )\r\n\r\n // Insert tokenfield to HTML\r\n this.$wrapper.insertBefore( this.$element )\r\n this.$element.prependTo( this.$wrapper )\r\n\r\n // Calculate inner input width\r\n this.update()\r\n\r\n // Create initial tokens, if any\r\n this.setTokens(this.options.tokens, false, ! this.$element.val() && this.options.tokens )\r\n\r\n // Start listening to events\r\n this.listen()\r\n\r\n // Initialize autocomplete, if necessary\r\n if ( ! $.isEmptyObject( this.options.autocomplete ) ) {\r\n var side = this.textDirection === 'rtl' ? 'right' : 'left'\r\n , autocompleteOptions = $.extend({\r\n minLength: this.options.showAutocompleteOnFocus ? 0 : null,\r\n position: { my: side + \" top\", at: side + \" bottom\", of: this.$wrapper }\r\n }, this.options.autocomplete )\r\n\r\n this.$input.autocomplete( autocompleteOptions )\r\n }\r\n\r\n // Initialize typeahead, if necessary\r\n if ( ! $.isEmptyObject( this.options.typeahead ) ) {\r\n\r\n var typeaheadOptions = this.options.typeahead\r\n , defaults = {\r\n minLength: this.options.showAutocompleteOnFocus ? 0 : null\r\n }\r\n , args = $.isArray( typeaheadOptions ) ? typeaheadOptions : [typeaheadOptions, typeaheadOptions]\r\n\r\n args[0] = $.extend( {}, defaults, args[0] )\r\n\r\n this.$input.typeahead.apply( this.$input, args )\r\n this.$hint = this.$input.prev('.tt-hint')\r\n this.typeahead = true\r\n }\r\n }\r\n\r\n Tokenfield.prototype = {\r\n\r\n constructor: Tokenfield\r\n\r\n , createToken: function (attrs, triggerChange) {\r\n var _self = this\r\n\r\n if (typeof attrs === 'string') {\r\n attrs = { value: attrs, label: attrs }\r\n } else {\r\n // Copy objects to prevent contamination of data sources.\r\n attrs = $.extend( {}, attrs )\r\n }\r\n\r\n if (typeof triggerChange === 'undefined') {\r\n triggerChange = true\r\n }\r\n\r\n // Normalize label and value\r\n attrs.value = $.trim(attrs.value.toString());\r\n attrs.label = attrs.label && attrs.label.length ? $.trim(attrs.label) : attrs.value\r\n\r\n // Bail out if has no value or label, or label is too short\r\n if (!attrs.value.length || !attrs.label.length || attrs.label.length <= this.options.minLength) return\r\n\r\n // Bail out if maximum number of tokens is reached\r\n if (this.options.limit && this.getTokens().length >= this.options.limit) return\r\n\r\n // Allow changing token data before creating it\r\n var createEvent = $.Event('tokenfield:createtoken', { attrs: attrs })\r\n this.$element.trigger(createEvent)\r\n\r\n // Bail out if there if attributes are empty or event was defaultPrevented\r\n if (!createEvent.attrs || createEvent.isDefaultPrevented()) return\r\n\r\n var $token = $('
')\r\n .append('')\r\n .append('×')\r\n .data('attrs', attrs)\r\n\r\n // Insert token into HTML\r\n if (this.$input.hasClass('tt-input')) {\r\n // If the input has typeahead enabled, insert token before it's parent\r\n this.$input.parent().before( $token )\r\n } else {\r\n this.$input.before( $token )\r\n }\r\n\r\n // Temporarily set input width to minimum\r\n this.$input.css('width', this.options.minWidth + 'px')\r\n\r\n var $tokenLabel = $token.find('.token-label')\r\n , $closeButton = $token.find('.close')\r\n\r\n // Determine maximum possible token label width\r\n if (!this.maxTokenWidth) {\r\n this.maxTokenWidth =\r\n this.$wrapper.width() - $closeButton.outerWidth() -\r\n parseInt($closeButton.css('margin-left'), 10) -\r\n parseInt($closeButton.css('margin-right'), 10) -\r\n parseInt($token.css('border-left-width'), 10) -\r\n parseInt($token.css('border-right-width'), 10) -\r\n parseInt($token.css('padding-left'), 10) -\r\n parseInt($token.css('padding-right'), 10)\r\n parseInt($tokenLabel.css('border-left-width'), 10) -\r\n parseInt($tokenLabel.css('border-right-width'), 10) -\r\n parseInt($tokenLabel.css('padding-left'), 10) -\r\n parseInt($tokenLabel.css('padding-right'), 10)\r\n parseInt($tokenLabel.css('margin-left'), 10) -\r\n parseInt($tokenLabel.css('margin-right'), 10)\r\n }\r\n\r\n $tokenLabel\r\n .text(attrs.label)\r\n .css('max-width', this.maxTokenWidth)\r\n\r\n // Listen to events on token\r\n $token\r\n .on('mousedown', function (e) {\r\n if (_self._disabled || _self._readonly) return false\r\n _self.preventDeactivation = true\r\n })\r\n .on('click', function (e) {\r\n if (_self._disabled || _self._readonly) return false\r\n _self.preventDeactivation = false\r\n\r\n if (e.ctrlKey || e.metaKey) {\r\n e.preventDefault()\r\n return _self.toggle( $token )\r\n }\r\n\r\n _self.activate( $token, e.shiftKey, e.shiftKey )\r\n })\r\n .on('dblclick', function (e) {\r\n if (_self._disabled || _self._readonly || !_self.options.allowEditing ) return false\r\n _self.edit( $token )\r\n })\r\n\r\n $closeButton\r\n .on('click', $.proxy(this.remove, this))\r\n\r\n // Trigger createdtoken event on the original field\r\n // indicating that the token is now in the DOM\r\n this.$element.trigger($.Event('tokenfield:createdtoken', {\r\n attrs: attrs,\r\n relatedTarget: $token.get(0)\r\n }))\r\n\r\n // Trigger change event on the original field\r\n if (triggerChange) {\r\n this.$element.val( this.getTokensList() ).trigger( $.Event('change', { initiator: 'tokenfield' }) )\r\n }\r\n\r\n // Update tokenfield dimensions\r\n this.update()\r\n\r\n // Return original element\r\n return this.$element.get(0)\r\n }\r\n\r\n , setTokens: function (tokens, add, triggerChange) {\r\n if (!tokens) return\r\n\r\n if (!add) this.$wrapper.find('.token').remove()\r\n\r\n if (typeof triggerChange === 'undefined') {\r\n triggerChange = true\r\n }\r\n\r\n if (typeof tokens === 'string') {\r\n if (this._delimiters.length) {\r\n // Split based on delimiters\r\n tokens = tokens.split( new RegExp( '[' + this._delimiters.join('') + ']' ) )\r\n } else {\r\n tokens = [tokens];\r\n }\r\n }\r\n\r\n var _self = this\r\n $.each(tokens, function (i, attrs) {\r\n _self.createToken(attrs, triggerChange)\r\n })\r\n\r\n return this.$element.get(0)\r\n }\r\n\r\n , getTokenData: function($token) {\r\n var data = $token.map(function() {\r\n var $token = $(this);\r\n return $token.data('attrs')\r\n }).get();\r\n\r\n if (data.length == 1) {\r\n data = data[0];\r\n }\r\n\r\n return data;\r\n }\r\n\r\n , getTokens: function(active) {\r\n var self = this\r\n , tokens = []\r\n , activeClass = active ? '.active' : '' // get active tokens only\r\n this.$wrapper.find( '.token' + activeClass ).each( function() {\r\n tokens.push( self.getTokenData( $(this) ) )\r\n })\r\n return tokens\r\n }\r\n\r\n , getTokensList: function(delimiter, beautify, active) {\r\n delimiter = delimiter || this._firstDelimiter\r\n beautify = ( typeof beautify !== 'undefined' && beautify !== null ) ? beautify : this.options.beautify\r\n\r\n var separator = delimiter + ( beautify && delimiter !== ' ' ? ' ' : '')\r\n return $.map( this.getTokens(active), function (token) {\r\n return token.value\r\n }).join(separator)\r\n }\r\n\r\n , getInput: function() {\r\n return this.$input.val()\r\n }\r\n\r\n , listen: function () {\r\n var _self = this\r\n\r\n this.$element\r\n .on('change', $.proxy(this.change, this))\r\n\r\n this.$wrapper\r\n .on('mousedown',$.proxy(this.focusInput, this))\r\n\r\n this.$input\r\n .on('focus', $.proxy(this.focus, this))\r\n .on('blur', $.proxy(this.blur, this))\r\n .on('paste', $.proxy(this.paste, this))\r\n .on('keydown', $.proxy(this.keydown, this))\r\n .on('keypress', $.proxy(this.keypress, this))\r\n .on('keyup', $.proxy(this.keyup, this))\r\n\r\n this.$copyHelper\r\n .on('focus', $.proxy(this.focus, this))\r\n .on('blur', $.proxy(this.blur, this))\r\n .on('keydown', $.proxy(this.keydown, this))\r\n .on('keyup', $.proxy(this.keyup, this))\r\n\r\n // Secondary listeners for input width calculation\r\n this.$input\r\n .on('keypress', $.proxy(this.update, this))\r\n .on('keyup', $.proxy(this.update, this))\r\n\r\n this.$input\r\n .on('autocompletecreate', function() {\r\n // Set minimum autocomplete menu width\r\n var $_menuElement = $(this).data('ui-autocomplete').menu.element\r\n\r\n var minWidth = _self.$wrapper.outerWidth() -\r\n parseInt( $_menuElement.css('border-left-width'), 10 ) -\r\n parseInt( $_menuElement.css('border-right-width'), 10 )\r\n\r\n $_menuElement.css( 'min-width', minWidth + 'px' )\r\n })\r\n .on('autocompleteselect', function (e, ui) {\r\n if (_self.createToken( ui.item )) {\r\n _self.$input.val('')\r\n if (_self.$input.data( 'edit' )) {\r\n _self.unedit(true)\r\n }\r\n }\r\n return false\r\n })\r\n .on('typeahead:selected typeahead:autocompleted', function (e, datum, dataset) {\r\n // Create token\r\n if (_self.createToken( datum )) {\r\n _self.$input.typeahead('val', '')\r\n if (_self.$input.data( 'edit' )) {\r\n _self.unedit(true)\r\n }\r\n }\r\n })\r\n\r\n // Listen to window resize\r\n $(window).on('resize', $.proxy(this.update, this ))\r\n\r\n }\r\n\r\n , keydown: function (e) {\r\n\r\n if (!this.focused) return\r\n\r\n var _self = this\r\n\r\n switch(e.keyCode) {\r\n case 8: // backspace\r\n if (!this.$input.is(document.activeElement)) break\r\n this.lastInputValue = this.$input.val()\r\n break\r\n\r\n case 37: // left arrow\r\n leftRight( this.textDirection === 'rtl' ? 'next': 'prev' )\r\n break\r\n\r\n case 38: // up arrow\r\n upDown('prev')\r\n break\r\n\r\n case 39: // right arrow\r\n leftRight( this.textDirection === 'rtl' ? 'prev': 'next' )\r\n break\r\n\r\n case 40: // down arrow\r\n upDown('next')\r\n break\r\n\r\n case 65: // a (to handle ctrl + a)\r\n if (this.$input.val().length > 0 || !(e.ctrlKey || e.metaKey)) break\r\n this.activateAll()\r\n e.preventDefault()\r\n break\r\n\r\n case 9: // tab\r\n case 13: // enter\r\n\r\n // We will handle creating tokens from autocomplete in autocomplete events\r\n if (this.$input.data('ui-autocomplete') && this.$input.data('ui-autocomplete').menu.element.find(\"li:has(a.ui-state-focus), li.ui-state-focus\").length) break\r\n\r\n // We will handle creating tokens from typeahead in typeahead events\r\n if (this.$input.hasClass('tt-input') && this.$wrapper.find('.tt-cursor').length ) break\r\n if (this.$input.hasClass('tt-input') && this.$wrapper.find('.tt-hint').val() && this.$wrapper.find('.tt-hint').val().length) break\r\n\r\n // Create token\r\n if (this.$input.is(document.activeElement) && this.$input.val().length || this.$input.data('edit')) {\r\n return this.createTokensFromInput(e, this.$input.data('edit'));\r\n }\r\n\r\n // Edit token\r\n if (e.keyCode === 13) {\r\n if (!this.$copyHelper.is(document.activeElement) || this.$wrapper.find('.token.active').length !== 1) break\r\n if (!_self.options.allowEditing) break\r\n this.edit( this.$wrapper.find('.token.active') )\r\n }\r\n }\r\n\r\n function leftRight(direction) {\r\n if (_self.$input.is(document.activeElement)) {\r\n if (_self.$input.val().length > 0) return\r\n\r\n direction += 'All'\r\n var $token = _self.$input.hasClass('tt-input') ? _self.$input.parent()[direction]('.token:first') : _self.$input[direction]('.token:first')\r\n if (!$token.length) return\r\n\r\n _self.preventInputFocus = true\r\n _self.preventDeactivation = true\r\n\r\n _self.activate( $token )\r\n e.preventDefault()\r\n\r\n } else {\r\n _self[direction]( e.shiftKey )\r\n e.preventDefault()\r\n }\r\n }\r\n\r\n function upDown(direction) {\r\n if (!e.shiftKey) return\r\n\r\n if (_self.$input.is(document.activeElement)) {\r\n if (_self.$input.val().length > 0) return\r\n\r\n var $token = _self.$input.hasClass('tt-input') ? _self.$input.parent()[direction + 'All']('.token:first') : _self.$input[direction + 'All']('.token:first')\r\n if (!$token.length) return\r\n\r\n _self.activate( $token )\r\n }\r\n\r\n var opposite = direction === 'prev' ? 'next' : 'prev'\r\n , position = direction === 'prev' ? 'first' : 'last'\r\n\r\n _self.$firstActiveToken[opposite + 'All']('.token').each(function() {\r\n _self.deactivate( $(this) )\r\n })\r\n\r\n _self.activate( _self.$wrapper.find('.token:' + position), true, true )\r\n e.preventDefault()\r\n }\r\n\r\n this.lastKeyDown = e.keyCode\r\n }\r\n\r\n , keypress: function(e) {\r\n\r\n // Comma\r\n if ($.inArray( e.which, this._triggerKeys) !== -1 && this.$input.is(document.activeElement)) {\r\n if (this.$input.val()) {\r\n this.createTokensFromInput(e)\r\n }\r\n return false;\r\n }\r\n }\r\n\r\n , keyup: function (e) {\r\n this.preventInputFocus = false\r\n\r\n if (!this.focused) return\r\n\r\n switch(e.keyCode) {\r\n case 8: // backspace\r\n if (this.$input.is(document.activeElement)) {\r\n if (this.$input.val().length || this.lastInputValue.length && this.lastKeyDown === 8) break\r\n\r\n this.preventDeactivation = true\r\n var $prevToken = this.$input.hasClass('tt-input') ? this.$input.parent().prevAll('.token:first') : this.$input.prevAll('.token:first')\r\n\r\n if (!$prevToken.length) break\r\n\r\n this.activate( $prevToken )\r\n } else {\r\n this.remove(e)\r\n }\r\n break\r\n\r\n case 46: // delete\r\n this.remove(e, 'next')\r\n break\r\n }\r\n this.lastKeyUp = e.keyCode\r\n }\r\n\r\n , focus: function (e) {\r\n this.focused = true\r\n this.$wrapper.addClass('focus')\r\n\r\n if (this.$input.is(document.activeElement)) {\r\n this.$wrapper.find('.active').removeClass('active')\r\n this.$firstActiveToken = null\r\n\r\n if (this.options.showAutocompleteOnFocus) {\r\n this.search()\r\n }\r\n }\r\n }\r\n\r\n , blur: function (e) {\r\n\r\n this.focused = false\r\n this.$wrapper.removeClass('focus')\r\n\r\n if (!this.preventDeactivation && !this.$element.is(document.activeElement)) {\r\n this.$wrapper.find('.active').removeClass('active')\r\n this.$firstActiveToken = null\r\n }\r\n\r\n if (!this.preventCreateTokens && (this.$input.data('edit') && !this.$input.is(document.activeElement) || this.options.createTokensOnBlur )) {\r\n this.createTokensFromInput(e)\r\n }\r\n\r\n this.preventDeactivation = false\r\n this.preventCreateTokens = false\r\n }\r\n\r\n , paste: function (e) {\r\n var _self = this\r\n\r\n // Add tokens to existing ones\r\n if (_self.options.allowPasting) {\r\n setTimeout(function () {\r\n _self.createTokensFromInput(e)\r\n }, 1)\r\n }\r\n }\r\n\r\n , change: function (e) {\r\n if ( e.initiator === 'tokenfield' ) return // Prevent loops\r\n\r\n this.setTokens( this.$element.val() )\r\n }\r\n\r\n , createTokensFromInput: function (e, focus) {\r\n if (this.$input.val().length < this.options.minLength)\r\n return // No input, simply return\r\n\r\n var tokensBefore = this.getTokensList()\r\n this.setTokens( this.$input.val(), true )\r\n\r\n if (tokensBefore == this.getTokensList() && this.$input.val().length)\r\n return false // No tokens were added, do nothing (prevent form submit)\r\n\r\n if (this.$input.hasClass('tt-input')) {\r\n // Typeahead acts weird when simply setting input value to empty,\r\n // so we set the query to empty instead\r\n this.$input.typeahead('val', '')\r\n } else {\r\n this.$input.val('')\r\n }\r\n\r\n if (this.$input.data( 'edit' )) {\r\n this.unedit(focus)\r\n }\r\n\r\n return false // Prevent form being submitted\r\n }\r\n\r\n , next: function (add) {\r\n if (add) {\r\n var $firstActiveToken = this.$wrapper.find('.active:first')\r\n , deactivate = $firstActiveToken && this.$firstActiveToken ? $firstActiveToken.index() < this.$firstActiveToken.index() : false\r\n\r\n if (deactivate) return this.deactivate( $firstActiveToken )\r\n }\r\n\r\n var $lastActiveToken = this.$wrapper.find('.active:last')\r\n , $nextToken = $lastActiveToken.nextAll('.token:first')\r\n\r\n if (!$nextToken.length) {\r\n this.$input.focus()\r\n return\r\n }\r\n\r\n this.activate($nextToken, add)\r\n }\r\n\r\n , prev: function (add) {\r\n\r\n if (add) {\r\n var $lastActiveToken = this.$wrapper.find('.active:last')\r\n , deactivate = $lastActiveToken && this.$firstActiveToken ? $lastActiveToken.index() > this.$firstActiveToken.index() : false\r\n\r\n if (deactivate) return this.deactivate( $lastActiveToken )\r\n }\r\n\r\n var $firstActiveToken = this.$wrapper.find('.active:first')\r\n , $prevToken = $firstActiveToken.prevAll('.token:first')\r\n\r\n if (!$prevToken.length) {\r\n $prevToken = this.$wrapper.find('.token:first')\r\n }\r\n\r\n if (!$prevToken.length && !add) {\r\n this.$input.focus()\r\n return\r\n }\r\n\r\n this.activate( $prevToken, add )\r\n }\r\n\r\n , activate: function ($token, add, multi, remember) {\r\n\r\n if (!$token) return\r\n\r\n if (typeof remember === 'undefined') var remember = true\r\n\r\n if (multi) var add = true\r\n\r\n this.$copyHelper.focus()\r\n\r\n if (!add) {\r\n this.$wrapper.find('.active').removeClass('active')\r\n if (remember) {\r\n this.$firstActiveToken = $token\r\n } else {\r\n delete this.$firstActiveToken\r\n }\r\n }\r\n\r\n if (multi && this.$firstActiveToken) {\r\n // Determine first active token and the current tokens indicies\r\n // Account for the 1 hidden textarea by subtracting 1 from both\r\n var i = this.$firstActiveToken.index() - 2\r\n , a = $token.index() - 2\r\n , _self = this\r\n\r\n this.$wrapper.find('.token').slice( Math.min(i, a) + 1, Math.max(i, a) ).each( function() {\r\n _self.activate( $(this), true )\r\n })\r\n }\r\n\r\n $token.addClass('active')\r\n this.$copyHelper.val( this.getTokensList( null, null, true ) ).select()\r\n }\r\n\r\n , activateAll: function() {\r\n var _self = this\r\n\r\n this.$wrapper.find('.token').each( function (i) {\r\n _self.activate($(this), i !== 0, false, false)\r\n })\r\n }\r\n\r\n , deactivate: function($token) {\r\n if (!$token) return\r\n\r\n $token.removeClass('active')\r\n this.$copyHelper.val( this.getTokensList( null, null, true ) ).select()\r\n }\r\n\r\n , toggle: function($token) {\r\n if (!$token) return\r\n\r\n $token.toggleClass('active')\r\n this.$copyHelper.val( this.getTokensList( null, null, true ) ).select()\r\n }\r\n\r\n , edit: function ($token) {\r\n if (!$token) return\r\n\r\n var attrs = $token.data('attrs')\r\n\r\n // Allow changing input value before editing\r\n var options = { attrs: attrs, relatedTarget: $token.get(0) }\r\n var editEvent = $.Event('tokenfield:edittoken', options)\r\n this.$element.trigger( editEvent )\r\n\r\n // Edit event can be cancelled if default is prevented\r\n if (editEvent.isDefaultPrevented()) return\r\n\r\n $token.find('.token-label').text(attrs.value)\r\n var tokenWidth = $token.outerWidth()\r\n\r\n var $_input = this.$input.hasClass('tt-input') ? this.$input.parent() : this.$input\r\n\r\n $token.replaceWith( $_input )\r\n\r\n this.preventCreateTokens = true\r\n\r\n this.$input.val( attrs.value )\r\n .select()\r\n .data( 'edit', true )\r\n .width( tokenWidth )\r\n\r\n this.update();\r\n\r\n // Indicate that token is now being edited, and is replaced with an input field in the DOM\r\n this.$element.trigger($.Event('tokenfield:editedtoken', options ))\r\n }\r\n\r\n , unedit: function (focus) {\r\n var $_input = this.$input.hasClass('tt-input') ? this.$input.parent() : this.$input\r\n $_input.appendTo( this.$wrapper )\r\n\r\n this.$input.data('edit', false)\r\n this.$mirror.text('')\r\n\r\n this.update()\r\n\r\n // Because moving the input element around in DOM\r\n // will cause it to lose focus, we provide an option\r\n // to re-focus the input after appending it to the wrapper\r\n if (focus) {\r\n var _self = this\r\n setTimeout(function () {\r\n _self.$input.focus()\r\n }, 1)\r\n }\r\n }\r\n\r\n , remove: function (e, direction) {\r\n if (this.$input.is(document.activeElement) || this._disabled || this._readonly) return\r\n\r\n var $token = (e.type === 'click') ? $(e.target).closest('.token') : this.$wrapper.find('.token.active')\r\n\r\n if (e.type !== 'click') {\r\n if (!direction) var direction = 'prev'\r\n this[direction]()\r\n\r\n // Was it the first token?\r\n if (direction === 'prev') var firstToken = $token.first().prevAll('.token:first').length === 0\r\n }\r\n\r\n // Prepare events and their options\r\n var options = { attrs: this.getTokenData( $token ), relatedTarget: $token.get(0) }\r\n , removeEvent = $.Event('tokenfield:removetoken', options)\r\n\r\n this.$element.trigger(removeEvent);\r\n\r\n // Remove event can be intercepted and cancelled\r\n if (removeEvent.isDefaultPrevented()) return\r\n\r\n var removedEvent = $.Event('tokenfield:removedtoken', options)\r\n , changeEvent = $.Event('change', { initiator: 'tokenfield' })\r\n\r\n // Remove token from DOM\r\n $token.remove()\r\n\r\n // Trigger events\r\n this.$element.val( this.getTokensList() ).trigger( removedEvent ).trigger( changeEvent )\r\n\r\n // Focus, when necessary:\r\n // When there are no more tokens, or if this was the first token\r\n // and it was removed with backspace or it was clicked on\r\n if (!this.$wrapper.find('.token').length || e.type === 'click' || firstToken) this.$input.focus()\r\n\r\n // Adjust input width\r\n this.$input.css('width', this.options.minWidth + 'px')\r\n this.update()\r\n\r\n // Cancel original event handlers\r\n e.preventDefault()\r\n e.stopPropagation()\r\n }\r\n\r\n /**\r\n * Update tokenfield dimensions\r\n */\r\n , update: function (e) {\r\n var value = this.$input.val()\r\n , inputPaddingLeft = parseInt(this.$input.css('padding-left'), 10)\r\n , inputPaddingRight = parseInt(this.$input.css('padding-right'), 10)\r\n , inputPadding = inputPaddingLeft + inputPaddingRight\r\n\r\n if (this.$input.data('edit')) {\r\n\r\n if (!value) {\r\n value = this.$input.prop(\"placeholder\")\r\n }\r\n if (value === this.$mirror.text()) return\r\n\r\n this.$mirror.text(value)\r\n\r\n var mirrorWidth = this.$mirror.width() + 10;\r\n if ( mirrorWidth > this.$wrapper.width() ) {\r\n return this.$input.width( this.$wrapper.width() )\r\n }\r\n\r\n this.$input.width( mirrorWidth )\r\n\r\n if (this.$hint) {\r\n this.$hint.width( mirrorWidth )\r\n }\r\n }\r\n else {\r\n var w = (this.textDirection === 'rtl')\r\n ? this.$input.offset().left + this.$input.outerWidth() - this.$wrapper.offset().left - parseInt(this.$wrapper.css('padding-left'), 10) - inputPadding - 1\r\n : this.$wrapper.offset().left + this.$wrapper.width() + parseInt(this.$wrapper.css('padding-left'), 10) - this.$input.offset().left - inputPadding;\r\n //\r\n // some usecases pre-render widget before attaching to DOM,\r\n // dimensions returned by jquery will be NaN -> we default to 100%\r\n // so placeholder won't be cut off.\r\n isNaN(w) ? this.$input.width('100%') : this.$input.width(w);\r\n\r\n if (this.$hint) {\r\n isNaN(w) ? this.$hint.width('100%') : this.$hint.width(w);\r\n }\r\n }\r\n }\r\n\r\n , focusInput: function (e) {\r\n if ( $(e.target).closest('.token').length || $(e.target).closest('.token-input').length || $(e.target).closest('.tt-dropdown-menu').length ) return\r\n // Focus only after the current call stack has cleared,\r\n // otherwise has no effect.\r\n // Reason: mousedown is too early - input will lose focus\r\n // after mousedown. However, since the input may be moved\r\n // in DOM, there may be no click or mouseup event triggered.\r\n var _self = this\r\n setTimeout(function() {\r\n _self.$input.focus()\r\n }, 0)\r\n }\r\n\r\n , search: function () {\r\n if ( this.$input.data('ui-autocomplete') ) {\r\n this.$input.autocomplete('search')\r\n }\r\n }\r\n\r\n , disable: function () {\r\n this.setProperty('disabled', true);\r\n }\r\n\r\n , enable: function () {\r\n this.setProperty('disabled', false);\r\n }\r\n\r\n , readonly: function () {\r\n this.setProperty('readonly', true);\r\n }\r\n\r\n , writeable: function () {\r\n this.setProperty('readonly', false);\r\n }\r\n\r\n , setProperty: function(property, value) {\r\n this['_' + property] = value;\r\n this.$input.prop(property, value);\r\n this.$element.prop(property, value);\r\n this.$wrapper[ value ? 'addClass' : 'removeClass' ](property);\r\n }\r\n\r\n , destroy: function() {\r\n // Set field value\r\n this.$element.val( this.getTokensList() );\r\n // Restore styles and properties\r\n this.$element.css( this.$element.data('original-styles') );\r\n this.$element.prop( 'tabindex', this.$element.data('original-tabindex') );\r\n\r\n // Re-route tokenfield label to original input\r\n var $label = $( 'label[for=\"' + this.$input.prop('id') + '\"]' )\r\n if ( $label.length ) {\r\n $label.prop( 'for', this.$element.prop('id') )\r\n }\r\n\r\n // Move original element outside of tokenfield wrapper\r\n this.$element.insertBefore( this.$wrapper );\r\n\r\n // Remove tokenfield-related data\r\n this.$element.removeData('original-styles')\r\n .removeData('original-tabindex')\r\n .removeData('bs.tokenfield');\r\n\r\n // Remove tokenfield from DOM\r\n this.$wrapper.remove();\r\n this.$mirror.remove();\r\n\r\n var $_element = this.$element;\r\n\r\n return $_element;\r\n }\r\n\r\n }\r\n\r\n\r\n /* TOKENFIELD PLUGIN DEFINITION\r\n * ======================== */\r\n\r\n var old = $.fn.tokenfield\r\n\r\n $.fn.tokenfield = function (option, param) {\r\n var value\r\n , args = []\r\n\r\n Array.prototype.push.apply( args, arguments );\r\n\r\n var elements = this.each(function () {\r\n var $this = $(this)\r\n , data = $this.data('bs.tokenfield')\r\n , options = typeof option == 'object' && option\r\n\r\n if (typeof option === 'string' && data && data[option]) {\r\n args.shift()\r\n value = data[option].apply(data, args)\r\n } else {\r\n if (!data && typeof option !== 'string' && !param) {\r\n $this.data('bs.tokenfield', (data = new Tokenfield(this, options)))\r\n $this.trigger('tokenfield:initialize')\r\n }\r\n }\r\n })\r\n\r\n return typeof value !== 'undefined' ? value : elements;\r\n }\r\n\r\n $.fn.tokenfield.defaults = {\r\n minWidth: 60,\r\n minLength: 0,\r\n allowEditing: true,\r\n allowPasting: true,\r\n limit: 0,\r\n autocomplete: {},\r\n typeahead: {},\r\n showAutocompleteOnFocus: false,\r\n createTokensOnBlur: false,\r\n delimiter: ',',\r\n beautify: true,\r\n inputType: 'text'\r\n }\r\n\r\n $.fn.tokenfield.Constructor = Tokenfield\r\n\r\n\r\n /* TOKENFIELD NO CONFLICT\r\n * ================== */\r\n\r\n $.fn.tokenfield.noConflict = function () {\r\n $.fn.tokenfield = old\r\n return this\r\n }\r\n\r\n return Tokenfield;\r\n\r\n}));\r\n","window.chTypeAhead = (function ($, Bloodhound, _, urlHelper) {\r\n var engines = (function () {\r\n var cache = {};\r\n\r\n var sort = {\r\n Active: function (a, b) { return a.Active == b.Active ? sort.label(a, b) : b.Active - a.Active; },\r\n active: function (a, b) { return a.active == b.active ? sort.label(a, b) : b.active - a.active; },\r\n archived: function (a, b) { return a.archived == b.archived ? sort.label(a, b) : a.archived - b.archived; },\r\n label: function (a, b) { return a.label < b.label ? -1 : (a.label > b.label ? 1 : 0); },\r\n relevance: function (a, b) { return b.relevance - a.relevance; }\r\n };\r\n\r\n var ignore = {\r\n Deactivated: function (d) { return d.Active === false; },\r\n deactivated: function (d) { return d.active === false; },\r\n archived: function (d) { return d.archived === true; }\r\n };\r\n\r\n function get(type) {\r\n if (!cache.hasOwnProperty(type)) {\r\n cache[type] = new Bloodhound(getConfig(type));\r\n }\r\n return cache[type];\r\n }\r\n\r\n function getConfig(type) {\r\n switch (type) {\r\n case 'Organisation':\r\n return buildConfig({\r\n url: '/admin/suggest/organisation?s={s}&maxResults=20',\r\n value: 'Id',\r\n label: function (datum) { return datum.Name + delimit(' - ', datum.Division); },\r\n ignore: ignore.Deactivated\r\n });\r\n case 'OrganisationContact':\r\n return buildConfig({\r\n url: '/admin/suggest/organisationContact?s={s}&active=true',\r\n value: 'Id',\r\n label: function (datum) { return datum.FirstName + delimit(', ' , datum.LastName); },\r\n ignore: ignore.Deactivated\r\n });\r\n case 'Activity':\r\n return buildConfig({\r\n url: '/admin/activities/search/suggest?text={s}&take=20',\r\n value: 'id',\r\n label: 'title'\r\n });\r\n case 'ActivityType':\r\n return buildConfig({\r\n url: '/admin/suggest/' + type,\r\n prefetch: { key: type, sort: sort.label },\r\n ignore: ignore.archived\r\n });\r\n case 'Administrator':\r\n return buildConfig({\r\n url: '/admin/suggest/administrator?maxResults=9000',\r\n prefetch: { key: type, sort: sort.Active },\r\n value: 'Id',\r\n label: 'Name',\r\n tokens: ['Position'],\r\n ignore: ignore.Deactivated\r\n });\r\n case 'JounralLabel':\r\n case 'GeneralLabel':\r\n return buildConfig({\r\n url: '/admin/suggest/label?type=' + type.substring(0, 7),\r\n prefetch: { key: type, sort: sort.archived },\r\n ignore: ignore.archived\r\n });\r\n case 'JobSeeker':\r\n return buildConfig({\r\n url: '/admin/suggest/jobseeker/suggest?s={s}&maxResults=20',\r\n value: 'Id',\r\n label: function (datum) { return datum.FirstName + ' ' + datum.LastName; }\r\n });\r\n case 'Campus':\r\n return buildConfig({\r\n url: '/admin/suggest/' + type,\r\n prefetch: { key: type, sort: sort.label }\r\n });\r\n case 'CampusBuilding':\r\n return buildConfig({\r\n url: '/admin/suggest/' + type + '?s={s}&maxResults=20'\r\n });\r\n case 'OnCampusLocation':\r\n return buildConfig({\r\n url: '/admin/suggest/' + type + '?s={s}&maxResults=20'\r\n });\r\n case 'Developer':\r\n return buildConfig({\r\n url: '/admin/suggest/developers',\r\n value: 'Id',\r\n prefetch: { key: type, sort: sort.label },\r\n label: function (datum) { return datum.Name + delimit(' - ', datum.Company); }\r\n });\r\n case 'ExperienceType':\r\n return buildConfig({\r\n url: '/admin/suggest/category?key=' + type,\r\n prefetch: { key: type, sort: sort.active },\r\n ignore: ignore.deactivated\r\n });\r\n case 'Event':\r\n return buildConfig({\r\n url: '/admin/suggest/event?s={s}&maxResults=20',\r\n value: 'Id',\r\n label: 'Title'\r\n });\r\n case 'Country':\r\n return buildConfig({\r\n url: '/countries',\r\n value: 'code',\r\n label: 'name',\r\n tokens: ['code', 'alpha3', 'aliases'],\r\n prefetch: { key: type, sort: sort.relevance, cache: true }\r\n });\r\n case 'EventType':\r\n return buildConfig({\r\n url: '/admin/suggest/' + type,\r\n prefetch: { key: type, sort: sort.label },\r\n ignore: ignore.archived\r\n });\r\n case 'Skill':\r\n return buildConfig({\r\n url: '/admin/suggest/skill',\r\n prefetch: { key: type, sort: sort.label },\r\n ignore: ignore.archived\r\n });\r\n case 'WorkGroup':\r\n return buildConfig({\r\n url: '/admin/suggest/' + type,\r\n prefetch: { key: type }\r\n });\r\n case 'Major':\r\n return buildConfig({\r\n url: '/admin/suggest/major?s={s}&maxResults=20',\r\n value: 'value',\r\n label: 'value'\r\n });\r\n case 'ResourceTopic':\r\n return buildConfig({\r\n url: '/admin/suggest/resourcetopic?s={s}'\r\n });\r\n case 'GuestTracker':\r\n return buildConfig({\r\n url: '/admin/suggest/guestTracker?s={s}&Active=true',\r\n value: 'EntityId',\r\n label: function (datum) { return datum.FirstName + delimit(', ', datum.LastName); },\r\n ignore: ignore.Deactivated\r\n });\r\n case 'Endorsement':\r\n return buildConfig({\r\n url: '/admin/suggest/endorsements?s={s}',\r\n value: 'id',\r\n label: 'name',\r\n ignore: ignore.archived\r\n });\r\n default:\r\n throw \"'\" + type + \"' type not supported\";\r\n }\r\n }\r\n\r\n function buildConfig(config) {\r\n if (!config.value) config.value = 'id';\r\n if (!config.label) config.label = 'name';\r\n \r\n var opts = {\r\n initialize: false,\r\n queryTokenizer: Bloodhound.tokenizers.whitespace,\r\n datumTokenizer: function (datum) {\r\n var tokens = [];\r\n\r\n if (config.ignore && config.ignore(datum)) {\r\n return [];\r\n }\r\n if (datum.label) {\r\n tokens = tokens.concat(Bloodhound.tokenizers.whitespace(datum.label));\r\n }\r\n if (datum.label != datum.value) {\r\n tokens.push('' + datum.value);\r\n }\r\n if (config.tokens) {\r\n _.each(config.tokens, function (key) {\r\n var val = datum[key];\r\n if (!val) {\r\n return;\r\n } else if (_.isString(val)) {\r\n tokens = tokens.concat(Bloodhound.tokenizers.whitespace(val));\r\n } else if (_.isArray(val)) {\r\n _.each(val, function (subVal) {\r\n tokens = tokens.concat(Bloodhound.tokenizers.whitespace(subVal));\r\n });\r\n }\r\n });\r\n }\r\n return tokens;\r\n },\r\n identify: function (datum) {\r\n return datum.value;\r\n }\r\n };\r\n\r\n var transform = function (data) {\r\n if (config.transform) {\r\n data = getter(data, config.transform);\r\n }\r\n _.each(data, function (item) {\r\n item.value = getter(item, config.value);\r\n item.label = getter(item, config.label);\r\n });\r\n\r\n if (config.prefetch) {\r\n if (config.prefetch.sort) {\r\n data.sort(config.prefetch.sort);\r\n }\r\n _.each(data, function (item, i) {\r\n item.i = i;\r\n });\r\n }\r\n\r\n return data;\r\n };\r\n\r\n var url = urlHelper.resolveUrl(config.url);\r\n\r\n if (config.prefetch) {\r\n opts.prefetch = {\r\n url: url,\r\n cache: config.prefetch.cache === true,\r\n cacheKey: config.prefetch.key,\r\n transform: transform\r\n };\r\n } else {\r\n opts.remote = {\r\n url: url,\r\n wildcard: '{s}',\r\n transform: transform\r\n };\r\n }\r\n\r\n return opts;\r\n }\r\n\r\n function delimit(before, value, after) {\r\n if (value === '' || value == null) {\r\n return '';\r\n } else {\r\n return (before == null ? '' : before) + value + (after == null ? '' : after);\r\n }\r\n }\r\n\r\n function getIndex(type) {\r\n var deferred = $.Deferred();\r\n\r\n var engine = get(type);\r\n\r\n engine.initialize()\r\n .done(function () {\r\n deferred.resolveWith(this, [_.sortBy(engine.index.datums, 'i'), engine]);\r\n })\r\n .fail(function () {\r\n deferred.rejectWith(this, arguments);\r\n });\r\n\r\n return deferred;\r\n }\r\n\r\n return {\r\n get: get,\r\n getIndex: getIndex\r\n };\r\n }());\r\n\r\n var dataSets = (function () {\r\n function boolLabel(prop, text, style, expected) {\r\n if (expected === undefined) {\r\n expected = true;\r\n }\r\n\r\n var cfg = {\r\n getter: function (d) {\r\n return (d.hasOwnProperty(prop) && d[prop] === expected) ? (text ? text : prop) : null;\r\n }\r\n };\r\n\r\n if (style) {\r\n cfg.style = function (d) { return style; };\r\n }\r\n return cfg;\r\n }\r\n\r\n function getStatusStyle(status) {\r\n switch (status) {\r\n case 'Deleted':\r\n case 'Cancelled': return 'danger';\r\n case 'Expired':\r\n case 'Ended':\r\n case 'Prelisted': return 'warning';\r\n case 'Published': return 'success';\r\n default: return \"secondary\";\r\n }\r\n }\r\n\r\n var label = {\r\n archived: boolLabel('archived', 'archived', 'warning'),\r\n deactivated: boolLabel('active', 'disabled', 'warning', false),\r\n Deactivated: boolLabel('Active', 'disabled', 'warning', false),\r\n status: {\r\n getter: function (d) { return d.status ? d.status.toUpperCase() : null; },\r\n style: function (d) { return getStatusStyle(d.status); }\r\n },\r\n Status: {\r\n getter: function (d) { return d.Status ? d.Status.toUpperCase() : null; },\r\n style: function (d) { return getStatusStyle(d.Status); }\r\n }\r\n };\r\n\r\n function get(type) {\r\n var dataset = {\r\n display: 'label',\r\n name: type,\r\n source: engines.get(type).ttAdapter(),\r\n // Bug when using limit (better to use server-side limit anyway): https://github.com/twitter/typeahead.js/issues/1795\r\n // This means prefetched data isn't limited when searching, however prefetched data should always be small or it shouldn't be prefetched\r\n limit: Infinity,\r\n templates: {\r\n pending: '
searching...
',\r\n notFound: '
no matches
'\r\n }\r\n };\r\n\r\n switch (type) {\r\n case 'Activity':\r\n setTableTemplates(dataset, [\r\n { name: 'Title', getter: 'label', span: 6, labels: [label.status] },\r\n { name: 'Location', getter: 'location', span: 6 }\r\n ]);\r\n break;\r\n case 'ActivityType':\r\n dataset.templates.suggestion = getLabelledSuggestion(label.archived);\r\n break;\r\n case 'Event':\r\n setTableTemplates(dataset, [\r\n { name: 'Title', getter: 'label', span: 5, labels: [label.Status] },\r\n { name: 'Date', getter: 'Start', span: 3 },\r\n { name: 'Venue', getter: 'Venue', span: 4 }\r\n ]);\r\n break;\r\n case 'JobSeeker':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: function (datum) { return datum.FirstName + ' ' + datum.LastName; }, span: 5 },\r\n { name: 'Student No.', getter: 'ExternalId', span: 3 },\r\n { name: 'Email', getter: 'Email', span: 4 }\r\n ]);\r\n break;\r\n case 'EventType':\r\n dataset.templates.suggestion = getLabelledSuggestion(label.archived);\r\n break;\r\n case 'ExperienceType':\r\n dataset.templates.suggestion = getLabelledSuggestion(label.archived);\r\n break;\r\n case 'WorkGroup':\r\n dataset.templates.suggestion = getLabelledSuggestion(\r\n boolLabel('openToJobSeekers', 'open to students', 'warning'), // TODO: use strings\r\n boolLabel('openToAdministrators', 'open to admin', 'warning'),\r\n boolLabel('default', null, 'info', true)\r\n );\r\n break;\r\n case 'JounralLabel':\r\n case 'GeneralLabel':\r\n dataset.templates.suggestion = getLabelledSuggestion(\r\n boolLabel('archived', null, 'warning'),\r\n boolLabel('private', null, 'info')\r\n );\r\n break;\r\n case 'Organisation':\r\n setTableTemplates(dataset, [\r\n { name: 'Name - Division', getter: 'label', span: 6, labels: [label.Deactivated] },\r\n { name: 'Email', getter: 'Email', span: 6 }\r\n ]);\r\n break;\r\n case 'OrganisationContact':\r\n setTableTemplates(dataset, [\r\n { name: 'Contact', getter: 'label', span: 4 },\r\n { name: 'Name - Division', getter: 'OrganisationName', span: 4, labels: [label.Deactivated] },\r\n { name: 'Email', getter: 'Email', span: 4, labels: [label.Deactivated] }\r\n ]);\r\n break;\r\n case 'GuestTracker':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'label', span: 4 },\r\n { name: 'Email', getter: 'Email', span: 4 },\r\n { name: 'Type', getter: 'TypeDescription', span: 4, labels: [label.Deactivated] }\r\n ]);\r\n break;\r\n case 'Administrator':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'label', span: 4, xsSpan:12, labels: [label.Deactivated] },\r\n { name: 'Email', getter: 'Email', span: 4, xsSpan: 12 },\r\n { name: 'Position', getter: 'Position', span: 4, xsSpan: 12 }\r\n ]);\r\n break;\r\n case 'Developer':\r\n setTableTemplates(dataset, [\r\n { name: 'Developer ID', getter: 'Id', span: 4 },\r\n { name: 'Name', getter: 'label', span: 2 },\r\n { name: 'Email', getter: 'Email', span: 3 },\r\n { name: 'Company', getter: 'Company', span: 3 }\r\n ]);\r\n break;\r\n case 'Campus':\r\n dataset.templates.suggestion = getLabelledSuggestion(label.deactivated);\r\n break;\r\n case 'CampusBuilding':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'label', span: 6, labels: [label.archived] },\r\n { name: 'Campus', getter: 'campusName', span: 6 }\r\n ]);\r\n break;\r\n case 'OnCampusLocation':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'label', span: 4, labels: [label.archived] }, \r\n { name: 'Building', getter: 'buildingName', span: 4 },\r\n { name: 'Campus', getter: 'campusName', span: 4 }\r\n ]);\r\n break;\r\n case 'Major':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'id', span: 12 }\r\n ]);\r\n break;\r\n case 'Skill':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'label', span: 6, labels: [label.archived] },\r\n { name: 'Classification', getter: 'classification', span: 6 }\r\n ]);\r\n break;\r\n case 'ResourceTopic':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'label', span: 6, labels: [label.archived] },\r\n { name: 'Promoted', getter: 'promoted', span: 6 }\r\n ]);\r\n break;\r\n case 'Endorsement':\r\n setTableTemplates(dataset, [\r\n { name: 'Name', getter: 'label', span: 6, labels: [label.archived] },\r\n { name: 'Acronym', getter: 'acronym', span: 6 }\r\n ]);\r\n break;\r\n default:\r\n dataset.templates.suggestion = defaultSuggestion;\r\n break;\r\n }\r\n\r\n return dataset;\r\n }\r\n\r\n function setTableTemplates(dataset, config) {\r\n dataset.templates.header = getTableHeader(config);\r\n dataset.templates.suggestion = getTableSuggestion(config);\r\n }\r\n\r\n function getLabelledSuggestion() {\r\n var config = arguments;\r\n return function (datum) {\r\n return '
' + datum.label + '
' + getLabels(datum, config) + '
';\r\n };\r\n }\r\n\r\n function getTableHeader(config) {\r\n var spans = [];\r\n $.each(config, function (i, cfg) {\r\n spans.push('
' + cfg.name + '
');\r\n });\r\n return '
' + spans.join('') + '
';\r\n }\r\n\r\n function getTableSuggestion(config) {\r\n return function (datum) {\r\n var spans = [];\r\n\r\n\r\n $.each(config, function (i, cfg) {\r\n var text = getter(datum, cfg.getter);\r\n\r\n var span = $('
')\r\n .addClass('col-' + cfg.span)\r\n .text(text ? text : '')\r\n .append(' ' + getLabels(datum, cfg.labels));\r\n\r\n spans.push(span[0].outerHTML);\r\n });\r\n\r\n return '
' + spans.join('') + '
';\r\n };\r\n }\r\n\r\n function getLabels(datum, config) {\r\n if (!config) return '';\r\n\r\n var labels = [];\r\n\r\n $.each(config, function (i, cfg) {\r\n var text = getter(datum, cfg.getter);\r\n\r\n if (text) {\r\n var style = getter(datum, cfg.style);\r\n\r\n var label = $('')\r\n .addClass('badge-' + (style ? style : 'secondary'))\r\n .text(text);\r\n\r\n labels.push(label[0].outerHTML);\r\n }\r\n });\r\n\r\n return labels.join(' ');\r\n }\r\n\r\n function defaultSuggestion(datum) {\r\n return $('
').text(datum.label);\r\n }\r\n\r\n return { get: get };\r\n }());\r\n\r\n function getter(item, prop) {\r\n return typeof prop === 'function' ? prop(item) : item[prop];\r\n }\r\n\r\n $.fn.chTypeahead = function (options) {\r\n var engine = engines.get(options.type);\r\n\r\n if (engine.prefetch) {\r\n this.on('focus', initializeEngine);\r\n }\r\n\r\n function initializeEngine(e) {\r\n engine.initialize();\r\n $(e.currentTarget).off('focus', initializeEngine);\r\n }\r\n\r\n if (options.submit) {\r\n this.on('typeahead:select', function () {\r\n var form = $(this.form);\r\n\r\n // timeout so typeahead-id executes first\r\n setTimeout(function () {\r\n form.submit();\r\n });\r\n });\r\n }\r\n\r\n var response = this.typeahead({\r\n highlight: true,\r\n minLength: 1\r\n }, dataSets.get(options.type));\r\n\r\n this.closest('.twitter-typeahead').addClass('form-control');\r\n\r\n return response;\r\n };\r\n\r\n return {\r\n engines: engines,\r\n dataSets: dataSets\r\n };\r\n}(jQuery, Bloodhound, _, urlHelper));\r\n","(function ($, _, engines, dataSets) {\r\n var checkboxModal = (function () {\r\n var dataName = 'chCheckboxModal';\r\n\r\n function init(type, values) {\r\n if (this.data(dataName)) {\r\n destroy.call(this);\r\n }\r\n\r\n this.data(dataName, {\r\n type: type,\r\n showAll: false\r\n }).on('click', open);\r\n\r\n vals.call(this, values);\r\n }\r\n\r\n function open() {\r\n var elm = $(this);\r\n\r\n var config = elm.data(dataName);\r\n\r\n if (config.modal) {\r\n config.modal.remove();\r\n }\r\n\r\n var size = 'modal-lg';\r\n var header = dataSets.get(config.type).templates.header;\r\n if (!header) {\r\n header = '';\r\n } else if ($('.row > div', header).length >= 3) {\r\n // use large modal for 3 or more columns\r\n size = 'modal-xl';\r\n }\r\n\r\n config.modal = $(\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
' + elm.attr('title') + '
' +\r\n '' +\r\n '
' +\r\n '
' + header + '
' +\r\n '
' +\r\n 'loading...' +\r\n '
' +\r\n '
' +\r\n '' +\r\n 'Close' +\r\n '
' +\r\n '
' +\r\n '
' +\r\n '
')\r\n .appendTo(document.body)\r\n .modal({})\r\n .on('hidden', function () {\r\n config.modal.remove();\r\n config.modal = null;\r\n config.showArchive = false;\r\n });\r\n\r\n $('.modal-footer .ch-checkboxModal-all', config.modal).on('click', function () {\r\n config.showAll = !config.showAll;\r\n renderBody.call(elm);\r\n });\r\n\r\n renderBody.call(elm);\r\n }\r\n\r\n function renderBody() {\r\n var elm = this;\r\n var config = elm.data(dataName);\r\n\r\n engines.getIndex(config.type).then(\r\n function (data, engine) {\r\n if (config.type.toLowerCase() === 'country' || config.type.toLowerCase() === 'workgroup') {\r\n data.sort(function (a, b) {\r\n // countries are sorted by relevance for typeahead\r\n // labels make more sense when listing\r\n return a.label < b.label ? -1 : (a.label > b.label ? 1 : 0);\r\n });\r\n }\r\n\r\n var dataset = dataSets.get(config.type),\r\n suggestion = dataset.templates.suggestion,\r\n body = $('.modal-body', config.modal).empty(),\r\n showAllLink = $('.ch-checkboxModal-all', config.modal),\r\n hasHidden = false;\r\n showAllLink.hide();\r\n\r\n var values = _.clone(config.values);\r\n\r\n _.each(data, function (datum) {\r\n var checked = $.inArray('' + datum.value, values) >= 0;\r\n\r\n if (engine.index.datumTokenizer(datum).length === 0) {\r\n if (!hasHidden) {\r\n showAllLink.show();\r\n hasHidden = true;\r\n showAllLink.html(' Show all');\r\n }\r\n if (!checked && !config.showAll) {\r\n return;\r\n }\r\n }\r\n\r\n body.append(getRow(suggestion(datum), datum, checked, elm));\r\n\r\n if (checked) {\r\n _.pull(values, '' + datum.value);\r\n }\r\n });\r\n\r\n // unknown values (deleted, no access...)\r\n _.each(values, function (value) {\r\n body.prepend(getRow(\r\n $('
').text('id:' + value).append(' '),\r\n { label: value, value: value }, true, elm));\r\n });\r\n },\r\n function () {\r\n $('.modal-body', modal).html('service error');\r\n });\r\n }\r\n\r\n function getRow(html, datum, checked, elm) {\r\n\r\n var row = $('
' +\r\n '' +\r\n '' +\r\n '
');\r\n row.find('.form-check-label').append(html);\r\n row.on('click', function (e) {\r\n var cb = $(this).find('input')[0];\r\n cb.checked = !cb.checked;\r\n change.call(elm);\r\n });\r\n\r\n var input = row.find('input')\r\n .data('token', datum)\r\n .on({\r\n 'change': function (e) { change.call(elm); },\r\n 'click': function (e) { e.stopPropagation(); }\r\n });\r\n\r\n if (checked) {\r\n row.addClass('selected');\r\n input.attr('checked', true);\r\n }\r\n\r\n return row;\r\n }\r\n\r\n function vals(values) {\r\n this.data(dataName).values = values ? _.map(values, function (o) { return '' + o; }) : [];\r\n }\r\n\r\n function destroy() {\r\n this.off('click', checkboxModal.open);\r\n var model = this.data(dataName).modal;\r\n if (model) modal.remove();\r\n this.removeData(dataName);\r\n }\r\n\r\n function change() {\r\n var checkboxes = $('input[type=checkbox]', this.data(dataName).modal);\r\n\r\n var tokens = [];\r\n $.each(checkboxes, function () {\r\n var token = $(this).data('token');\r\n\r\n $(this).closest('.ch-checkboxModal-row').toggleClass('selected', this.checked);\r\n\r\n if (this.checked) {\r\n tokens.push(token);\r\n }\r\n });\r\n\r\n var values = _.map(tokens, function (o) { return '' + o.value; });\r\n\r\n this.trigger('checkboxModal:change', {\r\n tokens: tokens,\r\n values: values\r\n });\r\n\r\n vals.call(this, values);\r\n }\r\n\r\n return {\r\n init: init,\r\n open: open,\r\n vals: vals,\r\n destroy: destroy\r\n };\r\n }());\r\n\r\n $.fn.chCheckboxModal = function (method) {\r\n if (checkboxModal[method]) {\r\n checkboxModal[method].apply(this, [].slice.call(arguments, 1));\r\n } else {\r\n checkboxModal.init.apply(this, arguments);\r\n }\r\n return this;\r\n };\r\n}($, _, chTypeAhead.engines, chTypeAhead.dataSets));\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n","$.fn.chServiceSubmit = function () {\r\n this.on('submit', function submit(e) {\r\n e.preventDefault();\r\n\r\n var form = $(e.target);\r\n\r\n var method = form.attr('method');\r\n if (!method) {\r\n method = 'POST';\r\n }\r\n\r\n clearErrors(form);\r\n\r\n var buttons = form\r\n .find('button[type=submit],input[type=submit]')\r\n .attr('disabled', 'disabled');\r\n\r\n $.ajax({\r\n type: method,\r\n url: form.attr('action'),\r\n data: form.serialize()\r\n })\r\n .done(function (data) {\r\n form.trigger('submit:success', data)\r\n })\r\n .fail(function (jqXHR) {\r\n if (jqXHR.status == 400) {\r\n var errors = $.parseJSON(jqXHR.responseText);\r\n displayErrors(form, errors);\r\n form.trigger('submit:fail', [errors])\r\n } else {\r\n alert('Unexpected error');\r\n form.trigger('submit:fail', arguments)\r\n }\r\n })\r\n .always(function () {\r\n buttons.removeAttr('disabled');\r\n })\r\n });\r\n\r\n function displayErrors(form, data) {\r\n var alertPlaceholder = $('.validation-alert', form);\r\n var alert = null;\r\n\r\n if (alertPlaceholder.length) {\r\n alert = $('
Validation Errors
    ');\r\n alertPlaceholder.replaceWith(alert);\r\n }\r\n\r\n for (var i = 0; i < data.fields.length; i++) {\r\n var fieldData = data.fields[i];\r\n var field = $(document.getElementById(fieldData.key.replace(/\\./g, '_')), form);\r\n var group = field.parents('.form-group');\r\n\r\n if (alert) {\r\n alert.removeClass('hidden');\r\n for (var j = 0; j < fieldData.errors.length; j++) {\r\n var error = fieldData.errors[j];\r\n\r\n var html = $('
  • ')\r\n .text(error.errorMessage)\r\n\r\n $('ul', alert).append(html);\r\n }\r\n }\r\n\r\n if (field) {\r\n for (var j = 0; j < fieldData.errors.length; j++) {\r\n var error = fieldData.errors[j];\r\n\r\n var html = $('
    ')\r\n .addClass('field-validation-error text-danger')\r\n .text(error.errorMessage)\r\n\r\n if (group.length === 1) {\r\n group.append(html).addClass('error')\r\n } else {\r\n field.after(html);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n function clearErrors(form) {\r\n $('.field-validation-error', form).remove();\r\n $('.form-group.error', form).removeClass('error');\r\n $('.validation-alert', form).replaceWith('
    ');\r\n }\r\n};\r\n","function TimeSpan(str) {\r\n this.seconds = 0;\r\n\r\n this.parse = function (val) {\r\n if (typeof val == 'number') {\r\n this.seconds = val;\r\n\r\n } else if (typeof val == 'string') {\r\n // Timespans should be in the format 'd.hh:mm:ss'.\r\n var parts = val.split(':');\r\n\r\n this.seconds = parseInt(parts[2]);\r\n this.seconds += parseInt(parts[1]) * 60;\r\n\r\n // the 'd.' is optional.\r\n parts = parts[0].split('.');\r\n if (parts.length == 2) {\r\n this.seconds += parseInt(parts[1]) * 3600;\r\n this.seconds += parseInt(parts[0]) * 86400;\r\n } else {\r\n this.seconds += parseInt(parts[0]) * 3600;\r\n }\r\n }\r\n };\r\n\r\n this.toFriendly = function () {\r\n var interval;\r\n var num = this.seconds;\r\n\r\n if (this.seconds % 60 != 0) {\r\n interval = 'second';\r\n\r\n } else if (this.seconds % 3600 != 0) {\r\n interval = 'minute';\r\n num = num / 60;\r\n\r\n } else if (this.seconds % 86400 != 0) {\r\n interval = 'hour';\r\n num = num / 3600;\r\n\r\n } else {\r\n interval = 'day';\r\n num = num / 86400;\r\n }\r\n\r\n if (Math.abs(num) != 1) {\r\n interval += 's'\r\n }\r\n\r\n return num + ' ' + interval;\r\n };\r\n\r\n this.fromSeconds = function (val) {\r\n this.seconds = val;\r\n };\r\n\r\n this.totalSeconds = function () {\r\n return this.seconds;\r\n };\r\n\r\n this.getParts = function () {\r\n var parts = {};\r\n\r\n var num = this.seconds;\r\n parts.seconds = num % 60;\r\n\r\n num = (num - parts.seconds) / 60;\r\n parts.minutes = num % 60;\r\n\r\n num = (num - parts.minutes) / 60;\r\n parts.hours = num % 24;\r\n\r\n parts.days = (num - parts.hours) / 24;\r\n\r\n return parts;\r\n };\r\n\r\n\r\n this.toString = function () {\r\n var parts = this.getParts();\r\n\r\n var str = pad(parts.hours) + ':' + pad(parts.minutes) + ':' + pad(parts.seconds % 60);\r\n\r\n if (parts.days != 0) {\r\n str = parts.days + '.' + str;\r\n }\r\n\r\n return str;\r\n };\r\n\r\n function pad(num) {\r\n var s = \"0\" + num;\r\n return s.substr(s.length - 2);\r\n }\r\n\r\n if (str) {\r\n this.parse(str);\r\n }\r\n}\r\n\r\n(function ($) {\r\n var intervals = [\r\n 'Minutes',\r\n 'Hours',\r\n 'Days'\r\n ];\r\n\r\n var defaults = {\r\n dropDirection: 'down'\r\n };\r\n\r\n function timeSpan(elm, opts) {\r\n // public methods\r\n this.init = init;\r\n this.val = val;\r\n this.destroy = destroy;\r\n\r\n var group;\r\n var num;\r\n var btn;\r\n var interval;\r\n var config = $.extend(defaults, opts);\r\n\r\n function init() {\r\n elm.hide();\r\n\r\n group = $('
    ').insertAfter(elm);\r\n\r\n num = $('')\r\n .on('change', change)\r\n .appendTo(group);\r\n\r\n var btnGroup = $('
    ')\r\n .addClass(config.dropDirection == 'up' ? 'dropup' : 'dropdown')\r\n .appendTo(group);\r\n\r\n btn = $('