From 0fd361c454e1b054bc7970fe2c72e1d21c3bd52a Mon Sep 17 00:00:00 2001 From: nikki Date: Sun, 1 Nov 2020 17:06:56 +0000 Subject: [PATCH 1/7] centralised Currency to mid section of page --- index.html | 593 +++++++++++++++++++++++++++++++++++++++++++---- style/custom.css | 98 ++++++-- 2 files changed, 632 insertions(+), 59 deletions(-) diff --git a/index.html b/index.html index b445926..f479caa 100644 --- a/index.html +++ b/index.html @@ -9,38 +9,14 @@ - + X-change Away. - - - - - - - - +
- - - -
- - +
+
-

EX AWAY

+
WELCOME TO...
+

EX AWAY

BEST WAY TO EXCHANGE

- - + + +
+
+
+
+
+
+
+
+
+

Currency Converter

+

Brief description.

+
- +
+ +
+ +
+ +
- - + +
+ +
+
+ + +
+ +
+

AMOUNT:

+
+ +
+
+ +
+

AMOUNT:

+
+ +
+
+
+
+
@@ -96,4 +604,5 @@

EX AWAY

- \ No newline at end of file + + diff --git a/style/custom.css b/style/custom.css index b3e822c..fee2093 100644 --- a/style/custom.css +++ b/style/custom.css @@ -2,44 +2,98 @@ margin:0; padding: 0; box-sizing: border-box; -moz-box-sizing: border-box; outline: 0; - } - body { - background-image: url(../assets/images/front-page-background.png); + background-image: url(../assets/images/front-page-background.png)!important; background-size: cover; + min-height: 500px; + padding: 0em 0em; background-repeat: no-repeat; } -.navbar { - +.menu{ + border: 0px!important; +} +.navbar{ + background-color: transparent !important; } -.title { +.welcome { + position: relative; + top:100px; + font-size: 20px; + display:flex; +} +.title{ margin: 90px 90px; - font-size: 150px; + font-size: 90px; position: relative; - top: 100px; + top: 20px; display: flex; color: #fff; font-family: Arial, Helvetica, sans-serif; } .item{ - color: white; - + color: white !important; +} +body div h2 span{ + color: orange; } .para { margin: 96px; - font-family: 'Raleway', sans-serif; + font-family: ‘Raleway’, sans-serif; color: white; font-weight: 700; - font-size: 30px; + font-size: 20px; + position: relative; + top: -90px; } - .btn { - position: relative; - top: 20px; left: 100px; + width: 150px; + font-size: smaller; + position: relative; +} +.selection { + width: 45px; + margin-bottom: 50px; + align-self: center; +} +#curConverterBtn{ + top: -50px; + background-color: orange; + border-radius: 15px; +} +#liveWeatherBtn{ + top: -50px; + border: 0.1px white; + border-radius: 15px; } +input { + border-radius: 25px; +} +/* +Moved to allign to the middle section of the page Rk +*/ + +h4 { + font-size: 36px; + font-style: inherit; + text-align: center; + +} + + +#center-currency{ + position: relative; + top: 400px; + left: 60px; + right: 10px ; + bottom: 10px ; + +} + + + /*.item{ color: white; @@ -50,8 +104,6 @@ body { left: 1350px; top: 25px; } - - /* .logo{ margin-top: 30px; @@ -63,3 +115,15 @@ body { } */ + + + + + + + + + + + + From 0b9afd73c4ea7388d6a66320b1503aee3635d0c6 Mon Sep 17 00:00:00 2001 From: nikki Date: Tue, 3 Nov 2020 20:40:47 +0000 Subject: [PATCH 2/7] dropdown and currency api's added --- assets/dist/.DS_Store | Bin 0 -> 6148 bytes assets/dist/components/dropdown.js | 3955 ++++++++++++++++++ assets/dist/components/dropdown.min.css | 9 + assets/dist/components/dropdown.min.js | 1 + assets/dist/components/icon.css | 4806 ++++++++++++++++++++++ assets/dist/components/transition.js | 1095 +++++ assets/dist/components/transition.min.js | 1 + assets/library/jquery.min.js | 4 + index.html | 56 +- script.js | 23 + 10 files changed, 9931 insertions(+), 19 deletions(-) create mode 100644 assets/dist/.DS_Store create mode 100644 assets/dist/components/dropdown.js create mode 100644 assets/dist/components/dropdown.min.css create mode 100644 assets/dist/components/dropdown.min.js create mode 100644 assets/dist/components/icon.css create mode 100644 assets/dist/components/transition.js create mode 100644 assets/dist/components/transition.min.js create mode 100644 assets/library/jquery.min.js create mode 100644 script.js diff --git a/assets/dist/.DS_Store b/assets/dist/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 0) + ? $module.prev().find(selector.text) + : $module.prev(), + + $menu = $module.children(selector.menu), + $item = $menu.find(selector.item), + + activated = false, + itemActivated = false, + internalChange = false, + element = this, + instance = $module.data(moduleNamespace), + + initialLoad, + pageLostFocus, + willRefocus, + elementNamespace, + id, + selectObserver, + menuObserver, + module + ; + + module = { + + initialize: function() { + module.debug('Initializing dropdown', settings); + + if( module.is.alreadySetup() ) { + module.setup.reference(); + } + else { + + module.setup.layout(); + + if(settings.values) { + module.change.values(settings.values); + } + + module.refreshData(); + + module.save.defaults(); + module.restore.selected(); + + module.create.id(); + module.bind.events(); + + module.observeChanges(); + module.instantiate(); + } + + }, + + instantiate: function() { + module.verbose('Storing instance of dropdown', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous dropdown', $module); + module.remove.tabbable(); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + $menu + .off(eventNamespace) + ; + $document + .off(elementNamespace) + ; + module.disconnect.menuObserver(); + module.disconnect.selectObserver(); + }, + + observeChanges: function() { + if('MutationObserver' in window) { + selectObserver = new MutationObserver(module.event.select.mutation); + menuObserver = new MutationObserver(module.event.menu.mutation); + module.debug('Setting up mutation observer', selectObserver, menuObserver); + module.observe.select(); + module.observe.menu(); + } + }, + + disconnect: { + menuObserver: function() { + if(menuObserver) { + menuObserver.disconnect(); + } + }, + selectObserver: function() { + if(selectObserver) { + selectObserver.disconnect(); + } + } + }, + observe: { + select: function() { + if(module.has.input()) { + selectObserver.observe($module[0], { + childList : true, + subtree : true + }); + } + }, + menu: function() { + if(module.has.menu()) { + menuObserver.observe($menu[0], { + childList : true, + subtree : true + }); + } + } + }, + + create: { + id: function() { + id = (Math.random().toString(16) + '000000000').substr(2, 8); + elementNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + }, + userChoice: function(values) { + var + $userChoices, + $userChoice, + isUserValue, + html + ; + values = values || module.get.userValues(); + if(!values) { + return false; + } + values = $.isArray(values) + ? values + : [values] + ; + $.each(values, function(index, value) { + if(module.get.item(value) === false) { + html = settings.templates.addition( module.add.variables(message.addResult, value) ); + $userChoice = $('
') + .html(html) + .attr('data-' + metadata.value, value) + .attr('data-' + metadata.text, value) + .addClass(className.addition) + .addClass(className.item) + ; + if(settings.hideAdditions) { + $userChoice.addClass(className.hidden); + } + $userChoices = ($userChoices === undefined) + ? $userChoice + : $userChoices.add($userChoice) + ; + module.verbose('Creating user choices for value', value, $userChoice); + } + }); + return $userChoices; + }, + userLabels: function(value) { + var + userValues = module.get.userValues() + ; + if(userValues) { + module.debug('Adding user labels', userValues); + $.each(userValues, function(index, value) { + module.verbose('Adding custom user value'); + module.add.label(value, value); + }); + } + }, + menu: function() { + $menu = $('
') + .addClass(className.menu) + .appendTo($module) + ; + }, + sizer: function() { + $sizer = $('') + .addClass(className.sizer) + .insertAfter($search) + ; + } + }, + + search: function(query) { + query = (query !== undefined) + ? query + : module.get.query() + ; + module.verbose('Searching for query', query); + if(module.has.minCharacters(query)) { + module.filter(query); + } + else { + module.hide(); + } + }, + + select: { + firstUnfiltered: function() { + module.verbose('Selecting first non-filtered element'); + module.remove.selectedItem(); + $item + .not(selector.unselectable) + .not(selector.addition + selector.hidden) + .eq(0) + .addClass(className.selected) + ; + }, + nextAvailable: function($selected) { + $selected = $selected.eq(0); + var + $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0), + $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0), + hasNext = ($nextAvailable.length > 0) + ; + if(hasNext) { + module.verbose('Moving selection to', $nextAvailable); + $nextAvailable.addClass(className.selected); + } + else { + module.verbose('Moving selection to', $prevAvailable); + $prevAvailable.addClass(className.selected); + } + } + }, + + setup: { + api: function() { + var + apiSettings = { + debug : settings.debug, + urlData : { + value : module.get.value(), + query : module.get.query() + }, + on : false + } + ; + module.verbose('First request, initializing API'); + $module + .api(apiSettings) + ; + }, + layout: function() { + if( $module.is('select') ) { + module.setup.select(); + module.setup.returnedObject(); + } + if( !module.has.menu() ) { + module.create.menu(); + } + if( module.is.search() && !module.has.search() ) { + module.verbose('Adding search input'); + $search = $('') + .addClass(className.search) + .prop('autocomplete', 'off') + .insertBefore($text) + ; + } + if( module.is.multiple() && module.is.searchSelection() && !module.has.sizer()) { + module.create.sizer(); + } + if(settings.allowTab) { + module.set.tabbable(); + } + }, + select: function() { + var + selectValues = module.get.selectValues() + ; + module.debug('Dropdown initialized on a select', selectValues); + if( $module.is('select') ) { + $input = $module; + } + // see if select is placed correctly already + if($input.parent(selector.dropdown).length > 0) { + module.debug('UI dropdown already exists. Creating dropdown menu only'); + $module = $input.closest(selector.dropdown); + if( !module.has.menu() ) { + module.create.menu(); + } + $menu = $module.children(selector.menu); + module.setup.menu(selectValues); + } + else { + module.debug('Creating entire dropdown from select'); + $module = $('
') + .attr('class', $input.attr('class') ) + .addClass(className.selection) + .addClass(className.dropdown) + .html( templates.dropdown(selectValues) ) + .insertBefore($input) + ; + if($input.hasClass(className.multiple) && $input.prop('multiple') === false) { + module.error(error.missingMultiple); + $input.prop('multiple', true); + } + if($input.is('[multiple]')) { + module.set.multiple(); + } + if ($input.prop('disabled')) { + module.debug('Disabling dropdown'); + $module.addClass(className.disabled); + } + $input + .removeAttr('class') + .detach() + .prependTo($module) + ; + } + module.refresh(); + }, + menu: function(values) { + $menu.html( templates.menu(values, fields)); + $item = $menu.find(selector.item); + }, + reference: function() { + module.debug('Dropdown behavior was called on select, replacing with closest dropdown'); + // replace module reference + $module = $module.parent(selector.dropdown); + instance = $module.data(moduleNamespace); + element = $module.get(0); + module.refresh(); + module.setup.returnedObject(); + }, + returnedObject: function() { + var + $firstModules = $allModules.slice(0, elementIndex), + $lastModules = $allModules.slice(elementIndex + 1) + ; + // adjust all modules to use correct reference + $allModules = $firstModules.add($module).add($lastModules); + } + }, + + refresh: function() { + module.refreshSelectors(); + module.refreshData(); + }, + + refreshItems: function() { + $item = $menu.find(selector.item); + }, + + refreshSelectors: function() { + module.verbose('Refreshing selector cache'); + $text = $module.find(selector.text); + $search = $module.find(selector.search); + $input = $module.find(selector.input); + $icon = $module.find(selector.icon); + $combo = ($module.prev().find(selector.text).length > 0) + ? $module.prev().find(selector.text) + : $module.prev() + ; + $menu = $module.children(selector.menu); + $item = $menu.find(selector.item); + }, + + refreshData: function() { + module.verbose('Refreshing cached metadata'); + $item + .removeData(metadata.text) + .removeData(metadata.value) + ; + }, + + clearData: function() { + module.verbose('Clearing metadata'); + $item + .removeData(metadata.text) + .removeData(metadata.value) + ; + $module + .removeData(metadata.defaultText) + .removeData(metadata.defaultValue) + .removeData(metadata.placeholderText) + ; + }, + + toggle: function() { + module.verbose('Toggling menu visibility'); + if( !module.is.active() ) { + module.show(); + } + else { + module.hide(); + } + }, + + show: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(!module.can.show() && module.is.remote()) { + module.debug('No API results retrieved, searching before show'); + module.queryRemote(module.get.query(), module.show); + } + if( module.can.show() && !module.is.active() ) { + module.debug('Showing dropdown'); + if(module.has.message() && !(module.has.maxSelections() || module.has.allResultsFiltered()) ) { + module.remove.message(); + } + if(module.is.allFiltered()) { + return true; + } + if(settings.onShow.call(element) !== false) { + module.animate.show(function() { + if( module.can.click() ) { + module.bind.intent(); + } + if(module.has.menuSearch()) { + module.focusSearch(); + } + module.set.visible(); + callback.call(element); + }); + } + } + }, + + hide: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.active() && !module.is.animatingOutward() ) { + module.debug('Hiding dropdown'); + if(settings.onHide.call(element) !== false) { + module.animate.hide(function() { + module.remove.visible(); + callback.call(element); + }); + } + } + }, + + hideOthers: function() { + module.verbose('Finding other dropdowns to hide'); + $allModules + .not($module) + .has(selector.menu + '.' + className.visible) + .dropdown('hide') + ; + }, + + hideMenu: function() { + module.verbose('Hiding menu instantaneously'); + module.remove.active(); + module.remove.visible(); + $menu.transition('hide'); + }, + + hideSubMenus: function() { + var + $subMenus = $menu.children(selector.item).find(selector.menu) + ; + module.verbose('Hiding sub menus', $subMenus); + $subMenus.transition('hide'); + }, + + bind: { + events: function() { + if(hasTouch) { + module.bind.touchEvents(); + } + module.bind.keyboardEvents(); + module.bind.inputEvents(); + module.bind.mouseEvents(); + }, + touchEvents: function() { + module.debug('Touch device detected binding additional touch events'); + if( module.is.searchSelection() ) { + // do nothing special yet + } + else if( module.is.single() ) { + $module + .on('touchstart' + eventNamespace, module.event.test.toggle) + ; + } + $menu + .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter) + ; + }, + keyboardEvents: function() { + module.verbose('Binding keyboard events'); + $module + .on('keydown' + eventNamespace, module.event.keydown) + ; + if( module.has.search() ) { + $module + .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input) + ; + } + if( module.is.multiple() ) { + $document + .on('keydown' + elementNamespace, module.event.document.keydown) + ; + } + }, + inputEvents: function() { + module.verbose('Binding input change events'); + $module + .on('change' + eventNamespace, selector.input, module.event.change) + ; + }, + mouseEvents: function() { + module.verbose('Binding mouse events'); + if(module.is.multiple()) { + $module + .on('click' + eventNamespace, selector.label, module.event.label.click) + .on('click' + eventNamespace, selector.remove, module.event.remove.click) + ; + } + if( module.is.searchSelection() ) { + $module + .on('mousedown' + eventNamespace, module.event.mousedown) + .on('mouseup' + eventNamespace, module.event.mouseup) + .on('mousedown' + eventNamespace, selector.menu, module.event.menu.mousedown) + .on('mouseup' + eventNamespace, selector.menu, module.event.menu.mouseup) + .on('click' + eventNamespace, selector.icon, module.event.icon.click) + .on('focus' + eventNamespace, selector.search, module.event.search.focus) + .on('click' + eventNamespace, selector.search, module.event.search.focus) + .on('blur' + eventNamespace, selector.search, module.event.search.blur) + .on('click' + eventNamespace, selector.text, module.event.text.focus) + ; + if(module.is.multiple()) { + $module + .on('click' + eventNamespace, module.event.click) + ; + } + } + else { + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.event.test.toggle) + ; + } + else if(settings.on == 'hover') { + $module + .on('mouseenter' + eventNamespace, module.delay.show) + .on('mouseleave' + eventNamespace, module.delay.hide) + ; + } + else { + $module + .on(settings.on + eventNamespace, module.toggle) + ; + } + $module + .on('click' + eventNamespace, selector.icon, module.event.icon.click) + .on('mousedown' + eventNamespace, module.event.mousedown) + .on('mouseup' + eventNamespace, module.event.mouseup) + .on('focus' + eventNamespace, module.event.focus) + ; + if(module.has.menuSearch() ) { + $module + .on('blur' + eventNamespace, selector.search, module.event.search.blur) + ; + } + else { + $module + .on('blur' + eventNamespace, module.event.blur) + ; + } + } + $menu + .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter) + .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave) + .on('click' + eventNamespace, selector.item, module.event.item.click) + ; + }, + intent: function() { + module.verbose('Binding hide intent event to document'); + if(hasTouch) { + $document + .on('touchstart' + elementNamespace, module.event.test.touch) + .on('touchmove' + elementNamespace, module.event.test.touch) + ; + } + $document + .on('click' + elementNamespace, module.event.test.hide) + ; + } + }, + + unbind: { + intent: function() { + module.verbose('Removing hide intent event from document'); + if(hasTouch) { + $document + .off('touchstart' + elementNamespace) + .off('touchmove' + elementNamespace) + ; + } + $document + .off('click' + elementNamespace) + ; + } + }, + + filter: function(query) { + var + searchTerm = (query !== undefined) + ? query + : module.get.query(), + afterFiltered = function() { + if(module.is.multiple()) { + module.filterActive(); + } + if(query || (!query && module.get.activeItem().length == 0)) { + module.select.firstUnfiltered(); + } + if( module.has.allResultsFiltered() ) { + if( settings.onNoResults.call(element, searchTerm) ) { + if(settings.allowAdditions) { + if(settings.hideAdditions) { + module.verbose('User addition with no menu, setting empty style'); + module.set.empty(); + module.hideMenu(); + } + } + else { + module.verbose('All items filtered, showing message', searchTerm); + module.add.message(message.noResults); + } + } + else { + module.verbose('All items filtered, hiding dropdown', searchTerm); + module.hideMenu(); + } + } + else { + module.remove.empty(); + module.remove.message(); + } + if(settings.allowAdditions) { + module.add.userSuggestion(query); + } + if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) { + module.show(); + } + } + ; + if(settings.useLabels && module.has.maxSelections()) { + return; + } + if(settings.apiSettings) { + if( module.can.useAPI() ) { + module.queryRemote(searchTerm, function() { + if(settings.filterRemoteData) { + module.filterItems(searchTerm); + } + afterFiltered(); + }); + } + else { + module.error(error.noAPI); + } + } + else { + module.filterItems(searchTerm); + afterFiltered(); + } + }, + + queryRemote: function(query, callback) { + var + apiSettings = { + errorDuration : false, + cache : 'local', + throttle : settings.throttle, + urlData : { + query: query + }, + onError: function() { + module.add.message(message.serverError); + callback(); + }, + onFailure: function() { + module.add.message(message.serverError); + callback(); + }, + onSuccess : function(response) { + var + values = response[fields.remoteValues], + hasRemoteValues = ($.isArray(values) && values.length > 0) + ; + if(hasRemoteValues) { + module.remove.message(); + module.setup.menu({ + values: response[fields.remoteValues] + }); + } + else { + module.add.message(message.noResults); + } + callback(); + } + } + ; + if( !$module.api('get request') ) { + module.setup.api(); + } + apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings); + $module + .api('setting', apiSettings) + .api('query') + ; + }, + + filterItems: function(query) { + var + searchTerm = (query !== undefined) + ? query + : module.get.query(), + results = null, + escapedTerm = module.escape.string(searchTerm), + beginsWithRegExp = new RegExp('^' + escapedTerm, 'igm') + ; + // avoid loop if we're matching nothing + if( module.has.query() ) { + results = []; + + module.verbose('Searching for matching values', searchTerm); + $item + .each(function(){ + var + $choice = $(this), + text, + value + ; + if(settings.match == 'both' || settings.match == 'text') { + text = String(module.get.choiceText($choice, false)); + if(text.search(beginsWithRegExp) !== -1) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, text)) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, text)) { + results.push(this); + return true; + } + } + if(settings.match == 'both' || settings.match == 'value') { + value = String(module.get.choiceValue($choice, text)); + if(value.search(beginsWithRegExp) !== -1) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, value)) { + results.push(this); + return true; + } + else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, value)) { + results.push(this); + return true; + } + } + }) + ; + } + module.debug('Showing only matched items', searchTerm); + module.remove.filteredItem(); + if(results) { + $item + .not(results) + .addClass(className.filtered) + ; + } + }, + + fuzzySearch: function(query, term) { + var + termLength = term.length, + queryLength = query.length + ; + query = query.toLowerCase(); + term = term.toLowerCase(); + if(queryLength > termLength) { + return false; + } + if(queryLength === termLength) { + return (query === term); + } + search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) { + var + queryCharacter = query.charCodeAt(characterIndex) + ; + while(nextCharacterIndex < termLength) { + if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) { + continue search; + } + } + return false; + } + return true; + }, + exactSearch: function (query, term) { + query = query.toLowerCase(); + term = term.toLowerCase(); + if(term.indexOf(query) > -1) { + return true; + } + return false; + }, + filterActive: function() { + if(settings.useLabels) { + $item.filter('.' + className.active) + .addClass(className.filtered) + ; + } + }, + + focusSearch: function(skipHandler) { + if( module.has.search() && !module.is.focusedOnSearch() ) { + if(skipHandler) { + $module.off('focus' + eventNamespace, selector.search); + $search.focus(); + $module.on('focus' + eventNamespace, selector.search, module.event.search.focus); + } + else { + $search.focus(); + } + } + }, + + forceSelection: function() { + var + $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0), + $activeItem = $item.not(className.filtered).filter('.' + className.active).eq(0), + $selectedItem = ($currentlySelected.length > 0) + ? $currentlySelected + : $activeItem, + hasSelected = ($selectedItem.length > 0) + ; + if(hasSelected && !module.is.multiple()) { + module.debug('Forcing partial selection to selected item', $selectedItem); + module.event.item.click.call($selectedItem, {}, true); + return; + } + else { + if(settings.allowAdditions) { + module.set.selected(module.get.query()); + module.remove.searchTerm(); + } + else { + module.remove.searchTerm(); + } + } + }, + + change: { + values: function(values) { + if(!settings.allowAdditions) { + module.clear(); + } + module.debug('Creating dropdown with specified values', values); + module.setup.menu({values: values}); + $.each(values, function(index, item) { + if(item.selected == true) { + module.debug('Setting initial selection to', item.value); + module.set.selected(item.value); + return true; + } + }); + } + }, + + event: { + change: function() { + if(!internalChange) { + module.debug('Input changed, updating selection'); + module.set.selected(); + } + }, + focus: function() { + if(settings.showOnFocus && !activated && module.is.hidden() && !pageLostFocus) { + module.show(); + } + }, + blur: function(event) { + pageLostFocus = (document.activeElement === this); + if(!activated && !pageLostFocus) { + module.remove.activeLabel(); + module.hide(); + } + }, + mousedown: function() { + if(module.is.searchSelection()) { + // prevent menu hiding on immediate re-focus + willRefocus = true; + } + else { + // prevents focus callback from occurring on mousedown + activated = true; + } + }, + mouseup: function() { + if(module.is.searchSelection()) { + // prevent menu hiding on immediate re-focus + willRefocus = false; + } + else { + activated = false; + } + }, + click: function(event) { + var + $target = $(event.target) + ; + // focus search + if($target.is($module)) { + if(!module.is.focusedOnSearch()) { + module.focusSearch(); + } + else { + module.show(); + } + } + }, + search: { + focus: function() { + activated = true; + if(module.is.multiple()) { + module.remove.activeLabel(); + } + if(settings.showOnFocus) { + module.search(); + } + }, + blur: function(event) { + pageLostFocus = (document.activeElement === this); + if(module.is.searchSelection() && !willRefocus) { + if(!itemActivated && !pageLostFocus) { + if(settings.forceSelection) { + module.forceSelection(); + } + module.hide(); + } + } + willRefocus = false; + } + }, + icon: { + click: function(event) { + if($icon.hasClass(className.clear)) { + module.clear(); + } + else if (module.can.click()) { + module.toggle(); + } + } + }, + text: { + focus: function(event) { + activated = true; + module.focusSearch(); + } + }, + input: function(event) { + if(module.is.multiple() || module.is.searchSelection()) { + module.set.filtered(); + } + clearTimeout(module.timer); + module.timer = setTimeout(module.search, settings.delay.search); + }, + label: { + click: function(event) { + var + $label = $(this), + $labels = $module.find(selector.label), + $activeLabels = $labels.filter('.' + className.active), + $nextActive = $label.nextAll('.' + className.active), + $prevActive = $label.prevAll('.' + className.active), + $range = ($nextActive.length > 0) + ? $label.nextUntil($nextActive).add($activeLabels).add($label) + : $label.prevUntil($prevActive).add($activeLabels).add($label) + ; + if(event.shiftKey) { + $activeLabels.removeClass(className.active); + $range.addClass(className.active); + } + else if(event.ctrlKey) { + $label.toggleClass(className.active); + } + else { + $activeLabels.removeClass(className.active); + $label.addClass(className.active); + } + settings.onLabelSelect.apply(this, $labels.filter('.' + className.active)); + } + }, + remove: { + click: function() { + var + $label = $(this).parent() + ; + if( $label.hasClass(className.active) ) { + // remove all selected labels + module.remove.activeLabels(); + } + else { + // remove this label only + module.remove.activeLabels( $label ); + } + } + }, + test: { + toggle: function(event) { + var + toggleBehavior = (module.is.multiple()) + ? module.show + : module.toggle + ; + if(module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) { + return; + } + if( module.determine.eventOnElement(event, toggleBehavior) ) { + event.preventDefault(); + } + }, + touch: function(event) { + module.determine.eventOnElement(event, function() { + if(event.type == 'touchstart') { + module.timer = setTimeout(function() { + module.hide(); + }, settings.delay.touch); + } + else if(event.type == 'touchmove') { + clearTimeout(module.timer); + } + }); + event.stopPropagation(); + }, + hide: function(event) { + module.determine.eventInModule(event, module.hide); + } + }, + select: { + mutation: function(mutations) { + module.debug(' removing selected option', removedValue); + newValue = module.remove.arrayValue(removedValue, values); + module.remove.optionValue(removedValue); + } + else { + module.verbose('Removing from delimited values', removedValue); + newValue = module.remove.arrayValue(removedValue, values); + newValue = newValue.join(settings.delimiter); + } + if(settings.fireOnInit === false && module.is.initialLoad()) { + module.verbose('No callback on initial load', settings.onRemove); + } + else { + settings.onRemove.call(element, removedValue, removedText, $removedItem); + } + module.set.value(newValue, removedText, $removedItem); + module.check.maxSelections(); + }, + arrayValue: function(removedValue, values) { + if( !$.isArray(values) ) { + values = [values]; + } + values = $.grep(values, function(value){ + return (removedValue != value); + }); + module.verbose('Removed value from delimited string', removedValue, values); + return values; + }, + label: function(value, shouldAnimate) { + var + $labels = $module.find(selector.label), + $removedLabel = $labels.filter('[data-' + metadata.value + '="' + module.escape.string(value) +'"]') + ; + module.verbose('Removing label', $removedLabel); + $removedLabel.remove(); + }, + activeLabels: function($activeLabels) { + $activeLabels = $activeLabels || $module.find(selector.label).filter('.' + className.active); + module.verbose('Removing active label selections', $activeLabels); + module.remove.labels($activeLabels); + }, + labels: function($labels) { + $labels = $labels || $module.find(selector.label); + module.verbose('Removing labels', $labels); + $labels + .each(function(){ + var + $label = $(this), + value = $label.data(metadata.value), + stringValue = (value !== undefined) + ? String(value) + : value, + isUserValue = module.is.userValue(stringValue) + ; + if(settings.onLabelRemove.call($label, value) === false) { + module.debug('Label remove callback cancelled removal'); + return; + } + module.remove.message(); + if(isUserValue) { + module.remove.value(stringValue); + module.remove.label(stringValue); + } + else { + // selected will also remove label + module.remove.selected(stringValue); + } + }) + ; + }, + tabbable: function() { + if( module.is.searchSelection() ) { + module.debug('Searchable dropdown initialized'); + $search + .removeAttr('tabindex') + ; + $menu + .removeAttr('tabindex') + ; + } + else { + module.debug('Simple selection dropdown initialized'); + $module + .removeAttr('tabindex') + ; + $menu + .removeAttr('tabindex') + ; + } + }, + clearable: function() { + $icon.removeClass(className.clear); + } + }, + + has: { + menuSearch: function() { + return (module.has.search() && $search.closest($menu).length > 0); + }, + search: function() { + return ($search.length > 0); + }, + sizer: function() { + return ($sizer.length > 0); + }, + selectInput: function() { + return ( $input.is('select') ); + }, + minCharacters: function(searchTerm) { + if(settings.minCharacters) { + searchTerm = (searchTerm !== undefined) + ? String(searchTerm) + : String(module.get.query()) + ; + return (searchTerm.length >= settings.minCharacters); + } + return true; + }, + firstLetter: function($item, letter) { + var + text, + firstLetter + ; + if(!$item || $item.length === 0 || typeof letter !== 'string') { + return false; + } + text = module.get.choiceText($item, false); + letter = letter.toLowerCase(); + firstLetter = String(text).charAt(0).toLowerCase(); + return (letter == firstLetter); + }, + input: function() { + return ($input.length > 0); + }, + items: function() { + return ($item.length > 0); + }, + menu: function() { + return ($menu.length > 0); + }, + message: function() { + return ($menu.children(selector.message).length !== 0); + }, + label: function(value) { + var + escapedValue = module.escape.value(value), + $labels = $module.find(selector.label) + ; + if(settings.ignoreCase) { + escapedValue = escapedValue.toLowerCase(); + } + return ($labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) +'"]').length > 0); + }, + maxSelections: function() { + return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections); + }, + allResultsFiltered: function() { + var + $normalResults = $item.not(selector.addition) + ; + return ($normalResults.filter(selector.unselectable).length === $normalResults.length); + }, + userSuggestion: function() { + return ($menu.children(selector.addition).length > 0); + }, + query: function() { + return (module.get.query() !== ''); + }, + value: function(value) { + return (settings.ignoreCase) + ? module.has.valueIgnoringCase(value) + : module.has.valueMatchingCase(value) + ; + }, + valueMatchingCase: function(value) { + var + values = module.get.values(), + hasValue = $.isArray(values) + ? values && ($.inArray(value, values) !== -1) + : (values == value) + ; + return (hasValue) + ? true + : false + ; + }, + valueIgnoringCase: function(value) { + var + values = module.get.values(), + hasValue = false + ; + if(!$.isArray(values)) { + values = [values]; + } + $.each(values, function(index, existingValue) { + if(String(value).toLowerCase() == String(existingValue).toLowerCase()) { + hasValue = true; + return false; + } + }); + return hasValue; + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + animatingInward: function() { + return $menu.transition('is inward'); + }, + animatingOutward: function() { + return $menu.transition('is outward'); + }, + bubbledLabelClick: function(event) { + return $(event.target).is('select, input') && $module.closest('label').length > 0; + }, + bubbledIconClick: function(event) { + return $(event.target).closest($icon).length > 0; + }, + alreadySetup: function() { + return ($module.is('select') && $module.parent(selector.dropdown).data(moduleNamespace) !== undefined && $module.prev().length === 0); + }, + animating: function($subMenu) { + return ($subMenu) + ? $subMenu.transition && $subMenu.transition('is animating') + : $menu.transition && $menu.transition('is animating') + ; + }, + leftward: function($subMenu) { + var $selectedMenu = $subMenu || $menu; + return $selectedMenu.hasClass(className.leftward); + }, + disabled: function() { + return $module.hasClass(className.disabled); + }, + focused: function() { + return (document.activeElement === $module[0]); + }, + focusedOnSearch: function() { + return (document.activeElement === $search[0]); + }, + allFiltered: function() { + return( (module.is.multiple() || module.has.search()) && !(settings.hideAdditions == false && module.has.userSuggestion()) && !module.has.message() && module.has.allResultsFiltered() ); + }, + hidden: function($subMenu) { + return !module.is.visible($subMenu); + }, + initialLoad: function() { + return initialLoad; + }, + inObject: function(needle, object) { + var + found = false + ; + $.each(object, function(index, property) { + if(property == needle) { + found = true; + return true; + } + }); + return found; + }, + multiple: function() { + return $module.hasClass(className.multiple); + }, + remote: function() { + return settings.apiSettings && module.can.useAPI(); + }, + single: function() { + return !module.is.multiple(); + }, + selectMutation: function(mutations) { + var + selectChanged = false + ; + $.each(mutations, function(index, mutation) { + if(mutation.target && $(mutation.target).is('select')) { + selectChanged = true; + return true; + } + }); + return selectChanged; + }, + search: function() { + return $module.hasClass(className.search); + }, + searchSelection: function() { + return ( module.has.search() && $search.parent(selector.dropdown).length === 1 ); + }, + selection: function() { + return $module.hasClass(className.selection); + }, + userValue: function(value) { + return ($.inArray(value, module.get.userValues()) !== -1); + }, + upward: function($menu) { + var $element = $menu || $module; + return $element.hasClass(className.upward); + }, + visible: function($subMenu) { + return ($subMenu) + ? $subMenu.hasClass(className.visible) + : $menu.hasClass(className.visible) + ; + }, + verticallyScrollableContext: function() { + var + overflowY = ($context.get(0) !== window) + ? $context.css('overflow-y') + : false + ; + return (overflowY == 'auto' || overflowY == 'scroll'); + }, + horizontallyScrollableContext: function() { + var + overflowX = ($context.get(0) !== window) + ? $context.css('overflow-X') + : false + ; + return (overflowX == 'auto' || overflowX == 'scroll'); + } + }, + + can: { + activate: function($item) { + if(settings.useLabels) { + return true; + } + if(!module.has.maxSelections()) { + return true; + } + if(module.has.maxSelections() && $item.hasClass(className.active)) { + return true; + } + return false; + }, + openDownward: function($subMenu) { + var + $currentMenu = $subMenu || $menu, + canOpenDownward = true, + onScreen = {}, + calculations + ; + $currentMenu + .addClass(className.loading) + ; + calculations = { + context: { + offset : ($context.get(0) === window) + ? { top: 0, left: 0} + : $context.offset(), + scrollTop : $context.scrollTop(), + height : $context.outerHeight() + }, + menu : { + offset: $currentMenu.offset(), + height: $currentMenu.outerHeight() + } + }; + if(module.is.verticallyScrollableContext()) { + calculations.menu.offset.top += calculations.context.scrollTop; + } + onScreen = { + above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.context.offset.top - calculations.menu.height, + below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top - calculations.context.offset.top + calculations.menu.height + }; + if(onScreen.below) { + module.verbose('Dropdown can fit in context downward', onScreen); + canOpenDownward = true; + } + else if(!onScreen.below && !onScreen.above) { + module.verbose('Dropdown cannot fit in either direction, favoring downward', onScreen); + canOpenDownward = true; + } + else { + module.verbose('Dropdown cannot fit below, opening upward', onScreen); + canOpenDownward = false; + } + $currentMenu.removeClass(className.loading); + return canOpenDownward; + }, + openRightward: function($subMenu) { + var + $currentMenu = $subMenu || $menu, + canOpenRightward = true, + isOffscreenRight = false, + calculations + ; + $currentMenu + .addClass(className.loading) + ; + calculations = { + context: { + offset : ($context.get(0) === window) + ? { top: 0, left: 0} + : $context.offset(), + scrollLeft : $context.scrollLeft(), + width : $context.outerWidth() + }, + menu: { + offset : $currentMenu.offset(), + width : $currentMenu.outerWidth() + } + }; + if(module.is.horizontallyScrollableContext()) { + calculations.menu.offset.left += calculations.context.scrollLeft; + } + isOffscreenRight = (calculations.menu.offset.left - calculations.context.offset.left + calculations.menu.width >= calculations.context.scrollLeft + calculations.context.width); + if(isOffscreenRight) { + module.verbose('Dropdown cannot fit in context rightward', isOffscreenRight); + canOpenRightward = false; + } + $currentMenu.removeClass(className.loading); + return canOpenRightward; + }, + click: function() { + return (hasTouch || settings.on == 'click'); + }, + extendSelect: function() { + return settings.allowAdditions || settings.apiSettings; + }, + show: function() { + return !module.is.disabled() && (module.has.items() || module.has.message()); + }, + useAPI: function() { + return $.fn.api !== undefined; + } + }, + + animate: { + show: function(callback, $subMenu) { + var + $currentMenu = $subMenu || $menu, + start = ($subMenu) + ? function() {} + : function() { + module.hideSubMenus(); + module.hideOthers(); + module.set.active(); + }, + transition + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.verbose('Doing menu show animation', $currentMenu); + module.set.direction($subMenu); + transition = module.get.transition($subMenu); + if( module.is.selection() ) { + module.set.scrollPosition(module.get.selectedItem(), true); + } + if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) { + if(transition == 'none') { + start(); + $currentMenu.transition('show'); + callback.call(element); + } + else if($.fn.transition !== undefined && $module.transition('is supported')) { + $currentMenu + .transition({ + animation : transition + ' in', + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + queue : true, + onStart : start, + onComplete : function() { + callback.call(element); + } + }) + ; + } + else { + module.error(error.noTransition, transition); + } + } + }, + hide: function(callback, $subMenu) { + var + $currentMenu = $subMenu || $menu, + duration = ($subMenu) + ? (settings.duration * 0.9) + : settings.duration, + start = ($subMenu) + ? function() {} + : function() { + if( module.can.click() ) { + module.unbind.intent(); + } + module.remove.active(); + }, + transition = module.get.transition($subMenu) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) { + module.verbose('Doing menu hide animation', $currentMenu); + + if(transition == 'none') { + start(); + $currentMenu.transition('hide'); + callback.call(element); + } + else if($.fn.transition !== undefined && $module.transition('is supported')) { + $currentMenu + .transition({ + animation : transition + ' out', + duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, + queue : false, + onStart : start, + onComplete : function() { + callback.call(element); + } + }) + ; + } + else { + module.error(error.transition); + } + } + } + }, + + hideAndClear: function() { + module.remove.searchTerm(); + if( module.has.maxSelections() ) { + return; + } + if(module.has.search()) { + module.hide(function() { + module.remove.filteredItem(); + }); + } + else { + module.hide(); + } + }, + + delay: { + show: function() { + module.verbose('Delaying show event to ensure user intent'); + clearTimeout(module.timer); + module.timer = setTimeout(module.show, settings.delay.show); + }, + hide: function() { + module.verbose('Delaying hide event to ensure user intent'); + clearTimeout(module.timer); + module.timer = setTimeout(module.hide, settings.delay.hide); + } + }, + + escape: { + value: function(value) { + var + multipleValues = $.isArray(value), + stringValue = (typeof value === 'string'), + isUnparsable = (!stringValue && !multipleValues), + hasQuotes = (stringValue && value.search(regExp.quote) !== -1), + values = [] + ; + if(isUnparsable || !hasQuotes) { + return value; + } + module.debug('Encoding quote values for use in select', value); + if(multipleValues) { + $.each(value, function(index, value){ + values.push(value.replace(regExp.quote, '"')); + }); + return values; + } + return value.replace(regExp.quote, '"'); + }, + string: function(text) { + text = String(text); + return text.replace(regExp.escape, '\\$&'); + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + return (returnedValue !== undefined) + ? returnedValue + : $allModules + ; +}; + +$.fn.dropdown.settings = { + + silent : false, + debug : false, + verbose : false, + performance : true, + + on : 'click', // what event should show menu action on item selection + action : 'activate', // action on item selection (nothing, activate, select, combo, hide, function(){}) + + values : false, // specify values to use for dropdown + + clearable : false, // whether the value of the dropdown can be cleared + + apiSettings : false, + selectOnKeydown : true, // Whether selection should occur automatically when keyboard shortcuts used + minCharacters : 0, // Minimum characters required to trigger API call + + filterRemoteData : false, // Whether API results should be filtered after being returned for query term + saveRemoteData : true, // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh + + throttle : 200, // How long to wait after last user input to search remotely + + context : window, // Context to use when determining if on screen + direction : 'auto', // Whether dropdown should always open in one direction + keepOnScreen : true, // Whether dropdown should check whether it is on screen before showing + + match : 'both', // what to match against with search selection (both, text, or label) + fullTextSearch : false, // search anywhere in value (set to 'exact' to require exact matches) + + placeholder : 'auto', // whether to convert blank the values will be delimited with this character + + showOnFocus : true, // show menu on focus + allowReselection : false, // whether current value should trigger callbacks when reselected + allowTab : true, // add tabindex to element + allowCategorySelection : false, // allow elements with sub-menus to be selected + + fireOnInit : false, // Whether callbacks should fire when initializing dropdown values + + transition : 'auto', // auto transition will slide down or up based on direction + duration : 200, // duration of transition + + glyphWidth : 1.037, // widest glyph width in em (W is 1.037 em) used to calculate multiselect input width + + // label settings on multi-select + label: { + transition : 'scale', + duration : 200, + variation : false + }, + + // delay before event + delay : { + hide : 300, + show : 200, + search : 20, + touch : 50 + }, + + /* Callbacks */ + onChange : function(value, text, $selected){}, + onAdd : function(value, text, $selected){}, + onRemove : function(value, text, $selected){}, + + onLabelSelect : function($selectedLabels){}, + onLabelCreate : function(value, text) { return $(this); }, + onLabelRemove : function(value) { return true; }, + onNoResults : function(searchTerm) { return true; }, + onShow : function(){}, + onHide : function(){}, + + /* Component */ + name : 'Dropdown', + namespace : 'dropdown', + + message: { + addResult : 'Add {term}', + count : '{count} selected', + maxSelections : 'Max {maxCount} selections', + noResults : 'No results found.', + serverError : 'There was an error contacting the server' + }, + + error : { + action : 'You called a dropdown action that was not defined', + alreadySetup : 'Once a select has been initialized behaviors must be called on the created ui dropdown', + labels : 'Allowing user additions currently requires the use of labels.', + missingMultiple : ' removing selected option",e),i=m.remove.arrayValue(e,a),m.remove.optionValue(e)):(m.verbose("Removing from delimited values",e),i=(i=m.remove.arrayValue(e,a)).join(h.delimiter)),!1===h.fireOnInit&&m.is.initialLoad()?m.verbose("No callback on initial load",h.onRemove):h.onRemove.call(M,e,t,n),m.set.value(i,t,n),m.check.maxSelections()},arrayValue:function(t,e){return X.isArray(e)||(e=[e]),e=X.grep(e,function(e){return t!=e}),m.verbose("Removed value from delimited string",t,e),e},label:function(e,t){var n=S.find(w.label).filter("[data-"+b.value+'="'+m.escape.string(e)+'"]');m.verbose("Removing label",n),n.remove()},activeLabels:function(e){e=e||S.find(w.label).filter("."+g.active),m.verbose("Removing active label selections",e),m.remove.labels(e)},labels:function(e){e=e||S.find(w.label),m.verbose("Removing labels",e),e.each(function(){var e=X(this),t=e.data(b.value),n=t!==J?String(t):t,i=m.is.userValue(n);!1!==h.onLabelRemove.call(e,t)?(m.remove.message(),i?(m.remove.value(n),m.remove.label(n)):m.remove.selected(n)):m.debug("Label remove callback cancelled removal")})},tabbable:function(){m.is.searchSelection()?(m.debug("Searchable dropdown initialized"),T.removeAttr("tabindex")):(m.debug("Simple selection dropdown initialized"),S.removeAttr("tabindex")),q.removeAttr("tabindex")},clearable:function(){I.removeClass(g.clear)}},has:{menuSearch:function(){return m.has.search()&&0=h.minCharacters},firstLetter:function(e,t){var n;return!(!e||0===e.length||"string"!=typeof t)&&(n=m.get.choiceText(e,!1),(t=t.toLowerCase())==String(n).charAt(0).toLowerCase())},input:function(){return 0=h.maxSelections},allResultsFiltered:function(){var e=R.not(w.addition);return e.filter(w.unselectable).length===e.length},userSuggestion:function(){return 0=n.menu.offset.top-n.context.offset.top+n.menu.height}).below?(m.verbose("Dropdown can fit in context downward",t),!0):t.below||t.above?(m.verbose("Dropdown cannot fit below, opening upward",t),!1):(m.verbose("Dropdown cannot fit in either direction, favoring downward",t),!0),i.removeClass(g.loading),a},openRightward:function(e){var t,n,i=e||q,a=!0;return i.addClass(g.loading),n={context:{offset:y.get(0)===Y?{top:0,left:0}:y.offset(),scrollLeft:y.scrollLeft(),width:y.outerWidth()},menu:{offset:i.offset(),width:i.outerWidth()}},m.is.horizontallyScrollableContext()&&(n.menu.offset.left+=n.context.scrollLeft),(t=n.menu.offset.left-n.context.offset.left+n.menu.width>=n.context.scrollLeft+n.context.width)&&(m.verbose("Dropdown cannot fit in context rightward",t),a=!1),i.removeClass(g.loading),a},click:function(){return U||"click"==h.on},extendSelect:function(){return h.allowAdditions||h.apiSettings},show:function(){return!m.is.disabled()&&(m.has.items()||m.has.message())},useAPI:function(){return X.fn.api!==J}},animate:{show:function(e,t){var n,i=t||q,a=t?function(){}:function(){m.hideSubMenus(),m.hideOthers(),m.set.active()};e=X.isFunction(e)?e:function(){},m.verbose("Doing menu show animation",i),m.set.direction(t),n=m.get.transition(t),m.is.selection()&&m.set.scrollPosition(m.get.selectedItem(),!0),(m.is.hidden(i)||m.is.animating(i))&&("none"==n?(a(),i.transition("show"),e.call(M)):X.fn.transition!==J&&S.transition("is supported")?i.transition({animation:n+" in",debug:h.debug,verbose:h.verbose,duration:h.duration,queue:!0,onStart:a,onComplete:function(){e.call(M)}}):m.error(v.noTransition,n))},hide:function(e,t){var n=t||q,i=(t?h.duration:h.duration,t?function(){}:function(){m.can.click()&&m.unbind.intent(),m.remove.active()}),a=m.get.transition(t);e=X.isFunction(e)?e:function(){},(m.is.visible(n)||m.is.animating(n))&&(m.verbose("Doing menu hide animation",n),"none"==a?(i(),n.transition("hide"),e.call(M)):X.fn.transition!==J&&S.transition("is supported")?n.transition({animation:a+" out",duration:h.duration,debug:h.debug,verbose:h.verbose,queue:!1,onStart:i,onComplete:function(){e.call(M)}}):m.error(v.transition))}},hideAndClear:function(){m.remove.searchTerm(),m.has.maxSelections()||(m.has.search()?m.hide(function(){m.remove.filteredItem()}):m.hide())},delay:{show:function(){m.verbose("Delaying show event to ensure user intent"),clearTimeout(m.timer),m.timer=setTimeout(m.show,h.delay.show)},hide:function(){m.verbose("Delaying hide event to ensure user intent"),clearTimeout(m.timer),m.timer=setTimeout(m.hide,h.delay.hide)}},escape:{value:function(e){var t=X.isArray(e),n="string"==typeof e,i=!n&&!t,a=n&&-1!==e.search(d.quote),o=[];return i||!a?e:(m.debug("Encoding quote values for use in select",e),t?(X.each(e,function(e,t){o.push(t.replace(d.quote,"""))}),o):e.replace(d.quote,"""))},string:function(e){return(e=String(e)).replace(d.escape,"\\$&")}},setting:function(e,t){if(m.debug("Changing setting",e,t),X.isPlainObject(e))X.extend(!0,h,e);else{if(t===J)return h[e];X.isPlainObject(h[e])?X.extend(!0,h[e],t):h[e]=t}},internal:function(e,t){if(X.isPlainObject(e))X.extend(!0,m,e);else{if(t===J)return m[e];m[e]=t}},debug:function(){!h.silent&&h.debug&&(h.performance?m.performance.log(arguments):(m.debug=Function.prototype.bind.call(console.info,console,h.name+":"),m.debug.apply(console,arguments)))},verbose:function(){!h.silent&&h.verbose&&h.debug&&(h.performance?m.performance.log(arguments):(m.verbose=Function.prototype.bind.call(console.info,console,h.name+":"),m.verbose.apply(console,arguments)))},error:function(){h.silent||(m.error=Function.prototype.bind.call(console.error,console,h.name+":"),m.error.apply(console,arguments))},performance:{log:function(e){var t,n;h.performance&&(n=(t=(new Date).getTime())-(K||t),K=t,W.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:M,"Execution Time":n})),clearTimeout(m.performance.timer),m.performance.timer=setTimeout(m.performance.display,500)},display:function(){var e=h.name+":",n=0;K=!1,clearTimeout(m.performance.timer),X.each(W,function(e,t){n+=t["Execution Time"]}),e+=" "+n+"ms",N&&(e+=" '"+N+"'"),(console.group!==J||console.table!==J)&&0{term}",count:"{count} selected",maxSelections:"Max {maxCount} selections",noResults:"No results found.",serverError:"There was an error contacting the server"},error:{action:"You called a dropdown action that was not defined",alreadySetup:"Once a select has been initialized behaviors must be called on the created ui dropdown",labels:"Allowing user additions currently requires the use of labels.",missingMultiple:"",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("' + ; + }, + placeholder : function(image, icon) { + var + html = '' + ; + if(icon) { + html += ''; + } + if(image) { + html += ''; + } + return html; + } + }, + + // NOT YET IMPLEMENTED + api : false, + onPause : function() {}, + onPlay : function() {}, + onStop : function() {} + +}; + + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Modal + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.modal = function(parameters) { + var + $allModules = $(this), + $window = $(window), + $document = $(document), + $body = $('body'), + + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.modal.settings, parameters) + : $.extend({}, $.fn.modal.settings), + + selector = settings.selector, + className = settings.className, + namespace = settings.namespace, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $context = $(settings.context), + $close = $module.find(selector.close), + + $allModals, + $otherModals, + $focusedElement, + $dimmable, + $dimmer, + + element = this, + instance = $module.data(moduleNamespace), + + ignoreRepeatedEvents = false, + + elementEventNamespace, + id, + observer, + module + ; + module = { + + initialize: function() { + module.verbose('Initializing dimmer', $context); + + module.create.id(); + module.create.dimmer(); + module.refreshModals(); + + module.bind.events(); + if(settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of modal'); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + create: { + dimmer: function() { + var + defaultSettings = { + debug : settings.debug, + variation : settings.centered + ? false + : 'top aligned', + dimmerName : 'modals' + }, + dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings) + ; + if($.fn.dimmer === undefined) { + module.error(error.dimmer); + return; + } + module.debug('Creating dimmer'); + $dimmable = $context.dimmer(dimmerSettings); + if(settings.detachable) { + module.verbose('Modal is detachable, moving content into dimmer'); + $dimmable.dimmer('add content', $module); + } + else { + module.set.undetached(); + } + $dimmer = $dimmable.dimmer('get dimmer'); + }, + id: function() { + id = (Math.random().toString(16) + '000000000').substr(2, 8); + elementEventNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + } + }, + + destroy: function() { + module.verbose('Destroying previous modal'); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + $window.off(elementEventNamespace); + $dimmer.off(elementEventNamespace); + $close.off(eventNamespace); + $context.dimmer('destroy'); + }, + + observeChanges: function() { + if('MutationObserver' in window) { + observer = new MutationObserver(function(mutations) { + module.debug('DOM tree modified, refreshing'); + module.refresh(); + }); + observer.observe(element, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + refresh: function() { + module.remove.scrolling(); + module.cacheSizes(); + if(!module.can.useFlex()) { + module.set.modalOffset(); + } + module.set.screenHeight(); + module.set.type(); + }, + + refreshModals: function() { + $otherModals = $module.siblings(selector.modal); + $allModals = $otherModals.add($module); + }, + + attachEvents: function(selector, event) { + var + $toggle = $(selector) + ; + event = $.isFunction(module[event]) + ? module[event] + : module.toggle + ; + if($toggle.length > 0) { + module.debug('Attaching modal events to element', selector, event); + $toggle + .off(eventNamespace) + .on('click' + eventNamespace, event) + ; + } + else { + module.error(error.notFound, selector); + } + }, + + bind: { + events: function() { + module.verbose('Attaching events'); + $module + .on('click' + eventNamespace, selector.close, module.event.close) + .on('click' + eventNamespace, selector.approve, module.event.approve) + .on('click' + eventNamespace, selector.deny, module.event.deny) + ; + $window + .on('resize' + elementEventNamespace, module.event.resize) + ; + }, + scrollLock: function() { + // touch events default to passive, due to changes in chrome to optimize mobile perf + $dimmable.get(0).addEventListener('touchmove', module.event.preventScroll, { passive: false }); + } + }, + + unbind: { + scrollLock: function() { + $dimmable.get(0).removeEventListener('touchmove', module.event.preventScroll, { passive: false }); + } + }, + + get: { + id: function() { + return (Math.random().toString(16) + '000000000').substr(2, 8); + } + }, + + event: { + approve: function() { + if(ignoreRepeatedEvents || settings.onApprove.call(element, $(this)) === false) { + module.verbose('Approve callback returned false cancelling hide'); + return; + } + ignoreRepeatedEvents = true; + module.hide(function() { + ignoreRepeatedEvents = false; + }); + }, + preventScroll: function(event) { + event.preventDefault(); + }, + deny: function() { + if(ignoreRepeatedEvents || settings.onDeny.call(element, $(this)) === false) { + module.verbose('Deny callback returned false cancelling hide'); + return; + } + ignoreRepeatedEvents = true; + module.hide(function() { + ignoreRepeatedEvents = false; + }); + }, + close: function() { + module.hide(); + }, + click: function(event) { + if(!settings.closable) { + module.verbose('Dimmer clicked but closable setting is disabled'); + return; + } + var + $target = $(event.target), + isInModal = ($target.closest(selector.modal).length > 0), + isInDOM = $.contains(document.documentElement, event.target) + ; + if(!isInModal && isInDOM && module.is.active()) { + module.debug('Dimmer clicked, hiding all modals'); + module.remove.clickaway(); + if(settings.allowMultiple) { + module.hide(); + } + else { + module.hideAll(); + } + } + }, + debounce: function(method, delay) { + clearTimeout(module.timer); + module.timer = setTimeout(method, delay); + }, + keyboard: function(event) { + var + keyCode = event.which, + escapeKey = 27 + ; + if(keyCode == escapeKey) { + if(settings.closable) { + module.debug('Escape key pressed hiding modal'); + module.hide(); + } + else { + module.debug('Escape key pressed, but closable is set to false'); + } + event.preventDefault(); + } + }, + resize: function() { + if( $dimmable.dimmer('is active') && ( module.is.animating() || module.is.active() ) ) { + requestAnimationFrame(module.refresh); + } + } + }, + + toggle: function() { + if( module.is.active() || module.is.animating() ) { + module.hide(); + } + else { + module.show(); + } + }, + + show: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.refreshModals(); + module.set.dimmerSettings(); + module.set.dimmerStyles(); + + module.showModal(callback); + }, + + hide: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.refreshModals(); + module.hideModal(callback); + }, + + showModal: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.animating() || !module.is.active() ) { + module.showDimmer(); + module.cacheSizes(); + if(module.can.useFlex()) { + module.remove.legacy(); + } + else { + module.set.legacy(); + module.set.modalOffset(); + module.debug('Using non-flex legacy modal positioning.'); + } + module.set.screenHeight(); + module.set.type(); + module.set.clickaway(); + + if( !settings.allowMultiple && module.others.active() ) { + module.hideOthers(module.showModal); + } + else { + if(settings.allowMultiple && settings.detachable) { + $module.detach().appendTo($dimmer); + } + settings.onShow.call(element); + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + module.debug('Showing modal with css animations'); + $module + .transition({ + debug : settings.debug, + animation : settings.transition + ' in', + queue : settings.queue, + duration : settings.duration, + useFailSafe : true, + onComplete : function() { + settings.onVisible.apply(element); + if(settings.keyboardShortcuts) { + module.add.keyboardShortcuts(); + } + module.save.focus(); + module.set.active(); + if(settings.autofocus) { + module.set.autofocus(); + } + callback(); + } + }) + ; + } + else { + module.error(error.noTransition); + } + } + } + else { + module.debug('Modal is already visible'); + } + }, + + hideModal: function(callback, keepDimmed) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.debug('Hiding modal'); + if(settings.onHide.call(element, $(this)) === false) { + module.verbose('Hide callback returned false cancelling hide'); + return; + } + + if( module.is.animating() || module.is.active() ) { + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + module.remove.active(); + $module + .transition({ + debug : settings.debug, + animation : settings.transition + ' out', + queue : settings.queue, + duration : settings.duration, + useFailSafe : true, + onStart : function() { + if(!module.others.active() && !keepDimmed) { + module.hideDimmer(); + } + if(settings.keyboardShortcuts) { + module.remove.keyboardShortcuts(); + } + }, + onComplete : function() { + settings.onHidden.call(element); + module.remove.dimmerStyles(); + module.restore.focus(); + callback(); + } + }) + ; + } + else { + module.error(error.noTransition); + } + } + }, + + showDimmer: function() { + if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) { + module.debug('Showing dimmer'); + $dimmable.dimmer('show'); + } + else { + module.debug('Dimmer already visible'); + } + }, + + hideDimmer: function() { + if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) { + module.unbind.scrollLock(); + $dimmable.dimmer('hide', function() { + module.remove.clickaway(); + module.remove.screenHeight(); + }); + } + else { + module.debug('Dimmer is not visible cannot hide'); + return; + } + }, + + hideAll: function(callback) { + var + $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( $visibleModals.length > 0 ) { + module.debug('Hiding all visible modals'); + module.hideDimmer(); + $visibleModals + .modal('hide modal', callback) + ; + } + }, + + hideOthers: function(callback) { + var + $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating) + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( $visibleModals.length > 0 ) { + module.debug('Hiding other modals', $otherModals); + $visibleModals + .modal('hide modal', callback, true) + ; + } + }, + + others: { + active: function() { + return ($otherModals.filter('.' + className.active).length > 0); + }, + animating: function() { + return ($otherModals.filter('.' + className.animating).length > 0); + } + }, + + + add: { + keyboardShortcuts: function() { + module.verbose('Adding keyboard shortcuts'); + $document + .on('keyup' + eventNamespace, module.event.keyboard) + ; + } + }, + + save: { + focus: function() { + var + $activeElement = $(document.activeElement), + inCurrentModal = $activeElement.closest($module).length > 0 + ; + if(!inCurrentModal) { + $focusedElement = $(document.activeElement).blur(); + } + } + }, + + restore: { + focus: function() { + if($focusedElement && $focusedElement.length > 0) { + $focusedElement.focus(); + } + } + }, + + remove: { + active: function() { + $module.removeClass(className.active); + }, + legacy: function() { + $module.removeClass(className.legacy); + }, + clickaway: function() { + $dimmer + .off('click' + elementEventNamespace) + ; + }, + dimmerStyles: function() { + $dimmer.removeClass(className.inverted); + $dimmable.removeClass(className.blurring); + }, + bodyStyle: function() { + if($body.attr('style') === '') { + module.verbose('Removing style attribute'); + $body.removeAttr('style'); + } + }, + screenHeight: function() { + module.debug('Removing page height'); + $body + .css('height', '') + ; + }, + keyboardShortcuts: function() { + module.verbose('Removing keyboard shortcuts'); + $document + .off('keyup' + eventNamespace) + ; + }, + scrolling: function() { + $dimmable.removeClass(className.scrolling); + $module.removeClass(className.scrolling); + } + }, + + cacheSizes: function() { + $module.addClass(className.loading); + var + scrollHeight = $module.prop('scrollHeight'), + modalWidth = $module.outerWidth(), + modalHeight = $module.outerHeight() + ; + if(module.cache === undefined || modalHeight !== 0) { + module.cache = { + pageHeight : $(document).outerHeight(), + width : modalWidth, + height : modalHeight + settings.offset, + scrollHeight : scrollHeight + settings.offset, + contextHeight : (settings.context == 'body') + ? $(window).height() + : $dimmable.height(), + }; + module.cache.topOffset = -(module.cache.height / 2); + } + $module.removeClass(className.loading); + module.debug('Caching modal and container sizes', module.cache); + }, + + can: { + useFlex: function() { + return (settings.useFlex == 'auto') + ? settings.detachable && !module.is.ie() + : settings.useFlex + ; + }, + fit: function() { + var + contextHeight = module.cache.contextHeight, + verticalCenter = module.cache.contextHeight / 2, + topOffset = module.cache.topOffset, + scrollHeight = module.cache.scrollHeight, + height = module.cache.height, + paddingHeight = settings.padding, + startPosition = (verticalCenter + topOffset) + ; + return (scrollHeight > height) + ? (startPosition + scrollHeight + paddingHeight < contextHeight) + : (height + (paddingHeight * 2) < contextHeight) + ; + } + }, + + is: { + active: function() { + return $module.hasClass(className.active); + }, + ie: function() { + var + isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window), + isIE = ('ActiveXObject' in window) + ; + return (isIE11 || isIE); + }, + animating: function() { + return $module.transition('is supported') + ? $module.transition('is animating') + : $module.is(':visible') + ; + }, + scrolling: function() { + return $dimmable.hasClass(className.scrolling); + }, + modernBrowser: function() { + // appName for IE11 reports 'Netscape' can no longer use + return !(window.ActiveXObject || 'ActiveXObject' in window); + } + }, + + set: { + autofocus: function() { + var + $inputs = $module.find('[tabindex], :input').filter(':visible'), + $autofocus = $inputs.filter('[autofocus]'), + $input = ($autofocus.length > 0) + ? $autofocus.first() + : $inputs.first() + ; + if($input.length > 0) { + $input.focus(); + } + }, + clickaway: function() { + $dimmer + .on('click' + elementEventNamespace, module.event.click) + ; + }, + dimmerSettings: function() { + if($.fn.dimmer === undefined) { + module.error(error.dimmer); + return; + } + var + defaultSettings = { + debug : settings.debug, + dimmerName : 'modals', + closable : 'auto', + useFlex : module.can.useFlex(), + variation : settings.centered + ? false + : 'top aligned', + duration : { + show : settings.duration, + hide : settings.duration + } + }, + dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings) + ; + if(settings.inverted) { + dimmerSettings.variation = (dimmerSettings.variation !== undefined) + ? dimmerSettings.variation + ' inverted' + : 'inverted' + ; + } + $context.dimmer('setting', dimmerSettings); + }, + dimmerStyles: function() { + if(settings.inverted) { + $dimmer.addClass(className.inverted); + } + else { + $dimmer.removeClass(className.inverted); + } + if(settings.blurring) { + $dimmable.addClass(className.blurring); + } + else { + $dimmable.removeClass(className.blurring); + } + }, + modalOffset: function() { + var + width = module.cache.width, + height = module.cache.height + ; + $module + .css({ + marginTop: (settings.centered && module.can.fit()) + ? -(height / 2) + : 0, + marginLeft: -(width / 2) + }) + ; + module.verbose('Setting modal offset for legacy mode'); + }, + screenHeight: function() { + if( module.can.fit() ) { + $body.css('height', ''); + } + else { + module.debug('Modal is taller than page content, resizing page height'); + $body + .css('height', module.cache.height + (settings.padding * 2) ) + ; + } + }, + active: function() { + $module.addClass(className.active); + }, + scrolling: function() { + $dimmable.addClass(className.scrolling); + $module.addClass(className.scrolling); + module.unbind.scrollLock(); + }, + legacy: function() { + $module.addClass(className.legacy); + }, + type: function() { + if(module.can.fit()) { + module.verbose('Modal fits on screen'); + if(!module.others.active() && !module.others.animating()) { + module.remove.scrolling(); + module.bind.scrollLock(); + } + } + else { + module.verbose('Modal cannot fit on screen setting to scrolling'); + module.set.scrolling(); + } + }, + undetached: function() { + $dimmable.addClass(className.undetached); + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.modal.settings = { + + name : 'Modal', + namespace : 'modal', + + useFlex : 'auto', + offset : 0, + + silent : false, + debug : false, + verbose : false, + performance : true, + + observeChanges : false, + + allowMultiple : false, + detachable : true, + closable : true, + autofocus : true, + + inverted : false, + blurring : false, + + centered : true, + + dimmerSettings : { + closable : false, + useCSS : true + }, + + // whether to use keyboard shortcuts + keyboardShortcuts: true, + + context : 'body', + + queue : false, + duration : 500, + transition : 'scale', + + // padding with edge of page + padding : 50, + + // called before show animation + onShow : function(){}, + + // called after show animation + onVisible : function(){}, + + // called before hide animation + onHide : function(){ return true; }, + + // called after hide animation + onHidden : function(){}, + + // called after approve selector match + onApprove : function(){ return true; }, + + // called after deny selector match + onDeny : function(){ return true; }, + + selector : { + close : '> .close', + approve : '.actions .positive, .actions .approve, .actions .ok', + deny : '.actions .negative, .actions .deny, .actions .cancel', + modal : '.ui.modal' + }, + error : { + dimmer : 'UI Dimmer, a required component is not included in this page', + method : 'The method you called is not defined.', + notFound : 'The element you specified could not be found' + }, + className : { + active : 'active', + animating : 'animating', + blurring : 'blurring', + inverted : 'inverted', + legacy : 'legacy', + loading : 'loading', + scrolling : 'scrolling', + undetached : 'undetached' + } +}; + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Nag + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.nag = function(parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.nag.settings, parameters) + : $.extend({}, $.fn.nag.settings), + + className = settings.className, + selector = settings.selector, + error = settings.error, + namespace = settings.namespace, + + eventNamespace = '.' + namespace, + moduleNamespace = namespace + '-module', + + $module = $(this), + + $close = $module.find(selector.close), + $context = (settings.context) + ? $(settings.context) + : $('body'), + + element = this, + instance = $module.data(moduleNamespace), + + moduleOffset, + moduleHeight, + + contextWidth, + contextHeight, + contextOffset, + + yOffset, + yPosition, + + timer, + module, + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); } + ; + module = { + + initialize: function() { + module.verbose('Initializing element'); + + $module + .on('click' + eventNamespace, selector.close, module.dismiss) + .data(moduleNamespace, module) + ; + + if(settings.detachable && $module.parent()[0] !== $context[0]) { + $module + .detach() + .prependTo($context) + ; + } + + if(settings.displayTime > 0) { + setTimeout(module.hide, settings.displayTime); + } + module.show(); + }, + + destroy: function() { + module.verbose('Destroying instance'); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + show: function() { + if( module.should.show() && !$module.is(':visible') ) { + module.debug('Showing nag', settings.animation.show); + if(settings.animation.show == 'fade') { + $module + .fadeIn(settings.duration, settings.easing) + ; + } + else { + $module + .slideDown(settings.duration, settings.easing) + ; + } + } + }, + + hide: function() { + module.debug('Showing nag', settings.animation.hide); + if(settings.animation.show == 'fade') { + $module + .fadeIn(settings.duration, settings.easing) + ; + } + else { + $module + .slideUp(settings.duration, settings.easing) + ; + } + }, + + onHide: function() { + module.debug('Removing nag', settings.animation.hide); + $module.remove(); + if (settings.onHide) { + settings.onHide(); + } + }, + + dismiss: function(event) { + if(settings.storageMethod) { + module.storage.set(settings.key, settings.value); + } + module.hide(); + event.stopImmediatePropagation(); + event.preventDefault(); + }, + + should: { + show: function() { + if(settings.persist) { + module.debug('Persistent nag is set, can show nag'); + return true; + } + if( module.storage.get(settings.key) != settings.value.toString() ) { + module.debug('Stored value is not set, can show nag', module.storage.get(settings.key)); + return true; + } + module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key)); + return false; + } + }, + + get: { + storageOptions: function() { + var + options = {} + ; + if(settings.expires) { + options.expires = settings.expires; + } + if(settings.domain) { + options.domain = settings.domain; + } + if(settings.path) { + options.path = settings.path; + } + return options; + } + }, + + clear: function() { + module.storage.remove(settings.key); + }, + + storage: { + set: function(key, value) { + var + options = module.get.storageOptions() + ; + if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { + window.localStorage.setItem(key, value); + module.debug('Value stored using local storage', key, value); + } + else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { + window.sessionStorage.setItem(key, value); + module.debug('Value stored using session storage', key, value); + } + else if($.cookie !== undefined) { + $.cookie(key, value, options); + module.debug('Value stored using cookie', key, value, options); + } + else { + module.error(error.noCookieStorage); + return; + } + }, + get: function(key, value) { + var + storedValue + ; + if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { + storedValue = window.localStorage.getItem(key); + } + else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { + storedValue = window.sessionStorage.getItem(key); + } + // get by cookie + else if($.cookie !== undefined) { + storedValue = $.cookie(key); + } + else { + module.error(error.noCookieStorage); + } + if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) { + storedValue = undefined; + } + return storedValue; + }, + remove: function(key) { + var + options = module.get.storageOptions() + ; + if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) { + window.localStorage.removeItem(key); + } + else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) { + window.sessionStorage.removeItem(key); + } + // store by cookie + else if($.cookie !== undefined) { + $.removeCookie(key, options); + } + else { + module.error(error.noStorage); + } + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.nag.settings = { + + name : 'Nag', + + silent : false, + debug : false, + verbose : false, + performance : true, + + namespace : 'Nag', + + // allows cookie to be overridden + persist : false, + + // set to zero to require manually dismissal, otherwise hides on its own + displayTime : 0, + + animation : { + show : 'slide', + hide : 'slide' + }, + + context : false, + detachable : false, + + expires : 30, + domain : false, + path : '/', + + // type of storage to use + storageMethod : 'cookie', + + // value to store in dismissed localstorage/cookie + key : 'nag', + value : 'dismiss', + + error: { + noCookieStorage : '$.cookie is not included. A storage solution is required.', + noStorage : 'Neither $.cookie or store is defined. A storage solution is required for storing state', + method : 'The method you called is not defined.' + }, + + className : { + bottom : 'bottom', + fixed : 'fixed' + }, + + selector : { + close : '.close.icon' + }, + + speed : 500, + easing : 'easeOutQuad', + + onHide: function() {} + +}; + +// Adds easing +$.extend( $.easing, { + easeOutQuad: function (x, t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + } +}); + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Popup + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.popup = function(parameters) { + var + $allModules = $(this), + $document = $(document), + $window = $(window), + $body = $('body'), + + moduleSelector = $allModules.selector || '', + + hasTouch = (true), + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.popup.settings, parameters) + : $.extend({}, $.fn.popup.settings), + + selector = settings.selector, + className = settings.className, + error = settings.error, + metadata = settings.metadata, + namespace = settings.namespace, + + eventNamespace = '.' + settings.namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $context = $(settings.context), + $scrollContext = $(settings.scrollContext), + $boundary = $(settings.boundary), + $target = (settings.target) + ? $(settings.target) + : $module, + + $popup, + $offsetParent, + + searchDepth = 0, + triedPositions = false, + openedWithTouch = false, + + element = this, + instance = $module.data(moduleNamespace), + + documentObserver, + elementNamespace, + id, + module + ; + + module = { + + // binds events + initialize: function() { + module.debug('Initializing', $module); + module.createID(); + module.bind.events(); + if(!module.exists() && settings.preserve) { + module.create(); + } + if(settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + observeChanges: function() { + if('MutationObserver' in window) { + documentObserver = new MutationObserver(module.event.documentChanged); + documentObserver.observe(document, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', documentObserver); + } + }, + + refresh: function() { + if(settings.popup) { + $popup = $(settings.popup).eq(0); + } + else { + if(settings.inline) { + $popup = $target.nextAll(selector.popup).eq(0); + settings.popup = $popup; + } + } + if(settings.popup) { + $popup.addClass(className.loading); + $offsetParent = module.get.offsetParent(); + $popup.removeClass(className.loading); + if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) { + module.debug('Moving popup to the same offset parent as target'); + $popup + .detach() + .appendTo($offsetParent) + ; + } + } + else { + $offsetParent = (settings.inline) + ? module.get.offsetParent($target) + : module.has.popup() + ? module.get.offsetParent($popup) + : $body + ; + } + if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) { + module.debug('Setting page as offset parent'); + $offsetParent = $body; + } + if( module.get.variation() ) { + module.set.variation(); + } + }, + + reposition: function() { + module.refresh(); + module.set.position(); + }, + + destroy: function() { + module.debug('Destroying previous module'); + if(documentObserver) { + documentObserver.disconnect(); + } + // remove element only if was created dynamically + if($popup && !settings.preserve) { + module.removePopup(); + } + // clear all timeouts + clearTimeout(module.hideTimer); + clearTimeout(module.showTimer); + // remove events + module.unbind.close(); + module.unbind.events(); + $module + .removeData(moduleNamespace) + ; + }, + + event: { + start: function(event) { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.show + : settings.delay + ; + clearTimeout(module.hideTimer); + if(!openedWithTouch) { + module.showTimer = setTimeout(module.show, delay); + } + }, + end: function() { + var + delay = ($.isPlainObject(settings.delay)) + ? settings.delay.hide + : settings.delay + ; + clearTimeout(module.showTimer); + module.hideTimer = setTimeout(module.hide, delay); + }, + touchstart: function(event) { + openedWithTouch = true; + module.show(); + }, + resize: function() { + if( module.is.visible() ) { + module.set.position(); + } + }, + documentChanged: function(mutations) { + [].forEach.call(mutations, function(mutation) { + if(mutation.removedNodes) { + [].forEach.call(mutation.removedNodes, function(node) { + if(node == element || $(node).find(element).length > 0) { + module.debug('Element removed from DOM, tearing down events'); + module.destroy(); + } + }); + } + }); + }, + hideGracefully: function(event) { + var + $target = $(event.target), + isInDOM = $.contains(document.documentElement, event.target), + inPopup = ($target.closest(selector.popup).length > 0) + ; + // don't close on clicks inside popup + if(event && !inPopup && isInDOM) { + module.debug('Click occurred outside popup hiding popup'); + module.hide(); + } + else { + module.debug('Click was inside popup, keeping popup open'); + } + } + }, + + // generates popup html from metadata + create: function() { + var + html = module.get.html(), + title = module.get.title(), + content = module.get.content() + ; + + if(html || content || title) { + module.debug('Creating pop-up html'); + if(!html) { + html = settings.templates.popup({ + title : title, + content : content + }); + } + $popup = $('
') + .addClass(className.popup) + .data(metadata.activator, $module) + .html(html) + ; + if(settings.inline) { + module.verbose('Inserting popup element inline', $popup); + $popup + .insertAfter($module) + ; + } + else { + module.verbose('Appending popup element to body', $popup); + $popup + .appendTo( $context ) + ; + } + module.refresh(); + module.set.variation(); + + if(settings.hoverable) { + module.bind.popup(); + } + settings.onCreate.call($popup, element); + } + else if($target.next(selector.popup).length !== 0) { + module.verbose('Pre-existing popup found'); + settings.inline = true; + settings.popup = $target.next(selector.popup).data(metadata.activator, $module); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else if(settings.popup) { + $(settings.popup).data(metadata.activator, $module); + module.verbose('Used popup specified in settings'); + module.refresh(); + if(settings.hoverable) { + module.bind.popup(); + } + } + else { + module.debug('No content specified skipping display', element); + } + }, + + createID: function() { + id = (Math.random().toString(16) + '000000000').substr(2, 8); + elementNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + }, + + // determines popup state + toggle: function() { + module.debug('Toggling pop-up'); + if( module.is.hidden() ) { + module.debug('Popup is hidden, showing pop-up'); + module.unbind.close(); + module.show(); + } + else { + module.debug('Popup is visible, hiding pop-up'); + module.hide(); + } + }, + + show: function(callback) { + callback = callback || function(){}; + module.debug('Showing pop-up', settings.transition); + if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { + if( !module.exists() ) { + module.create(); + } + if(settings.onShow.call($popup, element) === false) { + module.debug('onShow callback returned false, cancelling popup animation'); + return; + } + else if(!settings.preserve && !settings.popup) { + module.refresh(); + } + if( $popup && module.set.position() ) { + module.save.conditions(); + if(settings.exclusive) { + module.hideAll(); + } + module.animate.show(callback); + } + } + }, + + + hide: function(callback) { + callback = callback || function(){}; + if( module.is.visible() || module.is.animating() ) { + if(settings.onHide.call($popup, element) === false) { + module.debug('onHide callback returned false, cancelling popup animation'); + return; + } + module.remove.visible(); + module.unbind.close(); + module.restore.conditions(); + module.animate.hide(callback); + } + }, + + hideAll: function() { + $(selector.popup) + .filter('.' + className.popupVisible) + .each(function() { + $(this) + .data(metadata.activator) + .popup('hide') + ; + }) + ; + }, + exists: function() { + if(!$popup) { + return false; + } + if(settings.inline || settings.popup) { + return ( module.has.popup() ); + } + else { + return ( $popup.closest($context).length >= 1 ) + ? true + : false + ; + } + }, + + removePopup: function() { + if( module.has.popup() && !settings.popup) { + module.debug('Removing popup', $popup); + $popup.remove(); + $popup = undefined; + settings.onRemove.call($popup, element); + } + }, + + save: { + conditions: function() { + module.cache = { + title: $module.attr('title') + }; + if (module.cache.title) { + $module.removeAttr('title'); + } + module.verbose('Saving original attributes', module.cache.title); + } + }, + restore: { + conditions: function() { + if(module.cache && module.cache.title) { + $module.attr('title', module.cache.title); + module.verbose('Restoring original attributes', module.cache.title); + } + return true; + } + }, + supports: { + svg: function() { + return (typeof SVGGraphicsElement === 'undefined'); + } + }, + animate: { + show: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + module.set.visible(); + $popup + .transition({ + animation : settings.transition + ' in', + queue : false, + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { + module.bind.close(); + callback.call($popup, element); + settings.onVisible.call($popup, element); + } + }) + ; + } + else { + module.error(error.noTransition); + } + }, + hide: function(callback) { + callback = $.isFunction(callback) ? callback : function(){}; + module.debug('Hiding pop-up'); + if(settings.onHide.call($popup, element) === false) { + module.debug('onHide callback returned false, cancelling popup animation'); + return; + } + if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { + $popup + .transition({ + animation : settings.transition + ' out', + queue : false, + duration : settings.duration, + debug : settings.debug, + verbose : settings.verbose, + onComplete : function() { + module.reset(); + callback.call($popup, element); + settings.onHidden.call($popup, element); + } + }) + ; + } + else { + module.error(error.noTransition); + } + } + }, + + change: { + content: function(html) { + $popup.html(html); + } + }, + + get: { + html: function() { + $module.removeData(metadata.html); + return $module.data(metadata.html) || settings.html; + }, + title: function() { + $module.removeData(metadata.title); + return $module.data(metadata.title) || settings.title; + }, + content: function() { + $module.removeData(metadata.content); + return $module.data(metadata.content) || settings.content || $module.attr('title'); + }, + variation: function() { + $module.removeData(metadata.variation); + return $module.data(metadata.variation) || settings.variation; + }, + popup: function() { + return $popup; + }, + popupOffset: function() { + return $popup.offset(); + }, + calculations: function() { + var + $popupOffsetParent = module.get.offsetParent($popup), + targetElement = $target[0], + isWindow = ($boundary[0] == window), + targetPosition = (settings.inline || (settings.popup && settings.movePopup)) + ? $target.position() + : $target.offset(), + screenPosition = (isWindow) + ? { top: 0, left: 0 } + : $boundary.offset(), + calculations = {}, + scroll = (isWindow) + ? { top: $window.scrollTop(), left: $window.scrollLeft() } + : { top: 0, left: 0}, + screen + ; + calculations = { + // element which is launching popup + target : { + element : $target[0], + width : $target.outerWidth(), + height : $target.outerHeight(), + top : targetPosition.top, + left : targetPosition.left, + margin : {} + }, + // popup itself + popup : { + width : $popup.outerWidth(), + height : $popup.outerHeight() + }, + // offset container (or 3d context) + parent : { + width : $offsetParent.outerWidth(), + height : $offsetParent.outerHeight() + }, + // screen boundaries + screen : { + top : screenPosition.top, + left : screenPosition.left, + scroll: { + top : scroll.top, + left : scroll.left + }, + width : $boundary.width(), + height : $boundary.height() + } + }; + + // if popup offset context is not same as target, then adjust calculations + if($popupOffsetParent.get(0) !== $offsetParent.get(0)) { + var + popupOffset = $popupOffsetParent.offset() + ; + calculations.target.top -= popupOffset.top; + calculations.target.left -= popupOffset.left; + calculations.parent.width = $popupOffsetParent.outerWidth(); + calculations.parent.height = $popupOffsetParent.outerHeight(); + } + + // add in container calcs if fluid + if( settings.setFluidWidth && module.is.fluid() ) { + calculations.container = { + width: $popup.parent().outerWidth() + }; + calculations.popup.width = calculations.container.width; + } + + // add in margins if inline + calculations.target.margin.top = (settings.inline) + ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10) + : 0 + ; + calculations.target.margin.left = (settings.inline) + ? module.is.rtl() + ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10) + : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10) + : 0 + ; + // calculate screen boundaries + screen = calculations.screen; + calculations.boundary = { + top : screen.top + screen.scroll.top, + bottom : screen.top + screen.scroll.top + screen.height, + left : screen.left + screen.scroll.left, + right : screen.left + screen.scroll.left + screen.width + }; + return calculations; + }, + id: function() { + return id; + }, + startEvent: function() { + if(settings.on == 'hover') { + return 'mouseenter'; + } + else if(settings.on == 'focus') { + return 'focus'; + } + return false; + }, + scrollEvent: function() { + return 'scroll'; + }, + endEvent: function() { + if(settings.on == 'hover') { + return 'mouseleave'; + } + else if(settings.on == 'focus') { + return 'blur'; + } + return false; + }, + distanceFromBoundary: function(offset, calculations) { + var + distanceFromBoundary = {}, + popup, + boundary + ; + calculations = calculations || module.get.calculations(); + + // shorthand + popup = calculations.popup; + boundary = calculations.boundary; + + if(offset) { + distanceFromBoundary = { + top : (offset.top - boundary.top), + left : (offset.left - boundary.left), + right : (boundary.right - (offset.left + popup.width) ), + bottom : (boundary.bottom - (offset.top + popup.height) ) + }; + module.verbose('Distance from boundaries determined', offset, distanceFromBoundary); + } + return distanceFromBoundary; + }, + offsetParent: function($element) { + var + element = ($element !== undefined) + ? $element[0] + : $target[0], + parentNode = element.parentNode, + $node = $(parentNode) + ; + if(parentNode) { + var + is2D = ($node.css('transform') === 'none'), + isStatic = ($node.css('position') === 'static'), + isBody = $node.is('body') + ; + while(parentNode && !isBody && isStatic && is2D) { + parentNode = parentNode.parentNode; + $node = $(parentNode); + is2D = ($node.css('transform') === 'none'); + isStatic = ($node.css('position') === 'static'); + isBody = $node.is('body'); + } + } + return ($node && $node.length > 0) + ? $node + : $() + ; + }, + positions: function() { + return { + 'top left' : false, + 'top center' : false, + 'top right' : false, + 'bottom left' : false, + 'bottom center' : false, + 'bottom right' : false, + 'left center' : false, + 'right center' : false + }; + }, + nextPosition: function(position) { + var + positions = position.split(' '), + verticalPosition = positions[0], + horizontalPosition = positions[1], + opposite = { + top : 'bottom', + bottom : 'top', + left : 'right', + right : 'left' + }, + adjacent = { + left : 'center', + center : 'right', + right : 'left' + }, + backup = { + 'top left' : 'top center', + 'top center' : 'top right', + 'top right' : 'right center', + 'right center' : 'bottom right', + 'bottom right' : 'bottom center', + 'bottom center' : 'bottom left', + 'bottom left' : 'left center', + 'left center' : 'top left' + }, + adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'), + oppositeTried = false, + adjacentTried = false, + nextPosition = false + ; + if(!triedPositions) { + module.verbose('All available positions available'); + triedPositions = module.get.positions(); + } + + module.debug('Recording last position tried', position); + triedPositions[position] = true; + + if(settings.prefer === 'opposite') { + nextPosition = [opposite[verticalPosition], horizontalPosition]; + nextPosition = nextPosition.join(' '); + oppositeTried = (triedPositions[nextPosition] === true); + module.debug('Trying opposite strategy', nextPosition); + } + if((settings.prefer === 'adjacent') && adjacentsAvailable ) { + nextPosition = [verticalPosition, adjacent[horizontalPosition]]; + nextPosition = nextPosition.join(' '); + adjacentTried = (triedPositions[nextPosition] === true); + module.debug('Trying adjacent strategy', nextPosition); + } + if(adjacentTried || oppositeTried) { + module.debug('Using backup position', nextPosition); + nextPosition = backup[position]; + } + return nextPosition; + } + }, + + set: { + position: function(position, calculations) { + + // exit conditions + if($target.length === 0 || $popup.length === 0) { + module.error(error.notFound); + return; + } + var + offset, + distanceAway, + target, + popup, + parent, + positioning, + popupOffset, + distanceFromBoundary + ; + + calculations = calculations || module.get.calculations(); + position = position || $module.data(metadata.position) || settings.position; + + offset = $module.data(metadata.offset) || settings.offset; + distanceAway = settings.distanceAway; + + // shorthand + target = calculations.target; + popup = calculations.popup; + parent = calculations.parent; + + if(module.should.centerArrow(calculations)) { + module.verbose('Adjusting offset to center arrow on small target element'); + if(position == 'top left' || position == 'bottom left') { + offset += (target.width / 2) + offset -= settings.arrowPixelsFromEdge; + } + if(position == 'top right' || position == 'bottom right') { + offset -= (target.width / 2) + offset += settings.arrowPixelsFromEdge; + } + } + + if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) { + module.debug('Popup target is hidden, no action taken'); + return false; + } + + if(settings.inline) { + module.debug('Adding margin to calculation', target.margin); + if(position == 'left center' || position == 'right center') { + offset += target.margin.top; + distanceAway += -target.margin.left; + } + else if (position == 'top left' || position == 'top center' || position == 'top right') { + offset += target.margin.left; + distanceAway -= target.margin.top; + } + else { + offset += target.margin.left; + distanceAway += target.margin.top; + } + } + + module.debug('Determining popup position from calculations', position, calculations); + + if (module.is.rtl()) { + position = position.replace(/left|right/g, function (match) { + return (match == 'left') + ? 'right' + : 'left' + ; + }); + module.debug('RTL: Popup position updated', position); + } + + // if last attempt use specified last resort position + if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') { + position = settings.lastResort; + } + + switch (position) { + case 'top left': + positioning = { + top : 'auto', + bottom : parent.height - target.top + distanceAway, + left : target.left + offset, + right : 'auto' + }; + break; + case 'top center': + positioning = { + bottom : parent.height - target.top + distanceAway, + left : target.left + (target.width / 2) - (popup.width / 2) + offset, + top : 'auto', + right : 'auto' + }; + break; + case 'top right': + positioning = { + bottom : parent.height - target.top + distanceAway, + right : parent.width - target.left - target.width - offset, + top : 'auto', + left : 'auto' + }; + break; + case 'left center': + positioning = { + top : target.top + (target.height / 2) - (popup.height / 2) + offset, + right : parent.width - target.left + distanceAway, + left : 'auto', + bottom : 'auto' + }; + break; + case 'right center': + positioning = { + top : target.top + (target.height / 2) - (popup.height / 2) + offset, + left : target.left + target.width + distanceAway, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom left': + positioning = { + top : target.top + target.height + distanceAway, + left : target.left + offset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom center': + positioning = { + top : target.top + target.height + distanceAway, + left : target.left + (target.width / 2) - (popup.width / 2) + offset, + bottom : 'auto', + right : 'auto' + }; + break; + case 'bottom right': + positioning = { + top : target.top + target.height + distanceAway, + right : parent.width - target.left - target.width - offset, + left : 'auto', + bottom : 'auto' + }; + break; + } + if(positioning === undefined) { + module.error(error.invalidPosition, position); + } + + module.debug('Calculated popup positioning values', positioning); + + // tentatively place on stage + $popup + .css(positioning) + .removeClass(className.position) + .addClass(position) + .addClass(className.loading) + ; + + popupOffset = module.get.popupOffset(); + + // see if any boundaries are surpassed with this tentative position + distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations); + + if( module.is.offstage(distanceFromBoundary, position) ) { + module.debug('Position is outside viewport', position); + if(searchDepth < settings.maxSearchDepth) { + searchDepth++; + position = module.get.nextPosition(position); + module.debug('Trying new position', position); + return ($popup) + ? module.set.position(position, calculations) + : false + ; + } + else { + if(settings.lastResort) { + module.debug('No position found, showing with last position'); + } + else { + module.debug('Popup could not find a position to display', $popup); + module.error(error.cannotPlace, element); + module.remove.attempts(); + module.remove.loading(); + module.reset(); + settings.onUnplaceable.call($popup, element); + return false; + } + } + } + module.debug('Position is on stage', position); + module.remove.attempts(); + module.remove.loading(); + if( settings.setFluidWidth && module.is.fluid() ) { + module.set.fluidWidth(calculations); + } + return true; + }, + + fluidWidth: function(calculations) { + calculations = calculations || module.get.calculations(); + module.debug('Automatically setting element width to parent width', calculations.parent.width); + $popup.css('width', calculations.container.width); + }, + + variation: function(variation) { + variation = variation || module.get.variation(); + if(variation && module.has.popup() ) { + module.verbose('Adding variation to popup', variation); + $popup.addClass(variation); + } + }, + + visible: function() { + $module.addClass(className.visible); + } + }, + + remove: { + loading: function() { + $popup.removeClass(className.loading); + }, + variation: function(variation) { + variation = variation || module.get.variation(); + if(variation) { + module.verbose('Removing variation', variation); + $popup.removeClass(variation); + } + }, + visible: function() { + $module.removeClass(className.visible); + }, + attempts: function() { + module.verbose('Resetting all searched positions'); + searchDepth = 0; + triedPositions = false; + } + }, + + bind: { + events: function() { + module.debug('Binding popup events to module'); + if(settings.on == 'click') { + $module + .on('click' + eventNamespace, module.toggle) + ; + } + if(settings.on == 'hover' && hasTouch) { + $module + .on('touchstart' + eventNamespace, module.event.touchstart) + ; + } + if( module.get.startEvent() ) { + $module + .on(module.get.startEvent() + eventNamespace, module.event.start) + .on(module.get.endEvent() + eventNamespace, module.event.end) + ; + } + if(settings.target) { + module.debug('Target set to element', $target); + } + $window.on('resize' + elementNamespace, module.event.resize); + }, + popup: function() { + module.verbose('Allowing hover events on popup to prevent closing'); + if( $popup && module.has.popup() ) { + $popup + .on('mouseenter' + eventNamespace, module.event.start) + .on('mouseleave' + eventNamespace, module.event.end) + ; + } + }, + close: function() { + if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) { + module.bind.closeOnScroll(); + } + if(module.is.closable()) { + module.bind.clickaway(); + } + else if(settings.on == 'hover' && openedWithTouch) { + module.bind.touchClose(); + } + }, + closeOnScroll: function() { + module.verbose('Binding scroll close event to document'); + $scrollContext + .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully) + ; + }, + touchClose: function() { + module.verbose('Binding popup touchclose event to document'); + $document + .on('touchstart' + elementNamespace, function(event) { + module.verbose('Touched away from popup'); + module.event.hideGracefully.call(element, event); + }) + ; + }, + clickaway: function() { + module.verbose('Binding popup close event to document'); + $document + .on('click' + elementNamespace, function(event) { + module.verbose('Clicked away from popup'); + module.event.hideGracefully.call(element, event); + }) + ; + } + }, + + unbind: { + events: function() { + $window + .off(elementNamespace) + ; + $module + .off(eventNamespace) + ; + }, + close: function() { + $document + .off(elementNamespace) + ; + $scrollContext + .off(elementNamespace) + ; + }, + }, + + has: { + popup: function() { + return ($popup && $popup.length > 0); + } + }, + + should: { + centerArrow: function(calculations) { + return !module.is.basic() && calculations.target.width <= (settings.arrowPixelsFromEdge * 2); + }, + }, + + is: { + closable: function() { + if(settings.closable == 'auto') { + if(settings.on == 'hover') { + return false; + } + return true; + } + return settings.closable; + }, + offstage: function(distanceFromBoundary, position) { + var + offstage = [] + ; + // return boundaries that have been surpassed + $.each(distanceFromBoundary, function(direction, distance) { + if(distance < -settings.jitter) { + module.debug('Position exceeds allowable distance from edge', direction, distance, position); + offstage.push(direction); + } + }); + if(offstage.length > 0) { + return true; + } + else { + return false; + } + }, + svg: function(element) { + return module.supports.svg() && (element instanceof SVGGraphicsElement); + }, + basic: function() { + return $module.hasClass(className.basic); + }, + active: function() { + return $module.hasClass(className.active); + }, + animating: function() { + return ($popup !== undefined && $popup.hasClass(className.animating) ); + }, + fluid: function() { + return ($popup !== undefined && $popup.hasClass(className.fluid)); + }, + visible: function() { + return ($popup !== undefined && $popup.hasClass(className.popupVisible)); + }, + dropdown: function() { + return $module.hasClass(className.dropdown); + }, + hidden: function() { + return !module.is.visible(); + }, + rtl: function () { + return $module.css('direction') == 'rtl'; + } + }, + + reset: function() { + module.remove.visible(); + if(settings.preserve) { + if($.fn.transition !== undefined) { + $popup + .transition('remove transition') + ; + } + } + else { + module.removePopup(); + } + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + settings[name] = value; + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.popup.settings = { + + name : 'Popup', + + // module settings + silent : false, + debug : false, + verbose : false, + performance : true, + namespace : 'popup', + + // whether it should use dom mutation observers + observeChanges : true, + + // callback only when element added to dom + onCreate : function(){}, + + // callback before element removed from dom + onRemove : function(){}, + + // callback before show animation + onShow : function(){}, + + // callback after show animation + onVisible : function(){}, + + // callback before hide animation + onHide : function(){}, + + // callback when popup cannot be positioned in visible screen + onUnplaceable : function(){}, + + // callback after hide animation + onHidden : function(){}, + + // when to show popup + on : 'hover', + + // element to use to determine if popup is out of boundary + boundary : window, + + // whether to add touchstart events when using hover + addTouchEvents : true, + + // default position relative to element + position : 'top left', + + // name of variation to use + variation : '', + + // whether popup should be moved to context + movePopup : true, + + // element which popup should be relative to + target : false, + + // jq selector or element that should be used as popup + popup : false, + + // popup should remain inline next to activator + inline : false, + + // popup should be removed from page on hide + preserve : false, + + // popup should not close when being hovered on + hoverable : false, + + // explicitly set content + content : false, + + // explicitly set html + html : false, + + // explicitly set title + title : false, + + // whether automatically close on clickaway when on click + closable : true, + + // automatically hide on scroll + hideOnScroll : 'auto', + + // hide other popups on show + exclusive : false, + + // context to attach popups + context : 'body', + + // context for binding scroll events + scrollContext : window, + + // position to prefer when calculating new position + prefer : 'opposite', + + // specify position to appear even if it doesn't fit + lastResort : false, + + // number of pixels from edge of popup to pointing arrow center (used from centering) + arrowPixelsFromEdge: 20, + + // delay used to prevent accidental refiring of animations due to user error + delay : { + show : 50, + hide : 70 + }, + + // whether fluid variation should assign width explicitly + setFluidWidth : true, + + // transition settings + duration : 200, + transition : 'scale', + + // distance away from activating element in px + distanceAway : 0, + + // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding) + jitter : 2, + + // offset on aligning axis from calculated position + offset : 0, + + // maximum times to look for a position before failing (9 positions total) + maxSearchDepth : 15, + + error: { + invalidPosition : 'The position you specified is not a valid position', + cannotPlace : 'Popup does not fit within the boundaries of the viewport', + method : 'The method you called is not defined.', + noTransition : 'This module requires ui transitions ', + notFound : 'The target or popup you specified does not exist on the page' + }, + + metadata: { + activator : 'activator', + content : 'content', + html : 'html', + offset : 'offset', + position : 'position', + title : 'title', + variation : 'variation' + }, + + className : { + active : 'active', + basic : 'basic', + animating : 'animating', + dropdown : 'dropdown', + fluid : 'fluid', + loading : 'loading', + popup : 'ui popup', + position : 'top left center bottom right', + visible : 'visible', + popupVisible : 'visible' + }, + + selector : { + popup : '.ui.popup' + }, + + templates: { + escape: function(string) { + var + badChars = /[&<>"'`]/g, + shouldEscape = /[&<>"'`]/, + escape = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, + escapedChar = function(chr) { + return escape[chr]; + } + ; + if(shouldEscape.test(string)) { + return string.replace(badChars, escapedChar); + } + return string; + }, + popup: function(text) { + var + html = '', + escape = $.fn.popup.settings.templates.escape + ; + if(typeof text !== undefined) { + if(typeof text.title !== undefined && text.title) { + text.title = escape(text.title); + html += '
' + text.title + '
'; + } + if(typeof text.content !== undefined && text.content) { + text.content = escape(text.content); + html += '
' + text.content + '
'; + } + } + return html; + } + } + +}; + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Progress + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +var + global = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.progress = function(parameters) { + var + $allModules = $(this), + + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.progress.settings, parameters) + : $.extend({}, $.fn.progress.settings), + + className = settings.className, + metadata = settings.metadata, + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $bar = $(this).find(selector.bar), + $progress = $(this).find(selector.progress), + $label = $(this).find(selector.label), + + element = this, + instance = $module.data(moduleNamespace), + + animating = false, + transitionEnd, + module + ; + + module = { + + initialize: function() { + module.debug('Initializing progress bar', settings); + + module.set.duration(); + module.set.transitionEvent(); + + module.read.metadata(); + module.read.settings(); + + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of progress', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + destroy: function() { + module.verbose('Destroying previous progress for', $module); + clearInterval(instance.interval); + module.remove.state(); + $module.removeData(moduleNamespace); + instance = undefined; + }, + + reset: function() { + module.remove.nextValue(); + module.update.progress(0); + }, + + complete: function() { + if(module.percent === undefined || module.percent < 100) { + module.remove.progressPoll(); + module.set.percent(100); + } + }, + + read: { + metadata: function() { + var + data = { + percent : $module.data(metadata.percent), + total : $module.data(metadata.total), + value : $module.data(metadata.value) + } + ; + if(data.percent) { + module.debug('Current percent value set from metadata', data.percent); + module.set.percent(data.percent); + } + if(data.total) { + module.debug('Total value set from metadata', data.total); + module.set.total(data.total); + } + if(data.value) { + module.debug('Current value set from metadata', data.value); + module.set.value(data.value); + module.set.progress(data.value); + } + }, + settings: function() { + if(settings.total !== false) { + module.debug('Current total set in settings', settings.total); + module.set.total(settings.total); + } + if(settings.value !== false) { + module.debug('Current value set in settings', settings.value); + module.set.value(settings.value); + module.set.progress(module.value); + } + if(settings.percent !== false) { + module.debug('Current percent set in settings', settings.percent); + module.set.percent(settings.percent); + } + } + }, + + bind: { + transitionEnd: function(callback) { + var + transitionEnd = module.get.transitionEnd() + ; + $bar + .one(transitionEnd + eventNamespace, function(event) { + clearTimeout(module.failSafeTimer); + callback.call(this, event); + }) + ; + module.failSafeTimer = setTimeout(function() { + $bar.triggerHandler(transitionEnd); + }, settings.duration + settings.failSafeDelay); + module.verbose('Adding fail safe timer', module.timer); + } + }, + + increment: function(incrementValue) { + var + maxValue, + startValue, + newValue + ; + if( module.has.total() ) { + startValue = module.get.value(); + incrementValue = incrementValue || 1; + newValue = startValue + incrementValue; + } + else { + startValue = module.get.percent(); + incrementValue = incrementValue || module.get.randomValue(); + + newValue = startValue + incrementValue; + maxValue = 100; + module.debug('Incrementing percentage by', startValue, newValue); + } + newValue = module.get.normalizedValue(newValue); + module.set.progress(newValue); + }, + decrement: function(decrementValue) { + var + total = module.get.total(), + startValue, + newValue + ; + if(total) { + startValue = module.get.value(); + decrementValue = decrementValue || 1; + newValue = startValue - decrementValue; + module.debug('Decrementing value by', decrementValue, startValue); + } + else { + startValue = module.get.percent(); + decrementValue = decrementValue || module.get.randomValue(); + newValue = startValue - decrementValue; + module.debug('Decrementing percentage by', decrementValue, startValue); + } + newValue = module.get.normalizedValue(newValue); + module.set.progress(newValue); + }, + + has: { + progressPoll: function() { + return module.progressPoll; + }, + total: function() { + return (module.get.total() !== false); + } + }, + + get: { + text: function(templateText) { + var + value = module.value || 0, + total = module.total || 0, + percent = (animating) + ? module.get.displayPercent() + : module.percent || 0, + left = (module.total > 0) + ? (total - value) + : (100 - percent) + ; + templateText = templateText || ''; + templateText = templateText + .replace('{value}', value) + .replace('{total}', total) + .replace('{left}', left) + .replace('{percent}', percent) + ; + module.verbose('Adding variables to progress bar text', templateText); + return templateText; + }, + + normalizedValue: function(value) { + if(value < 0) { + module.debug('Value cannot decrement below 0'); + return 0; + } + if(module.has.total()) { + if(value > module.total) { + module.debug('Value cannot increment above total', module.total); + return module.total; + } + } + else if(value > 100 ) { + module.debug('Value cannot increment above 100 percent'); + return 100; + } + return value; + }, + + updateInterval: function() { + if(settings.updateInterval == 'auto') { + return settings.duration; + } + return settings.updateInterval; + }, + + randomValue: function() { + module.debug('Generating random increment percentage'); + return Math.floor((Math.random() * settings.random.max) + settings.random.min); + }, + + numericValue: function(value) { + return (typeof value === 'string') + ? (value.replace(/[^\d.]/g, '') !== '') + ? +(value.replace(/[^\d.]/g, '')) + : false + : value + ; + }, + + transitionEnd: function() { + var + element = document.createElement('element'), + transitions = { + 'transition' :'transitionend', + 'OTransition' :'oTransitionEnd', + 'MozTransition' :'transitionend', + 'WebkitTransition' :'webkitTransitionEnd' + }, + transition + ; + for(transition in transitions){ + if( element.style[transition] !== undefined ){ + return transitions[transition]; + } + } + }, + + // gets current displayed percentage (if animating values this is the intermediary value) + displayPercent: function() { + var + barWidth = $bar.width(), + totalWidth = $module.width(), + minDisplay = parseInt($bar.css('min-width'), 10), + displayPercent = (barWidth > minDisplay) + ? (barWidth / totalWidth * 100) + : module.percent + ; + return (settings.precision > 0) + ? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision) + : Math.round(displayPercent) + ; + }, + + percent: function() { + return module.percent || 0; + }, + value: function() { + return module.nextValue || module.value || 0; + }, + total: function() { + return module.total || false; + } + }, + + create: { + progressPoll: function() { + module.progressPoll = setTimeout(function() { + module.update.toNextValue(); + module.remove.progressPoll(); + }, module.get.updateInterval()); + }, + }, + + is: { + complete: function() { + return module.is.success() || module.is.warning() || module.is.error(); + }, + success: function() { + return $module.hasClass(className.success); + }, + warning: function() { + return $module.hasClass(className.warning); + }, + error: function() { + return $module.hasClass(className.error); + }, + active: function() { + return $module.hasClass(className.active); + }, + visible: function() { + return $module.is(':visible'); + } + }, + + remove: { + progressPoll: function() { + module.verbose('Removing progress poll timer'); + if(module.progressPoll) { + clearTimeout(module.progressPoll); + delete module.progressPoll; + } + }, + nextValue: function() { + module.verbose('Removing progress value stored for next update'); + delete module.nextValue; + }, + state: function() { + module.verbose('Removing stored state'); + delete module.total; + delete module.percent; + delete module.value; + }, + active: function() { + module.verbose('Removing active state'); + $module.removeClass(className.active); + }, + success: function() { + module.verbose('Removing success state'); + $module.removeClass(className.success); + }, + warning: function() { + module.verbose('Removing warning state'); + $module.removeClass(className.warning); + }, + error: function() { + module.verbose('Removing error state'); + $module.removeClass(className.error); + } + }, + + set: { + barWidth: function(value) { + if(value > 100) { + module.error(error.tooHigh, value); + } + else if (value < 0) { + module.error(error.tooLow, value); + } + else { + $bar + .css('width', value + '%') + ; + $module + .attr('data-percent', parseInt(value, 10)) + ; + } + }, + duration: function(duration) { + duration = duration || settings.duration; + duration = (typeof duration == 'number') + ? duration + 'ms' + : duration + ; + module.verbose('Setting progress bar transition duration', duration); + $bar + .css({ + 'transition-duration': duration + }) + ; + }, + percent: function(percent) { + percent = (typeof percent == 'string') + ? +(percent.replace('%', '')) + : percent + ; + // round display percentage + percent = (settings.precision > 0) + ? Math.round(percent * (10 * settings.precision)) / (10 * settings.precision) + : Math.round(percent) + ; + module.percent = percent; + if( !module.has.total() ) { + module.value = (settings.precision > 0) + ? Math.round( (percent / 100) * module.total * (10 * settings.precision)) / (10 * settings.precision) + : Math.round( (percent / 100) * module.total * 10) / 10 + ; + if(settings.limitValues) { + module.value = (module.value > 100) + ? 100 + : (module.value < 0) + ? 0 + : module.value + ; + } + } + module.set.barWidth(percent); + module.set.labelInterval(); + module.set.labels(); + settings.onChange.call(element, percent, module.value, module.total); + }, + labelInterval: function() { + var + animationCallback = function() { + module.verbose('Bar finished animating, removing continuous label updates'); + clearInterval(module.interval); + animating = false; + module.set.labels(); + } + ; + clearInterval(module.interval); + module.bind.transitionEnd(animationCallback); + animating = true; + module.interval = setInterval(function() { + var + isInDOM = $.contains(document.documentElement, element) + ; + if(!isInDOM) { + clearInterval(module.interval); + animating = false; + } + module.set.labels(); + }, settings.framerate); + }, + labels: function() { + module.verbose('Setting both bar progress and outer label text'); + module.set.barLabel(); + module.set.state(); + }, + label: function(text) { + text = text || ''; + if(text) { + text = module.get.text(text); + module.verbose('Setting label to text', text); + $label.text(text); + } + }, + state: function(percent) { + percent = (percent !== undefined) + ? percent + : module.percent + ; + if(percent === 100) { + if(settings.autoSuccess && !(module.is.warning() || module.is.error() || module.is.success())) { + module.set.success(); + module.debug('Automatically triggering success at 100%'); + } + else { + module.verbose('Reached 100% removing active state'); + module.remove.active(); + module.remove.progressPoll(); + } + } + else if(percent > 0) { + module.verbose('Adjusting active progress bar label', percent); + module.set.active(); + } + else { + module.remove.active(); + module.set.label(settings.text.active); + } + }, + barLabel: function(text) { + if(text !== undefined) { + $progress.text( module.get.text(text) ); + } + else if(settings.label == 'ratio' && module.total) { + module.verbose('Adding ratio to bar label'); + $progress.text( module.get.text(settings.text.ratio) ); + } + else if(settings.label == 'percent') { + module.verbose('Adding percentage to bar label'); + $progress.text( module.get.text(settings.text.percent) ); + } + }, + active: function(text) { + text = text || settings.text.active; + module.debug('Setting active state'); + if(settings.showActivity && !module.is.active() ) { + $module.addClass(className.active); + } + module.remove.warning(); + module.remove.error(); + module.remove.success(); + text = settings.onLabelUpdate('active', text, module.value, module.total); + if(text) { + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onActive.call(element, module.value, module.total); + }); + }, + success : function(text) { + text = text || settings.text.success || settings.text.active; + module.debug('Setting success state'); + $module.addClass(className.success); + module.remove.active(); + module.remove.warning(); + module.remove.error(); + module.complete(); + if(settings.text.success) { + text = settings.onLabelUpdate('success', text, module.value, module.total); + module.set.label(text); + } + else { + text = settings.onLabelUpdate('active', text, module.value, module.total); + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onSuccess.call(element, module.total); + }); + }, + warning : function(text) { + text = text || settings.text.warning; + module.debug('Setting warning state'); + $module.addClass(className.warning); + module.remove.active(); + module.remove.success(); + module.remove.error(); + module.complete(); + text = settings.onLabelUpdate('warning', text, module.value, module.total); + if(text) { + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onWarning.call(element, module.value, module.total); + }); + }, + error : function(text) { + text = text || settings.text.error; + module.debug('Setting error state'); + $module.addClass(className.error); + module.remove.active(); + module.remove.success(); + module.remove.warning(); + module.complete(); + text = settings.onLabelUpdate('error', text, module.value, module.total); + if(text) { + module.set.label(text); + } + module.bind.transitionEnd(function() { + settings.onError.call(element, module.value, module.total); + }); + }, + transitionEvent: function() { + transitionEnd = module.get.transitionEnd(); + }, + total: function(totalValue) { + module.total = totalValue; + }, + value: function(value) { + module.value = value; + }, + progress: function(value) { + if(!module.has.progressPoll()) { + module.debug('First update in progress update interval, immediately updating', value); + module.update.progress(value); + module.create.progressPoll(); + } + else { + module.debug('Updated within interval, setting next update to use new value', value); + module.set.nextValue(value); + } + }, + nextValue: function(value) { + module.nextValue = value; + } + }, + + update: { + toNextValue: function() { + var + nextValue = module.nextValue + ; + if(nextValue) { + module.debug('Update interval complete using last updated value', nextValue); + module.update.progress(nextValue); + module.remove.nextValue(); + } + }, + progress: function(value) { + var + percentComplete + ; + value = module.get.numericValue(value); + if(value === false) { + module.error(error.nonNumeric, value); + } + value = module.get.normalizedValue(value); + if( module.has.total() ) { + module.set.value(value); + percentComplete = (value / module.total) * 100; + module.debug('Calculating percent complete from total', percentComplete); + module.set.percent( percentComplete ); + } + else { + percentComplete = value; + module.debug('Setting value to exact percentage value', percentComplete); + module.set.percent( percentComplete ); + } + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.progress.settings = { + + name : 'Progress', + namespace : 'progress', + + silent : false, + debug : false, + verbose : false, + performance : true, + + random : { + min : 2, + max : 5 + }, + + duration : 300, + + updateInterval : 'auto', + + autoSuccess : true, + showActivity : true, + limitValues : true, + + label : 'percent', + precision : 0, + framerate : (1000 / 30), /// 30 fps + + percent : false, + total : false, + value : false, + + // delay in ms for fail safe animation callback + failSafeDelay : 100, + + onLabelUpdate : function(state, text, value, total){ + return text; + }, + onChange : function(percent, value, total){}, + onSuccess : function(total){}, + onActive : function(value, total){}, + onError : function(value, total){}, + onWarning : function(value, total){}, + + error : { + method : 'The method you called is not defined.', + nonNumeric : 'Progress value is non numeric', + tooHigh : 'Value specified is above 100%', + tooLow : 'Value specified is below 0%' + }, + + regExp: { + variable: /\{\$*[A-z0-9]+\}/g + }, + + metadata: { + percent : 'percent', + total : 'total', + value : 'value' + }, + + selector : { + bar : '> .bar', + label : '> .label', + progress : '.bar > .progress' + }, + + text : { + active : false, + error : false, + success : false, + warning : false, + percent : '{percent}%', + ratio : '{value} of {total}' + }, + + className : { + active : 'active', + error : 'error', + success : 'success', + warning : 'warning' + } + +}; + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Rating + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.rating = function(parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.rating.settings, parameters) + : $.extend({}, $.fn.rating.settings), + + namespace = settings.namespace, + className = settings.className, + metadata = settings.metadata, + selector = settings.selector, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + element = this, + instance = $(this).data(moduleNamespace), + + $module = $(this), + $icon = $module.find(selector.icon), + + initialLoad, + module + ; + + module = { + + initialize: function() { + module.verbose('Initializing rating module', settings); + + if($icon.length === 0) { + module.setup.layout(); + } + + if(settings.interactive) { + module.enable(); + } + else { + module.disable(); + } + module.set.initialLoad(); + module.set.rating( module.get.initialRating() ); + module.remove.initialLoad(); + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Instantiating module', settings); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous instance', instance); + module.remove.events(); + $module + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + $icon = $module.find(selector.icon); + }, + + setup: { + layout: function() { + var + maxRating = module.get.maxRating(), + html = $.fn.rating.settings.templates.icon(maxRating) + ; + module.debug('Generating icon html dynamically'); + $module + .html(html) + ; + module.refresh(); + } + }, + + event: { + mouseenter: function() { + var + $activeIcon = $(this) + ; + $activeIcon + .nextAll() + .removeClass(className.selected) + ; + $module + .addClass(className.selected) + ; + $activeIcon + .addClass(className.selected) + .prevAll() + .addClass(className.selected) + ; + }, + mouseleave: function() { + $module + .removeClass(className.selected) + ; + $icon + .removeClass(className.selected) + ; + }, + click: function() { + var + $activeIcon = $(this), + currentRating = module.get.rating(), + rating = $icon.index($activeIcon) + 1, + canClear = (settings.clearable == 'auto') + ? ($icon.length === 1) + : settings.clearable + ; + if(canClear && currentRating == rating) { + module.clearRating(); + } + else { + module.set.rating( rating ); + } + } + }, + + clearRating: function() { + module.debug('Clearing current rating'); + module.set.rating(0); + }, + + bind: { + events: function() { + module.verbose('Binding events'); + $module + .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter) + .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave) + .on('click' + eventNamespace, selector.icon, module.event.click) + ; + } + }, + + remove: { + events: function() { + module.verbose('Removing events'); + $module + .off(eventNamespace) + ; + }, + initialLoad: function() { + initialLoad = false; + } + }, + + enable: function() { + module.debug('Setting rating to interactive mode'); + module.bind.events(); + $module + .removeClass(className.disabled) + ; + }, + + disable: function() { + module.debug('Setting rating to read-only mode'); + module.remove.events(); + $module + .addClass(className.disabled) + ; + }, + + is: { + initialLoad: function() { + return initialLoad; + } + }, + + get: { + initialRating: function() { + if($module.data(metadata.rating) !== undefined) { + $module.removeData(metadata.rating); + return $module.data(metadata.rating); + } + return settings.initialRating; + }, + maxRating: function() { + if($module.data(metadata.maxRating) !== undefined) { + $module.removeData(metadata.maxRating); + return $module.data(metadata.maxRating); + } + return settings.maxRating; + }, + rating: function() { + var + currentRating = $icon.filter('.' + className.active).length + ; + module.verbose('Current rating retrieved', currentRating); + return currentRating; + } + }, + + set: { + rating: function(rating) { + var + ratingIndex = (rating - 1 >= 0) + ? (rating - 1) + : 0, + $activeIcon = $icon.eq(ratingIndex) + ; + $module + .removeClass(className.selected) + ; + $icon + .removeClass(className.selected) + .removeClass(className.active) + ; + if(rating > 0) { + module.verbose('Setting current rating to', rating); + $activeIcon + .prevAll() + .addBack() + .addClass(className.active) + ; + } + if(!module.is.initialLoad()) { + settings.onRate.call(element, rating); + } + }, + initialLoad: function() { + initialLoad = true; + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.rating.settings = { + + name : 'Rating', + namespace : 'rating', + + slent : false, + debug : false, + verbose : false, + performance : true, + + initialRating : 0, + interactive : true, + maxRating : 4, + clearable : 'auto', + + fireOnInit : false, + + onRate : function(rating){}, + + error : { + method : 'The method you called is not defined', + noMaximum : 'No maximum rating specified. Cannot generate HTML automatically' + }, + + + metadata: { + rating : 'rating', + maxRating : 'maxRating' + }, + + className : { + active : 'active', + disabled : 'disabled', + selected : 'selected', + loading : 'loading' + }, + + selector : { + icon : '.icon' + }, + + templates: { + icon: function(maxRating) { + var + icon = 1, + html = '' + ; + while(icon <= maxRating) { + html += ''; + icon++; + } + return html; + } + } + +}; + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Search + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.search = function(parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; + $(this) + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.search.settings, parameters) + : $.extend({}, $.fn.search.settings), + + className = settings.className, + metadata = settings.metadata, + regExp = settings.regExp, + fields = settings.fields, + selector = settings.selector, + error = settings.error, + namespace = settings.namespace, + + eventNamespace = '.' + namespace, + moduleNamespace = namespace + '-module', + + $module = $(this), + $prompt = $module.find(selector.prompt), + $searchButton = $module.find(selector.searchButton), + $results = $module.find(selector.results), + $result = $module.find(selector.result), + $category = $module.find(selector.category), + + element = this, + instance = $module.data(moduleNamespace), + + disabledBubbled = false, + resultsDismissed = false, + + module + ; + + module = { + + initialize: function() { + module.verbose('Initializing module'); + module.get.settings(); + module.determine.searchFields(); + module.bind.events(); + module.set.type(); + module.create.results(); + module.instantiate(); + }, + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + destroy: function() { + module.verbose('Destroying instance'); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + module.debug('Refreshing selector cache'); + $prompt = $module.find(selector.prompt); + $searchButton = $module.find(selector.searchButton); + $category = $module.find(selector.category); + $results = $module.find(selector.results); + $result = $module.find(selector.result); + }, + + refreshResults: function() { + $results = $module.find(selector.results); + $result = $module.find(selector.result); + }, + + bind: { + events: function() { + module.verbose('Binding events to search'); + if(settings.automatic) { + $module + .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input) + ; + $prompt + .attr('autocomplete', 'off') + ; + } + $module + // prompt + .on('focus' + eventNamespace, selector.prompt, module.event.focus) + .on('blur' + eventNamespace, selector.prompt, module.event.blur) + .on('keydown' + eventNamespace, selector.prompt, module.handleKeyboard) + // search button + .on('click' + eventNamespace, selector.searchButton, module.query) + // results + .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown) + .on('mouseup' + eventNamespace, selector.results, module.event.result.mouseup) + .on('click' + eventNamespace, selector.result, module.event.result.click) + ; + } + }, + + determine: { + searchFields: function() { + // this makes sure $.extend does not add specified search fields to default fields + // this is the only setting which should not extend defaults + if(parameters && parameters.searchFields !== undefined) { + settings.searchFields = parameters.searchFields; + } + } + }, + + event: { + input: function() { + if(settings.searchDelay) { + clearTimeout(module.timer); + module.timer = setTimeout(function() { + if(module.is.focused()) { + module.query(); + } + }, settings.searchDelay); + } + else { + module.query(); + } + }, + focus: function() { + module.set.focus(); + if(settings.searchOnFocus && module.has.minimumCharacters() ) { + module.query(function() { + if(module.can.show() ) { + module.showResults(); + } + }); + } + }, + blur: function(event) { + var + pageLostFocus = (document.activeElement === this), + callback = function() { + module.cancel.query(); + module.remove.focus(); + module.timer = setTimeout(module.hideResults, settings.hideDelay); + } + ; + if(pageLostFocus) { + return; + } + resultsDismissed = false; + if(module.resultsClicked) { + module.debug('Determining if user action caused search to close'); + $module + .one('click.close' + eventNamespace, selector.results, function(event) { + if(module.is.inMessage(event) || disabledBubbled) { + $prompt.focus(); + return; + } + disabledBubbled = false; + if( !module.is.animating() && !module.is.hidden()) { + callback(); + } + }) + ; + } + else { + module.debug('Input blurred without user action, closing results'); + callback(); + } + }, + result: { + mousedown: function() { + module.resultsClicked = true; + }, + mouseup: function() { + module.resultsClicked = false; + }, + click: function(event) { + module.debug('Search result selected'); + var + $result = $(this), + $title = $result.find(selector.title).eq(0), + $link = $result.is('a[href]') + ? $result + : $result.find('a[href]').eq(0), + href = $link.attr('href') || false, + target = $link.attr('target') || false, + title = $title.html(), + // title is used for result lookup + value = ($title.length > 0) + ? $title.text() + : false, + results = module.get.results(), + result = $result.data(metadata.result) || module.get.result(value, results), + returnedValue + ; + if( $.isFunction(settings.onSelect) ) { + if(settings.onSelect.call(element, result, results) === false) { + module.debug('Custom onSelect callback cancelled default select action'); + disabledBubbled = true; + return; + } + } + module.hideResults(); + if(value) { + module.set.value(value); + } + if(href) { + module.verbose('Opening search link found in result', $link); + if(target == '_blank' || event.ctrlKey) { + window.open(href); + } + else { + window.location.href = (href); + } + } + } + } + }, + handleKeyboard: function(event) { + var + // force selector refresh + $result = $module.find(selector.result), + $category = $module.find(selector.category), + $activeResult = $result.filter('.' + className.active), + currentIndex = $result.index( $activeResult ), + resultSize = $result.length, + hasActiveResult = $activeResult.length > 0, + + keyCode = event.which, + keys = { + backspace : 8, + enter : 13, + escape : 27, + upArrow : 38, + downArrow : 40 + }, + newIndex + ; + // search shortcuts + if(keyCode == keys.escape) { + module.verbose('Escape key pressed, blurring search field'); + module.hideResults(); + resultsDismissed = true; + } + if( module.is.visible() ) { + if(keyCode == keys.enter) { + module.verbose('Enter key pressed, selecting active result'); + if( $result.filter('.' + className.active).length > 0 ) { + module.event.result.click.call($result.filter('.' + className.active), event); + event.preventDefault(); + return false; + } + } + else if(keyCode == keys.upArrow && hasActiveResult) { + module.verbose('Up key pressed, changing active result'); + newIndex = (currentIndex - 1 < 0) + ? currentIndex + : currentIndex - 1 + ; + $category + .removeClass(className.active) + ; + $result + .removeClass(className.active) + .eq(newIndex) + .addClass(className.active) + .closest($category) + .addClass(className.active) + ; + event.preventDefault(); + } + else if(keyCode == keys.downArrow) { + module.verbose('Down key pressed, changing active result'); + newIndex = (currentIndex + 1 >= resultSize) + ? currentIndex + : currentIndex + 1 + ; + $category + .removeClass(className.active) + ; + $result + .removeClass(className.active) + .eq(newIndex) + .addClass(className.active) + .closest($category) + .addClass(className.active) + ; + event.preventDefault(); + } + } + else { + // query shortcuts + if(keyCode == keys.enter) { + module.verbose('Enter key pressed, executing query'); + module.query(); + module.set.buttonPressed(); + $prompt.one('keyup', module.remove.buttonFocus); + } + } + }, + + setup: { + api: function(searchTerm, callback) { + var + apiSettings = { + debug : settings.debug, + on : false, + cache : settings.cache, + action : 'search', + urlData : { + query : searchTerm + }, + onSuccess : function(response) { + module.parse.response.call(element, response, searchTerm); + callback(); + }, + onFailure : function() { + module.displayMessage(error.serverError); + callback(); + }, + onAbort : function(response) { + }, + onError : module.error + }, + searchHTML + ; + $.extend(true, apiSettings, settings.apiSettings); + module.verbose('Setting up API request', apiSettings); + $module.api(apiSettings); + } + }, + + can: { + useAPI: function() { + return $.fn.api !== undefined; + }, + show: function() { + return module.is.focused() && !module.is.visible() && !module.is.empty(); + }, + transition: function() { + return settings.transition && $.fn.transition !== undefined && $module.transition('is supported'); + } + }, + + is: { + animating: function() { + return $results.hasClass(className.animating); + }, + hidden: function() { + return $results.hasClass(className.hidden); + }, + inMessage: function(event) { + if(!event.target) { + return; + } + var + $target = $(event.target), + isInDOM = $.contains(document.documentElement, event.target) + ; + return (isInDOM && $target.closest(selector.message).length > 0); + }, + empty: function() { + return ($results.html() === ''); + }, + visible: function() { + return ($results.filter(':visible').length > 0); + }, + focused: function() { + return ($prompt.filter(':focus').length > 0); + } + }, + + get: { + settings: function() { + if($.isPlainObject(parameters) && parameters.searchFullText) { + settings.fullTextSearch = parameters.searchFullText; + module.error(settings.error.oldSearchSyntax, element); + } + }, + inputEvent: function() { + var + prompt = $prompt[0], + inputEvent = (prompt !== undefined && prompt.oninput !== undefined) + ? 'input' + : (prompt !== undefined && prompt.onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + return inputEvent; + }, + value: function() { + return $prompt.val(); + }, + results: function() { + var + results = $module.data(metadata.results) + ; + return results; + }, + result: function(value, results) { + var + lookupFields = ['title', 'id'], + result = false + ; + value = (value !== undefined) + ? value + : module.get.value() + ; + results = (results !== undefined) + ? results + : module.get.results() + ; + if(settings.type === 'category') { + module.debug('Finding result that matches', value); + $.each(results, function(index, category) { + if($.isArray(category.results)) { + result = module.search.object(value, category.results, lookupFields)[0]; + // don't continue searching if a result is found + if(result) { + return false; + } + } + }); + } + else { + module.debug('Finding result in results object', value); + result = module.search.object(value, results, lookupFields)[0]; + } + return result || false; + }, + }, + + select: { + firstResult: function() { + module.verbose('Selecting first result'); + $result.first().addClass(className.active); + } + }, + + set: { + focus: function() { + $module.addClass(className.focus); + }, + loading: function() { + $module.addClass(className.loading); + }, + value: function(value) { + module.verbose('Setting search input value', value); + $prompt + .val(value) + ; + }, + type: function(type) { + type = type || settings.type; + if(settings.type == 'category') { + $module.addClass(settings.type); + } + }, + buttonPressed: function() { + $searchButton.addClass(className.pressed); + } + }, + + remove: { + loading: function() { + $module.removeClass(className.loading); + }, + focus: function() { + $module.removeClass(className.focus); + }, + buttonPressed: function() { + $searchButton.removeClass(className.pressed); + } + }, + + query: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + var + searchTerm = module.get.value(), + cache = module.read.cache(searchTerm) + ; + callback = callback || function() {}; + if( module.has.minimumCharacters() ) { + if(cache) { + module.debug('Reading result from cache', searchTerm); + module.save.results(cache.results); + module.addResults(cache.html); + module.inject.id(cache.results); + callback(); + } + else { + module.debug('Querying for', searchTerm); + if($.isPlainObject(settings.source) || $.isArray(settings.source)) { + module.search.local(searchTerm); + callback(); + } + else if( module.can.useAPI() ) { + module.search.remote(searchTerm, callback); + } + else { + module.error(error.source); + callback(); + } + } + settings.onSearchQuery.call(element, searchTerm); + } + else { + module.hideResults(); + } + }, + + search: { + local: function(searchTerm) { + var + results = module.search.object(searchTerm, settings.content), + searchHTML + ; + module.set.loading(); + module.save.results(results); + module.debug('Returned full local search results', results); + if(settings.maxResults > 0) { + module.debug('Using specified max results', results); + results = results.slice(0, settings.maxResults); + } + if(settings.type == 'category') { + results = module.create.categoryResults(results); + } + searchHTML = module.generateResults({ + results: results + }); + module.remove.loading(); + module.addResults(searchHTML); + module.inject.id(results); + module.write.cache(searchTerm, { + html : searchHTML, + results : results + }); + }, + remote: function(searchTerm, callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if($module.api('is loading')) { + $module.api('abort'); + } + module.setup.api(searchTerm, callback); + $module + .api('query') + ; + }, + object: function(searchTerm, source, searchFields) { + var + results = [], + exactResults = [], + fuzzyResults = [], + searchExp = searchTerm.toString().replace(regExp.escape, '\\$&'), + matchRegExp = new RegExp(regExp.beginsWith + searchExp, 'i'), + + // avoid duplicates when pushing results + addResult = function(array, result) { + var + notResult = ($.inArray(result, results) == -1), + notFuzzyResult = ($.inArray(result, fuzzyResults) == -1), + notExactResults = ($.inArray(result, exactResults) == -1) + ; + if(notResult && notFuzzyResult && notExactResults) { + array.push(result); + } + } + ; + source = source || settings.source; + searchFields = (searchFields !== undefined) + ? searchFields + : settings.searchFields + ; + + // search fields should be array to loop correctly + if(!$.isArray(searchFields)) { + searchFields = [searchFields]; + } + + // exit conditions if no source + if(source === undefined || source === false) { + module.error(error.source); + return []; + } + // iterate through search fields looking for matches + $.each(searchFields, function(index, field) { + $.each(source, function(label, content) { + var + fieldExists = (typeof content[field] == 'string') + ; + if(fieldExists) { + if( content[field].search(matchRegExp) !== -1) { + // content starts with value (first in results) + addResult(results, content); + } + else if(settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, content[field]) ) { + // content fuzzy matches (last in results) + addResult(exactResults, content); + } + else if(settings.fullTextSearch == true && module.fuzzySearch(searchTerm, content[field]) ) { + // content fuzzy matches (last in results) + addResult(fuzzyResults, content); + } + } + }); + }); + $.merge(exactResults, fuzzyResults) + $.merge(results, exactResults); + return results; + } + }, + exactSearch: function (query, term) { + query = query.toLowerCase(); + term = term.toLowerCase(); + if(term.indexOf(query) > -1) { + return true; + } + return false; + }, + fuzzySearch: function(query, term) { + var + termLength = term.length, + queryLength = query.length + ; + if(typeof query !== 'string') { + return false; + } + query = query.toLowerCase(); + term = term.toLowerCase(); + if(queryLength > termLength) { + return false; + } + if(queryLength === termLength) { + return (query === term); + } + search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) { + var + queryCharacter = query.charCodeAt(characterIndex) + ; + while(nextCharacterIndex < termLength) { + if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) { + continue search; + } + } + return false; + } + return true; + }, + + parse: { + response: function(response, searchTerm) { + var + searchHTML = module.generateResults(response) + ; + module.verbose('Parsing server response', response); + if(response !== undefined) { + if(searchTerm !== undefined && response[fields.results] !== undefined) { + module.addResults(searchHTML); + module.inject.id(response[fields.results]); + module.write.cache(searchTerm, { + html : searchHTML, + results : response[fields.results] + }); + module.save.results(response[fields.results]); + } + } + } + }, + + cancel: { + query: function() { + if( module.can.useAPI() ) { + $module.api('abort'); + } + } + }, + + has: { + minimumCharacters: function() { + var + searchTerm = module.get.value(), + numCharacters = searchTerm.length + ; + return (numCharacters >= settings.minCharacters); + }, + results: function() { + if($results.length === 0) { + return false; + } + var + html = $results.html() + ; + return html != ''; + } + }, + + clear: { + cache: function(value) { + var + cache = $module.data(metadata.cache) + ; + if(!value) { + module.debug('Clearing cache', value); + $module.removeData(metadata.cache); + } + else if(value && cache && cache[value]) { + module.debug('Removing value from cache', value); + delete cache[value]; + $module.data(metadata.cache, cache); + } + } + }, + + read: { + cache: function(name) { + var + cache = $module.data(metadata.cache) + ; + if(settings.cache) { + module.verbose('Checking cache for generated html for query', name); + return (typeof cache == 'object') && (cache[name] !== undefined) + ? cache[name] + : false + ; + } + return false; + } + }, + + create: { + categoryResults: function(results) { + var + categoryResults = {} + ; + $.each(results, function(index, result) { + if(!result.category) { + return; + } + if(categoryResults[result.category] === undefined) { + module.verbose('Creating new category of results', result.category); + categoryResults[result.category] = { + name : result.category, + results : [result] + } + } + else { + categoryResults[result.category].results.push(result); + } + }); + return categoryResults; + }, + id: function(resultIndex, categoryIndex) { + var + resultID = (resultIndex + 1), // not zero indexed + categoryID = (categoryIndex + 1), + firstCharCode, + letterID, + id + ; + if(categoryIndex !== undefined) { + // start char code for "A" + letterID = String.fromCharCode(97 + categoryIndex); + id = letterID + resultID; + module.verbose('Creating category result id', id); + } + else { + id = resultID; + module.verbose('Creating result id', id); + } + return id; + }, + results: function() { + if($results.length === 0) { + $results = $('
') + .addClass(className.results) + .appendTo($module) + ; + } + } + }, + + inject: { + result: function(result, resultIndex, categoryIndex) { + module.verbose('Injecting result into results'); + var + $selectedResult = (categoryIndex !== undefined) + ? $results + .children().eq(categoryIndex) + .children(selector.results) + .first() + .children(selector.result) + .eq(resultIndex) + : $results + .children(selector.result).eq(resultIndex) + ; + module.verbose('Injecting results metadata', $selectedResult); + $selectedResult + .data(metadata.result, result) + ; + }, + id: function(results) { + module.debug('Injecting unique ids into results'); + var + // since results may be object, we must use counters + categoryIndex = 0, + resultIndex = 0 + ; + if(settings.type === 'category') { + // iterate through each category result + $.each(results, function(index, category) { + resultIndex = 0; + $.each(category.results, function(index, value) { + var + result = category.results[index] + ; + if(result.id === undefined) { + result.id = module.create.id(resultIndex, categoryIndex); + } + module.inject.result(result, resultIndex, categoryIndex); + resultIndex++; + }); + categoryIndex++; + }); + } + else { + // top level + $.each(results, function(index, value) { + var + result = results[index] + ; + if(result.id === undefined) { + result.id = module.create.id(resultIndex); + } + module.inject.result(result, resultIndex); + resultIndex++; + }); + } + return results; + } + }, + + save: { + results: function(results) { + module.verbose('Saving current search results to metadata', results); + $module.data(metadata.results, results); + } + }, + + write: { + cache: function(name, value) { + var + cache = ($module.data(metadata.cache) !== undefined) + ? $module.data(metadata.cache) + : {} + ; + if(settings.cache) { + module.verbose('Writing generated html to cache', name, value); + cache[name] = value; + $module + .data(metadata.cache, cache) + ; + } + } + }, + + addResults: function(html) { + if( $.isFunction(settings.onResultsAdd) ) { + if( settings.onResultsAdd.call($results, html) === false ) { + module.debug('onResultsAdd callback cancelled default action'); + return false; + } + } + if(html) { + $results + .html(html) + ; + module.refreshResults(); + if(settings.selectFirstResult) { + module.select.firstResult(); + } + module.showResults(); + } + else { + module.hideResults(function() { + $results.empty(); + }); + } + }, + + showResults: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(resultsDismissed) { + return; + } + if(!module.is.visible() && module.has.results()) { + if( module.can.transition() ) { + module.debug('Showing results with css animations'); + $results + .transition({ + animation : settings.transition + ' in', + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { + callback(); + }, + queue : true + }) + ; + } + else { + module.debug('Showing results with javascript'); + $results + .stop() + .fadeIn(settings.duration, settings.easing) + ; + } + settings.onResultsOpen.call($results); + } + }, + hideResults: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if( module.is.visible() ) { + if( module.can.transition() ) { + module.debug('Hiding results with css animations'); + $results + .transition({ + animation : settings.transition + ' out', + debug : settings.debug, + verbose : settings.verbose, + duration : settings.duration, + onComplete : function() { + callback(); + }, + queue : true + }) + ; + } + else { + module.debug('Hiding results with javascript'); + $results + .stop() + .fadeOut(settings.duration, settings.easing) + ; + } + settings.onResultsClose.call($results); + } + }, + + generateResults: function(response) { + module.debug('Generating html from response', response); + var + template = settings.templates[settings.type], + isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])), + isProperArray = ($.isArray(response[fields.results]) && response[fields.results].length > 0), + html = '' + ; + if(isProperObject || isProperArray ) { + if(settings.maxResults > 0) { + if(isProperObject) { + if(settings.type == 'standard') { + module.error(error.maxResults); + } + } + else { + response[fields.results] = response[fields.results].slice(0, settings.maxResults); + } + } + if($.isFunction(template)) { + html = template(response, fields); + } + else { + module.error(error.noTemplate, false); + } + } + else if(settings.showNoResults) { + html = module.displayMessage(error.noResults, 'empty'); + } + settings.onResults.call(element, response); + return html; + }, + + displayMessage: function(text, type) { + type = type || 'standard'; + module.debug('Displaying message', text, type); + module.addResults( settings.templates.message(text, type) ); + return settings.templates.message(text, type); + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + settings[name] = value; + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + return false; + } + }); + } + if( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.search.settings = { + + name : 'Search', + namespace : 'search', + + silent : false, + debug : false, + verbose : false, + performance : true, + + // template to use (specified in settings.templates) + type : 'standard', + + // minimum characters required to search + minCharacters : 1, + + // whether to select first result after searching automatically + selectFirstResult : false, + + // API config + apiSettings : false, + + // object to search + source : false, + + // Whether search should query current term on focus + searchOnFocus : true, + + // fields to search + searchFields : [ + 'title', + 'description' + ], + + // field to display in standard results template + displayField : '', + + // search anywhere in value (set to 'exact' to require exact matches + fullTextSearch : 'exact', + + // whether to add events to prompt automatically + automatic : true, + + // delay before hiding menu after blur + hideDelay : 0, + + // delay before searching + searchDelay : 200, + + // maximum results returned from search + maxResults : 7, + + // whether to store lookups in local cache + cache : true, + + // whether no results errors should be shown + showNoResults : true, + + // transition settings + transition : 'scale', + duration : 200, + easing : 'easeOutExpo', + + // callbacks + onSelect : false, + onResultsAdd : false, + + onSearchQuery : function(query){}, + onResults : function(response){}, + + onResultsOpen : function(){}, + onResultsClose : function(){}, + + className: { + animating : 'animating', + active : 'active', + empty : 'empty', + focus : 'focus', + hidden : 'hidden', + loading : 'loading', + results : 'results', + pressed : 'down' + }, + + error : { + source : 'Cannot search. No source used, and Semantic API module was not included', + noResults : 'Your search returned no results', + logging : 'Error in debug logging, exiting.', + noEndpoint : 'No search endpoint was specified', + noTemplate : 'A valid template name was not specified.', + oldSearchSyntax : 'searchFullText setting has been renamed fullTextSearch for consistency, please adjust your settings.', + serverError : 'There was an issue querying the server.', + maxResults : 'Results must be an array to use maxResults setting', + method : 'The method you called is not defined.' + }, + + metadata: { + cache : 'cache', + results : 'results', + result : 'result' + }, + + regExp: { + escape : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, + beginsWith : '(?:\s|^)' + }, + + // maps api response attributes to internal representation + fields: { + categories : 'results', // array of categories (category view) + categoryName : 'name', // name of category (category view) + categoryResults : 'results', // array of results (category view) + description : 'description', // result description + image : 'image', // result image + price : 'price', // result price + results : 'results', // array of results (standard) + title : 'title', // result title + url : 'url', // result url + action : 'action', // "view more" object name + actionText : 'text', // "view more" text + actionURL : 'url' // "view more" url + }, + + selector : { + prompt : '.prompt', + searchButton : '.search.button', + results : '.results', + message : '.results > .message', + category : '.category', + result : '.result', + title : '.title, .name' + }, + + templates: { + escape: function(string) { + var + badChars = /[&<>"'`]/g, + shouldEscape = /[&<>"'`]/, + escape = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + "`": "`" + }, + escapedChar = function(chr) { + return escape[chr]; + } + ; + if(shouldEscape.test(string)) { + return string.replace(badChars, escapedChar); + } + return string; + }, + message: function(message, type) { + var + html = '' + ; + if(message !== undefined && type !== undefined) { + html += '' + + '
' + ; + // message type + if(type == 'empty') { + html += '' + + '
No Results
' + + '
' + message + '
' + ; + } + else { + html += '
' + message + '
'; + } + html += '
'; + } + return html; + }, + category: function(response, fields) { + var + html = '', + escape = $.fn.search.settings.templates.escape + ; + if(response[fields.categoryResults] !== undefined) { + + // each category + $.each(response[fields.categoryResults], function(index, category) { + if(category[fields.results] !== undefined && category.results.length > 0) { + + html += '' + ; + } + }); + if(response[fields.action]) { + html += '' + + '' + + response[fields.action][fields.actionText] + + ''; + } + return html; + } + return false; + }, + standard: function(response, fields) { + var + html = '' + ; + if(response[fields.results] !== undefined) { + + // each result + $.each(response[fields.results], function(index, result) { + if(result[fields.url]) { + html += ''; + } + else { + html += ''; + } + if(result[fields.image] !== undefined) { + html += '' + + '
' + + ' ' + + '
' + ; + } + html += '
'; + if(result[fields.price] !== undefined) { + html += '
' + result[fields.price] + '
'; + } + if(result[fields.title] !== undefined) { + html += '
' + result[fields.title] + '
'; + } + if(result[fields.description] !== undefined) { + html += '
' + result[fields.description] + '
'; + } + html += '' + + '
' + ; + html += '
'; + }); + + if(response[fields.action]) { + html += '' + + '' + + response[fields.action][fields.actionText] + + ''; + } + return html; + } + return false; + } + } +}; + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Shape + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.shape = function(parameters) { + var + $allModules = $(this), + $body = $('body'), + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + returnedValue + ; + + $allModules + .each(function() { + var + moduleSelector = $allModules.selector || '', + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.shape.settings, parameters) + : $.extend({}, $.fn.shape.settings), + + // internal aliases + namespace = settings.namespace, + selector = settings.selector, + error = settings.error, + className = settings.className, + + // define namespaces for modules + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + // selector cache + $module = $(this), + $sides = $module.find(selector.sides), + $side = $module.find(selector.side), + + // private variables + nextIndex = false, + $activeSide, + $nextSide, + + // standard module + element = this, + instance = $module.data(moduleNamespace), + module + ; + + module = { + + initialize: function() { + module.verbose('Initializing module for', element); + module.set.defaultSide(); + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module for', element); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + refresh: function() { + module.verbose('Refreshing selector cache for', element); + $module = $(element); + $sides = $(this).find(selector.shape); + $side = $(this).find(selector.side); + }, + + repaint: function() { + module.verbose('Forcing repaint event'); + var + shape = $sides[0] || document.createElement('div'), + fakeAssignment = shape.offsetWidth + ; + }, + + animate: function(propertyObject, callback) { + module.verbose('Animating box with properties', propertyObject); + callback = callback || function(event) { + module.verbose('Executing animation callback'); + if(event !== undefined) { + event.stopPropagation(); + } + module.reset(); + module.set.active(); + }; + settings.beforeChange.call($nextSide[0]); + if(module.get.transitionEvent()) { + module.verbose('Starting CSS animation'); + $module + .addClass(className.animating) + ; + $sides + .css(propertyObject) + .one(module.get.transitionEvent(), callback) + ; + module.set.duration(settings.duration); + requestAnimationFrame(function() { + $module + .addClass(className.animating) + ; + $activeSide + .addClass(className.hidden) + ; + }); + } + else { + callback(); + } + }, + + queue: function(method) { + module.debug('Queueing animation of', method); + $sides + .one(module.get.transitionEvent(), function() { + module.debug('Executing queued animation'); + setTimeout(function(){ + $module.shape(method); + }, 0); + }) + ; + }, + + reset: function() { + module.verbose('Animating states reset'); + $module + .removeClass(className.animating) + .attr('style', '') + .removeAttr('style') + ; + // removeAttr style does not consistently work in safari + $sides + .attr('style', '') + .removeAttr('style') + ; + $side + .attr('style', '') + .removeAttr('style') + .removeClass(className.hidden) + ; + $nextSide + .removeClass(className.animating) + .attr('style', '') + .removeAttr('style') + ; + }, + + is: { + complete: function() { + return ($side.filter('.' + className.active)[0] == $nextSide[0]); + }, + animating: function() { + return $module.hasClass(className.animating); + } + }, + + set: { + + defaultSide: function() { + $activeSide = $module.find('.' + settings.className.active); + $nextSide = ( $activeSide.next(selector.side).length > 0 ) + ? $activeSide.next(selector.side) + : $module.find(selector.side).first() + ; + nextIndex = false; + module.verbose('Active side set to', $activeSide); + module.verbose('Next side set to', $nextSide); + }, + + duration: function(duration) { + duration = duration || settings.duration; + duration = (typeof duration == 'number') + ? duration + 'ms' + : duration + ; + module.verbose('Setting animation duration', duration); + if(settings.duration || settings.duration === 0) { + $sides.add($side) + .css({ + '-webkit-transition-duration': duration, + '-moz-transition-duration': duration, + '-ms-transition-duration': duration, + '-o-transition-duration': duration, + 'transition-duration': duration + }) + ; + } + }, + + currentStageSize: function() { + var + $activeSide = $module.find('.' + settings.className.active), + width = $activeSide.outerWidth(true), + height = $activeSide.outerHeight(true) + ; + $module + .css({ + width: width, + height: height + }) + ; + }, + + stageSize: function() { + var + $clone = $module.clone().addClass(className.loading), + $activeSide = $clone.find('.' + settings.className.active), + $nextSide = (nextIndex) + ? $clone.find(selector.side).eq(nextIndex) + : ( $activeSide.next(selector.side).length > 0 ) + ? $activeSide.next(selector.side) + : $clone.find(selector.side).first(), + newWidth = (settings.width == 'next') + ? $nextSide.outerWidth(true) + : (settings.width == 'initial') + ? $module.width() + : settings.width, + newHeight = (settings.height == 'next') + ? $nextSide.outerHeight(true) + : (settings.height == 'initial') + ? $module.height() + : settings.height + ; + $activeSide.removeClass(className.active); + $nextSide.addClass(className.active); + $clone.insertAfter($module); + $clone.remove(); + if(settings.width != 'auto') { + $module.css('width', newWidth + settings.jitter); + module.verbose('Specifying width during animation', newWidth); + } + if(settings.height != 'auto') { + $module.css('height', newHeight + settings.jitter); + module.verbose('Specifying height during animation', newHeight); + } + }, + + nextSide: function(selector) { + nextIndex = selector; + $nextSide = $side.filter(selector); + nextIndex = $side.index($nextSide); + if($nextSide.length === 0) { + module.set.defaultSide(); + module.error(error.side); + } + module.verbose('Next side manually set to', $nextSide); + }, + + active: function() { + module.verbose('Setting new side to active', $nextSide); + $side + .removeClass(className.active) + ; + $nextSide + .addClass(className.active) + ; + settings.onChange.call($nextSide[0]); + module.set.defaultSide(); + } + }, + + flip: { + + up: function() { + if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { + module.debug('Side already visible', $nextSide); + return; + } + if( !module.is.animating()) { + module.debug('Flipping up', $nextSide); + var + transform = module.get.transform.up() + ; + module.set.stageSize(); + module.stage.above(); + module.animate(transform); + } + else { + module.queue('flip up'); + } + }, + + down: function() { + if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { + module.debug('Side already visible', $nextSide); + return; + } + if( !module.is.animating()) { + module.debug('Flipping down', $nextSide); + var + transform = module.get.transform.down() + ; + module.set.stageSize(); + module.stage.below(); + module.animate(transform); + } + else { + module.queue('flip down'); + } + }, + + left: function() { + if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { + module.debug('Side already visible', $nextSide); + return; + } + if( !module.is.animating()) { + module.debug('Flipping left', $nextSide); + var + transform = module.get.transform.left() + ; + module.set.stageSize(); + module.stage.left(); + module.animate(transform); + } + else { + module.queue('flip left'); + } + }, + + right: function() { + if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { + module.debug('Side already visible', $nextSide); + return; + } + if( !module.is.animating()) { + module.debug('Flipping right', $nextSide); + var + transform = module.get.transform.right() + ; + module.set.stageSize(); + module.stage.right(); + module.animate(transform); + } + else { + module.queue('flip right'); + } + }, + + over: function() { + if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { + module.debug('Side already visible', $nextSide); + return; + } + if( !module.is.animating()) { + module.debug('Flipping over', $nextSide); + module.set.stageSize(); + module.stage.behind(); + module.animate(module.get.transform.over() ); + } + else { + module.queue('flip over'); + } + }, + + back: function() { + if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) { + module.debug('Side already visible', $nextSide); + return; + } + if( !module.is.animating()) { + module.debug('Flipping back', $nextSide); + module.set.stageSize(); + module.stage.behind(); + module.animate(module.get.transform.back() ); + } + else { + module.queue('flip back'); + } + } + + }, + + get: { + + transform: { + up: function() { + var + translate = { + y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), + z: -($activeSide.outerHeight(true) / 2) + } + ; + return { + transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)' + }; + }, + + down: function() { + var + translate = { + y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), + z: -($activeSide.outerHeight(true) / 2) + } + ; + return { + transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)' + }; + }, + + left: function() { + var + translate = { + x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2), + z : -($activeSide.outerWidth(true) / 2) + } + ; + return { + transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)' + }; + }, + + right: function() { + var + translate = { + x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2), + z : -($activeSide.outerWidth(true) / 2) + } + ; + return { + transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)' + }; + }, + + over: function() { + var + translate = { + x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2) + } + ; + return { + transform: 'translateX(' + translate.x + 'px) rotateY(180deg)' + }; + }, + + back: function() { + var + translate = { + x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2) + } + ; + return { + transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)' + }; + } + }, + + transitionEvent: function() { + var + element = document.createElement('element'), + transitions = { + 'transition' :'transitionend', + 'OTransition' :'oTransitionEnd', + 'MozTransition' :'transitionend', + 'WebkitTransition' :'webkitTransitionEnd' + }, + transition + ; + for(transition in transitions){ + if( element.style[transition] !== undefined ){ + return transitions[transition]; + } + } + }, + + nextSide: function() { + return ( $activeSide.next(selector.side).length > 0 ) + ? $activeSide.next(selector.side) + : $module.find(selector.side).first() + ; + } + + }, + + stage: { + + above: function() { + var + box = { + origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), + depth : { + active : ($nextSide.outerHeight(true) / 2), + next : ($activeSide.outerHeight(true) / 2) + } + } + ; + module.verbose('Setting the initial animation position as above', $nextSide, box); + $sides + .css({ + 'transform' : 'translateZ(-' + box.depth.active + 'px)' + }) + ; + $activeSide + .css({ + 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'top' : box.origin + 'px', + 'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)' + }) + ; + }, + + below: function() { + var + box = { + origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2), + depth : { + active : ($nextSide.outerHeight(true) / 2), + next : ($activeSide.outerHeight(true) / 2) + } + } + ; + module.verbose('Setting the initial animation position as below', $nextSide, box); + $sides + .css({ + 'transform' : 'translateZ(-' + box.depth.active + 'px)' + }) + ; + $activeSide + .css({ + 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'top' : box.origin + 'px', + 'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)' + }) + ; + }, + + left: function() { + var + height = { + active : $activeSide.outerWidth(true), + next : $nextSide.outerWidth(true) + }, + box = { + origin : ( ( height.active - height.next ) / 2), + depth : { + active : (height.next / 2), + next : (height.active / 2) + } + } + ; + module.verbose('Setting the initial animation position as left', $nextSide, box); + $sides + .css({ + 'transform' : 'translateZ(-' + box.depth.active + 'px)' + }) + ; + $activeSide + .css({ + 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'left' : box.origin + 'px', + 'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)' + }) + ; + }, + + right: function() { + var + height = { + active : $activeSide.outerWidth(true), + next : $nextSide.outerWidth(true) + }, + box = { + origin : ( ( height.active - height.next ) / 2), + depth : { + active : (height.next / 2), + next : (height.active / 2) + } + } + ; + module.verbose('Setting the initial animation position as left', $nextSide, box); + $sides + .css({ + 'transform' : 'translateZ(-' + box.depth.active + 'px)' + }) + ; + $activeSide + .css({ + 'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'left' : box.origin + 'px', + 'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)' + }) + ; + }, + + behind: function() { + var + height = { + active : $activeSide.outerWidth(true), + next : $nextSide.outerWidth(true) + }, + box = { + origin : ( ( height.active - height.next ) / 2), + depth : { + active : (height.next / 2), + next : (height.active / 2) + } + } + ; + module.verbose('Setting the initial animation position as behind', $nextSide, box); + $activeSide + .css({ + 'transform' : 'rotateY(0deg)' + }) + ; + $nextSide + .addClass(className.animating) + .css({ + 'left' : box.origin + 'px', + 'transform' : 'rotateY(-180deg)' + }) + ; + } + }, + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.shape.settings = { + + // module info + name : 'Shape', + + // hide all debug content + silent : false, + + // debug content outputted to console + debug : false, + + // verbose debug output + verbose : false, + + // fudge factor in pixels when swapping from 2d to 3d (can be useful to correct rounding errors) + jitter : 0, + + // performance data output + performance: true, + + // event namespace + namespace : 'shape', + + // width during animation, can be set to 'auto', initial', 'next' or pixel amount + width: 'initial', + + // height during animation, can be set to 'auto', 'initial', 'next' or pixel amount + height: 'initial', + + // callback occurs on side change + beforeChange : function() {}, + onChange : function() {}, + + // allow animation to same side + allowRepeats: false, + + // animation duration + duration : false, + + // possible errors + error: { + side : 'You tried to switch to a side that does not exist.', + method : 'The method you called is not defined' + }, + + // classnames used + className : { + animating : 'animating', + hidden : 'hidden', + loading : 'loading', + active : 'active' + }, + + // selectors used + selector : { + sides : '.sides', + side : '.side' + } + +}; + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Sidebar + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.sidebar = function(parameters) { + var + $allModules = $(this), + $window = $(window), + $document = $(document), + $html = $('html'), + $head = $('head'), + + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.sidebar.settings, parameters) + : $.extend({}, $.fn.sidebar.settings), + + selector = settings.selector, + className = settings.className, + namespace = settings.namespace, + regExp = settings.regExp, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $context = $(settings.context), + + $sidebars = $module.children(selector.sidebar), + $fixed = $context.children(selector.fixed), + $pusher = $context.children(selector.pusher), + $style, + + element = this, + instance = $module.data(moduleNamespace), + + elementNamespace, + id, + currentScroll, + transitionEvent, + + module + ; + + module = { + + initialize: function() { + module.debug('Initializing sidebar', parameters); + + module.create.id(); + + transitionEvent = module.get.transitionEvent(); + + // avoids locking rendering if initialized in onReady + if(settings.delaySetup) { + requestAnimationFrame(module.setup.layout); + } + else { + module.setup.layout(); + } + + requestAnimationFrame(function() { + module.setup.cache(); + }); + + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + create: { + id: function() { + id = (Math.random().toString(16) + '000000000').substr(2,8); + elementNamespace = '.' + id; + module.verbose('Creating unique id for element', id); + } + }, + + destroy: function() { + module.verbose('Destroying previous module for', $module); + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + if(module.is.ios()) { + module.remove.ios(); + } + // bound by uuid + $context.off(elementNamespace); + $window.off(elementNamespace); + $document.off(elementNamespace); + }, + + event: { + clickaway: function(event) { + var + clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)), + clickedContext = ($context.is(event.target)) + ; + if(clickedInPusher) { + module.verbose('User clicked on dimmed page'); + module.hide(); + } + if(clickedContext) { + module.verbose('User clicked on dimmable context (scaled out page)'); + module.hide(); + } + }, + touch: function(event) { + //event.stopPropagation(); + }, + containScroll: function(event) { + if(element.scrollTop <= 0) { + element.scrollTop = 1; + } + if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) { + element.scrollTop = element.scrollHeight - element.offsetHeight - 1; + } + }, + scroll: function(event) { + if( $(event.target).closest(selector.sidebar).length === 0 ) { + event.preventDefault(); + } + } + }, + + bind: { + clickaway: function() { + module.verbose('Adding clickaway events to context', $context); + if(settings.closable) { + $context + .on('click' + elementNamespace, module.event.clickaway) + .on('touchend' + elementNamespace, module.event.clickaway) + ; + } + }, + scrollLock: function() { + if(settings.scrollLock) { + module.debug('Disabling page scroll'); + $window + .on('DOMMouseScroll' + elementNamespace, module.event.scroll) + ; + } + module.verbose('Adding events to contain sidebar scroll'); + $document + .on('touchmove' + elementNamespace, module.event.touch) + ; + $module + .on('scroll' + eventNamespace, module.event.containScroll) + ; + } + }, + unbind: { + clickaway: function() { + module.verbose('Removing clickaway events from context', $context); + $context.off(elementNamespace); + }, + scrollLock: function() { + module.verbose('Removing scroll lock from page'); + $document.off(elementNamespace); + $window.off(elementNamespace); + $module.off('scroll' + eventNamespace); + } + }, + + add: { + inlineCSS: function() { + var + width = module.cache.width || $module.outerWidth(), + height = module.cache.height || $module.outerHeight(), + isRTL = module.is.rtl(), + direction = module.get.direction(), + distance = { + left : width, + right : -width, + top : height, + bottom : -height + }, + style + ; + + if(isRTL){ + module.verbose('RTL detected, flipping widths'); + distance.left = -width; + distance.right = width; + } + + style = ''; + $style = $(style) + .appendTo($head) + ; + module.debug('Adding sizing css to head', $style); + } + }, + + refresh: function() { + module.verbose('Refreshing selector cache'); + $context = $(settings.context); + $sidebars = $context.children(selector.sidebar); + $pusher = $context.children(selector.pusher); + $fixed = $context.children(selector.fixed); + module.clear.cache(); + }, + + refreshSidebars: function() { + module.verbose('Refreshing other sidebars'); + $sidebars = $context.children(selector.sidebar); + }, + + repaint: function() { + module.verbose('Forcing repaint event'); + element.style.display = 'none'; + var ignored = element.offsetHeight; + element.scrollTop = element.scrollTop; + element.style.display = ''; + }, + + setup: { + cache: function() { + module.cache = { + width : $module.outerWidth(), + height : $module.outerHeight(), + rtl : ($module.css('direction') == 'rtl') + }; + }, + layout: function() { + if( $context.children(selector.pusher).length === 0 ) { + module.debug('Adding wrapper element for sidebar'); + module.error(error.pusher); + $pusher = $('
'); + $context + .children() + .not(selector.omitted) + .not($sidebars) + .wrapAll($pusher) + ; + module.refresh(); + } + if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) { + module.debug('Moved sidebar to correct parent element'); + module.error(error.movedSidebar, element); + $module.detach().prependTo($context); + module.refresh(); + } + module.clear.cache(); + module.set.pushable(); + module.set.direction(); + } + }, + + attachEvents: function(selector, event) { + var + $toggle = $(selector) + ; + event = $.isFunction(module[event]) + ? module[event] + : module.toggle + ; + if($toggle.length > 0) { + module.debug('Attaching sidebar events to element', selector, event); + $toggle + .on('click' + eventNamespace, event) + ; + } + else { + module.error(error.notFound, selector); + } + }, + + show: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(module.is.hidden()) { + module.refreshSidebars(); + if(settings.overlay) { + module.error(error.overlay); + settings.transition = 'overlay'; + } + module.refresh(); + if(module.othersActive()) { + module.debug('Other sidebars currently visible'); + if(settings.exclusive) { + // if not overlay queue animation after hide + if(settings.transition != 'overlay') { + module.hideOthers(module.show); + return; + } + else { + module.hideOthers(); + } + } + else { + settings.transition = 'overlay'; + } + } + module.pushPage(function() { + callback.call(element); + settings.onShow.call(element); + }); + settings.onChange.call(element); + settings.onVisible.call(element); + } + else { + module.debug('Sidebar is already visible'); + } + }, + + hide: function(callback) { + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(module.is.visible() || module.is.animating()) { + module.debug('Hiding sidebar', callback); + module.refreshSidebars(); + module.pullPage(function() { + callback.call(element); + settings.onHidden.call(element); + }); + settings.onChange.call(element); + settings.onHide.call(element); + } + }, + + othersAnimating: function() { + return ($sidebars.not($module).filter('.' + className.animating).length > 0); + }, + othersVisible: function() { + return ($sidebars.not($module).filter('.' + className.visible).length > 0); + }, + othersActive: function() { + return(module.othersVisible() || module.othersAnimating()); + }, + + hideOthers: function(callback) { + var + $otherSidebars = $sidebars.not($module).filter('.' + className.visible), + sidebarCount = $otherSidebars.length, + callbackCount = 0 + ; + callback = callback || function(){}; + $otherSidebars + .sidebar('hide', function() { + callbackCount++; + if(callbackCount == sidebarCount) { + callback(); + } + }) + ; + }, + + toggle: function() { + module.verbose('Determining toggled direction'); + if(module.is.hidden()) { + module.show(); + } + else { + module.hide(); + } + }, + + pushPage: function(callback) { + var + transition = module.get.transition(), + $transition = (transition === 'overlay' || module.othersActive()) + ? $module + : $pusher, + animate, + dim, + transitionEnd + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + if(settings.transition == 'scale down') { + module.scrollToTop(); + } + module.set.transition(transition); + module.repaint(); + animate = function() { + module.bind.clickaway(); + module.add.inlineCSS(); + module.set.animating(); + module.set.visible(); + }; + dim = function() { + module.set.dimmed(); + }; + transitionEnd = function(event) { + if( event.target == $transition[0] ) { + $transition.off(transitionEvent + elementNamespace, transitionEnd); + module.remove.animating(); + module.bind.scrollLock(); + callback.call(element); + } + }; + $transition.off(transitionEvent + elementNamespace); + $transition.on(transitionEvent + elementNamespace, transitionEnd); + requestAnimationFrame(animate); + if(settings.dimPage && !module.othersVisible()) { + requestAnimationFrame(dim); + } + }, + + pullPage: function(callback) { + var + transition = module.get.transition(), + $transition = (transition == 'overlay' || module.othersActive()) + ? $module + : $pusher, + animate, + transitionEnd + ; + callback = $.isFunction(callback) + ? callback + : function(){} + ; + module.verbose('Removing context push state', module.get.direction()); + + module.unbind.clickaway(); + module.unbind.scrollLock(); + + animate = function() { + module.set.transition(transition); + module.set.animating(); + module.remove.visible(); + if(settings.dimPage && !module.othersVisible()) { + $pusher.removeClass(className.dimmed); + } + }; + transitionEnd = function(event) { + if( event.target == $transition[0] ) { + $transition.off(transitionEvent + elementNamespace, transitionEnd); + module.remove.animating(); + module.remove.transition(); + module.remove.inlineCSS(); + if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) { + module.scrollBack(); + } + callback.call(element); + } + }; + $transition.off(transitionEvent + elementNamespace); + $transition.on(transitionEvent + elementNamespace, transitionEnd); + requestAnimationFrame(animate); + }, + + scrollToTop: function() { + module.verbose('Scrolling to top of page to avoid animation issues'); + currentScroll = $(window).scrollTop(); + $module.scrollTop(0); + window.scrollTo(0, 0); + }, + + scrollBack: function() { + module.verbose('Scrolling back to original page position'); + window.scrollTo(0, currentScroll); + }, + + clear: { + cache: function() { + module.verbose('Clearing cached dimensions'); + module.cache = {}; + } + }, + + set: { + + // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios + // (This is no longer necessary in latest iOS) + ios: function() { + $html.addClass(className.ios); + }, + + // container + pushed: function() { + $context.addClass(className.pushed); + }, + pushable: function() { + $context.addClass(className.pushable); + }, + + // pusher + dimmed: function() { + $pusher.addClass(className.dimmed); + }, + + // sidebar + active: function() { + $module.addClass(className.active); + }, + animating: function() { + $module.addClass(className.animating); + }, + transition: function(transition) { + transition = transition || module.get.transition(); + $module.addClass(transition); + }, + direction: function(direction) { + direction = direction || module.get.direction(); + $module.addClass(className[direction]); + }, + visible: function() { + $module.addClass(className.visible); + }, + overlay: function() { + $module.addClass(className.overlay); + } + }, + remove: { + + inlineCSS: function() { + module.debug('Removing inline css styles', $style); + if($style && $style.length > 0) { + $style.remove(); + } + }, + + // ios scroll on html not document + ios: function() { + $html.removeClass(className.ios); + }, + + // context + pushed: function() { + $context.removeClass(className.pushed); + }, + pushable: function() { + $context.removeClass(className.pushable); + }, + + // sidebar + active: function() { + $module.removeClass(className.active); + }, + animating: function() { + $module.removeClass(className.animating); + }, + transition: function(transition) { + transition = transition || module.get.transition(); + $module.removeClass(transition); + }, + direction: function(direction) { + direction = direction || module.get.direction(); + $module.removeClass(className[direction]); + }, + visible: function() { + $module.removeClass(className.visible); + }, + overlay: function() { + $module.removeClass(className.overlay); + } + }, + + get: { + direction: function() { + if($module.hasClass(className.top)) { + return className.top; + } + else if($module.hasClass(className.right)) { + return className.right; + } + else if($module.hasClass(className.bottom)) { + return className.bottom; + } + return className.left; + }, + transition: function() { + var + direction = module.get.direction(), + transition + ; + transition = ( module.is.mobile() ) + ? (settings.mobileTransition == 'auto') + ? settings.defaultTransition.mobile[direction] + : settings.mobileTransition + : (settings.transition == 'auto') + ? settings.defaultTransition.computer[direction] + : settings.transition + ; + module.verbose('Determined transition', transition); + return transition; + }, + transitionEvent: function() { + var + element = document.createElement('element'), + transitions = { + 'transition' :'transitionend', + 'OTransition' :'oTransitionEnd', + 'MozTransition' :'transitionend', + 'WebkitTransition' :'webkitTransitionEnd' + }, + transition + ; + for(transition in transitions){ + if( element.style[transition] !== undefined ){ + return transitions[transition]; + } + } + } + }, + + is: { + + ie: function() { + var + isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window), + isIE = ('ActiveXObject' in window) + ; + return (isIE11 || isIE); + }, + + ios: function() { + var + userAgent = navigator.userAgent, + isIOS = userAgent.match(regExp.ios), + isMobileChrome = userAgent.match(regExp.mobileChrome) + ; + if(isIOS && !isMobileChrome) { + module.verbose('Browser was found to be iOS', userAgent); + return true; + } + else { + return false; + } + }, + mobile: function() { + var + userAgent = navigator.userAgent, + isMobile = userAgent.match(regExp.mobile) + ; + if(isMobile) { + module.verbose('Browser was found to be mobile', userAgent); + return true; + } + else { + module.verbose('Browser is not mobile, using regular transition', userAgent); + return false; + } + }, + hidden: function() { + return !module.is.visible(); + }, + visible: function() { + return $module.hasClass(className.visible); + }, + // alias + open: function() { + return module.is.visible(); + }, + closed: function() { + return module.is.hidden(); + }, + vertical: function() { + return $module.hasClass(className.top); + }, + animating: function() { + return $context.hasClass(className.animating); + }, + rtl: function () { + if(module.cache.rtl === undefined) { + module.cache.rtl = ($module.css('direction') == 'rtl'); + } + return module.cache.rtl; + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + } + ; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + module.invoke('destroy'); + } + module.initialize(); + } + }); + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.sidebar.settings = { + + name : 'Sidebar', + namespace : 'sidebar', + + silent : false, + debug : false, + verbose : false, + performance : true, + + transition : 'auto', + mobileTransition : 'auto', + + defaultTransition : { + computer: { + left : 'uncover', + right : 'uncover', + top : 'overlay', + bottom : 'overlay' + }, + mobile: { + left : 'uncover', + right : 'uncover', + top : 'overlay', + bottom : 'overlay' + } + }, + + context : 'body', + exclusive : false, + closable : true, + dimPage : true, + scrollLock : false, + returnScroll : false, + delaySetup : false, + + duration : 500, + + onChange : function(){}, + onShow : function(){}, + onHide : function(){}, + + onHidden : function(){}, + onVisible : function(){}, + + className : { + active : 'active', + animating : 'animating', + dimmed : 'dimmed', + ios : 'ios', + pushable : 'pushable', + pushed : 'pushed', + right : 'right', + top : 'top', + left : 'left', + bottom : 'bottom', + visible : 'visible' + }, + + selector: { + fixed : '.fixed', + omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed', + pusher : '.pusher', + sidebar : '.ui.sidebar' + }, + + regExp: { + ios : /(iPad|iPhone|iPod)/g, + mobileChrome : /(CriOS)/g, + mobile : /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g + }, + + error : { + method : 'The method you called is not defined.', + pusher : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element', + movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag', + overlay : 'The overlay setting is no longer supported, use animation: overlay', + notFound : 'There were no elements that matched the specified selector' + } + +}; + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Sticky + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.sticky = function(parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.sticky.settings, parameters) + : $.extend({}, $.fn.sticky.settings), + + className = settings.className, + namespace = settings.namespace, + error = settings.error, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $module = $(this), + $window = $(window), + $scroll = $(settings.scrollContext), + $container, + $context, + + selector = $module.selector || '', + instance = $module.data(moduleNamespace), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + element = this, + + documentObserver, + observer, + module + ; + + module = { + + initialize: function() { + + module.determineContainer(); + module.determineContext(); + module.verbose('Initializing sticky', settings, $container); + + module.save.positions(); + module.checkErrors(); + module.bind.events(); + + if(settings.observeChanges) { + module.observeChanges(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.verbose('Destroying previous instance'); + module.reset(); + if(documentObserver) { + documentObserver.disconnect(); + } + if(observer) { + observer.disconnect(); + } + $window + .off('load' + eventNamespace, module.event.load) + .off('resize' + eventNamespace, module.event.resize) + ; + $scroll + .off('scrollchange' + eventNamespace, module.event.scrollchange) + ; + $module.removeData(moduleNamespace); + }, + + observeChanges: function() { + if('MutationObserver' in window) { + documentObserver = new MutationObserver(module.event.documentChanged); + observer = new MutationObserver(module.event.changed); + documentObserver.observe(document, { + childList : true, + subtree : true + }); + observer.observe(element, { + childList : true, + subtree : true + }); + observer.observe($context[0], { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + determineContainer: function() { + if(settings.container) { + $container = $(settings.container); + } + else { + $container = $module.offsetParent(); + } + }, + + determineContext: function() { + if(settings.context) { + $context = $(settings.context); + } + else { + $context = $container; + } + if($context.length === 0) { + module.error(error.invalidContext, settings.context, $module); + return; + } + }, + + checkErrors: function() { + if( module.is.hidden() ) { + module.error(error.visible, $module); + } + if(module.cache.element.height > module.cache.context.height) { + module.reset(); + module.error(error.elementSize, $module); + return; + } + }, + + bind: { + events: function() { + $window + .on('load' + eventNamespace, module.event.load) + .on('resize' + eventNamespace, module.event.resize) + ; + // pub/sub pattern + $scroll + .off('scroll' + eventNamespace) + .on('scroll' + eventNamespace, module.event.scroll) + .on('scrollchange' + eventNamespace, module.event.scrollchange) + ; + } + }, + + event: { + changed: function(mutations) { + clearTimeout(module.timer); + module.timer = setTimeout(function() { + module.verbose('DOM tree modified, updating sticky menu', mutations); + module.refresh(); + }, 100); + }, + documentChanged: function(mutations) { + [].forEach.call(mutations, function(mutation) { + if(mutation.removedNodes) { + [].forEach.call(mutation.removedNodes, function(node) { + if(node == element || $(node).find(element).length > 0) { + module.debug('Element removed from DOM, tearing down events'); + module.destroy(); + } + }); + } + }); + }, + load: function() { + module.verbose('Page contents finished loading'); + requestAnimationFrame(module.refresh); + }, + resize: function() { + module.verbose('Window resized'); + requestAnimationFrame(module.refresh); + }, + scroll: function() { + requestAnimationFrame(function() { + $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() ); + }); + }, + scrollchange: function(event, scrollPosition) { + module.stick(scrollPosition); + settings.onScroll.call(element); + } + }, + + refresh: function(hardRefresh) { + module.reset(); + if(!settings.context) { + module.determineContext(); + } + if(hardRefresh) { + module.determineContainer(); + } + module.save.positions(); + module.stick(); + settings.onReposition.call(element); + }, + + supports: { + sticky: function() { + var + $element = $('
'), + element = $element[0] + ; + $element.addClass(className.supported); + return($element.css('position').match('sticky')); + } + }, + + save: { + lastScroll: function(scroll) { + module.lastScroll = scroll; + }, + elementScroll: function(scroll) { + module.elementScroll = scroll; + }, + positions: function() { + var + scrollContext = { + height : $scroll.height() + }, + element = { + margin: { + top : parseInt($module.css('margin-top'), 10), + bottom : parseInt($module.css('margin-bottom'), 10), + }, + offset : $module.offset(), + width : $module.outerWidth(), + height : $module.outerHeight() + }, + context = { + offset : $context.offset(), + height : $context.outerHeight() + }, + container = { + height: $container.outerHeight() + } + ; + if( !module.is.standardScroll() ) { + module.debug('Non-standard scroll. Removing scroll offset from element offset'); + + scrollContext.top = $scroll.scrollTop(); + scrollContext.left = $scroll.scrollLeft(); + + element.offset.top += scrollContext.top; + context.offset.top += scrollContext.top; + element.offset.left += scrollContext.left; + context.offset.left += scrollContext.left; + } + module.cache = { + fits : ( (element.height + settings.offset) <= scrollContext.height), + sameHeight : (element.height == context.height), + scrollContext : { + height : scrollContext.height + }, + element: { + margin : element.margin, + top : element.offset.top - element.margin.top, + left : element.offset.left, + width : element.width, + height : element.height, + bottom : element.offset.top + element.height + }, + context: { + top : context.offset.top, + height : context.height, + bottom : context.offset.top + context.height + } + }; + module.set.containerSize(); + + module.stick(); + module.debug('Caching element positions', module.cache); + } + }, + + get: { + direction: function(scroll) { + var + direction = 'down' + ; + scroll = scroll || $scroll.scrollTop(); + if(module.lastScroll !== undefined) { + if(module.lastScroll < scroll) { + direction = 'down'; + } + else if(module.lastScroll > scroll) { + direction = 'up'; + } + } + return direction; + }, + scrollChange: function(scroll) { + scroll = scroll || $scroll.scrollTop(); + return (module.lastScroll) + ? (scroll - module.lastScroll) + : 0 + ; + }, + currentElementScroll: function() { + if(module.elementScroll) { + return module.elementScroll; + } + return ( module.is.top() ) + ? Math.abs(parseInt($module.css('top'), 10)) || 0 + : Math.abs(parseInt($module.css('bottom'), 10)) || 0 + ; + }, + + elementScroll: function(scroll) { + scroll = scroll || $scroll.scrollTop(); + var + element = module.cache.element, + scrollContext = module.cache.scrollContext, + delta = module.get.scrollChange(scroll), + maxScroll = (element.height - scrollContext.height + settings.offset), + elementScroll = module.get.currentElementScroll(), + possibleScroll = (elementScroll + delta) + ; + if(module.cache.fits || possibleScroll < 0) { + elementScroll = 0; + } + else if(possibleScroll > maxScroll ) { + elementScroll = maxScroll; + } + else { + elementScroll = possibleScroll; + } + return elementScroll; + } + }, + + remove: { + lastScroll: function() { + delete module.lastScroll; + }, + elementScroll: function(scroll) { + delete module.elementScroll; + }, + minimumSize: function() { + $container + .css('min-height', '') + ; + }, + offset: function() { + $module.css('margin-top', ''); + } + }, + + set: { + offset: function() { + module.verbose('Setting offset on element', settings.offset); + $module + .css('margin-top', settings.offset) + ; + }, + containerSize: function() { + var + tagName = $container.get(0).tagName + ; + if(tagName === 'HTML' || tagName == 'body') { + // this can trigger for too many reasons + //module.error(error.container, tagName, $module); + module.determineContainer(); + } + else { + if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) { + module.debug('Context has padding, specifying exact height for container', module.cache.context.height); + $container.css({ + height: module.cache.context.height + }); + } + } + }, + minimumSize: function() { + var + element = module.cache.element + ; + $container + .css('min-height', element.height) + ; + }, + scroll: function(scroll) { + module.debug('Setting scroll on element', scroll); + if(module.elementScroll == scroll) { + return; + } + if( module.is.top() ) { + $module + .css('bottom', '') + .css('top', -scroll) + ; + } + if( module.is.bottom() ) { + $module + .css('top', '') + .css('bottom', scroll) + ; + } + }, + size: function() { + if(module.cache.element.height !== 0 && module.cache.element.width !== 0) { + element.style.setProperty('width', module.cache.element.width + 'px', 'important'); + element.style.setProperty('height', module.cache.element.height + 'px', 'important'); + } + } + }, + + is: { + standardScroll: function() { + return ($scroll[0] == window); + }, + top: function() { + return $module.hasClass(className.top); + }, + bottom: function() { + return $module.hasClass(className.bottom); + }, + initialPosition: function() { + return (!module.is.fixed() && !module.is.bound()); + }, + hidden: function() { + return (!$module.is(':visible')); + }, + bound: function() { + return $module.hasClass(className.bound); + }, + fixed: function() { + return $module.hasClass(className.fixed); + } + }, + + stick: function(scroll) { + var + cachedPosition = scroll || $scroll.scrollTop(), + cache = module.cache, + fits = cache.fits, + sameHeight = cache.sameHeight, + element = cache.element, + scrollContext = cache.scrollContext, + context = cache.context, + offset = (module.is.bottom() && settings.pushing) + ? settings.bottomOffset + : settings.offset, + scroll = { + top : cachedPosition + offset, + bottom : cachedPosition + offset + scrollContext.height + }, + direction = module.get.direction(scroll.top), + elementScroll = (fits) + ? 0 + : module.get.elementScroll(scroll.top), + + // shorthand + doesntFit = !fits, + elementVisible = (element.height !== 0) + ; + if(elementVisible && !sameHeight) { + + if( module.is.initialPosition() ) { + if(scroll.top >= context.bottom) { + module.debug('Initial element position is bottom of container'); + module.bindBottom(); + } + else if(scroll.top > element.top) { + if( (element.height + scroll.top - elementScroll) >= context.bottom ) { + module.debug('Initial element position is bottom of container'); + module.bindBottom(); + } + else { + module.debug('Initial element position is fixed'); + module.fixTop(); + } + } + + } + else if( module.is.fixed() ) { + + // currently fixed top + if( module.is.top() ) { + if( scroll.top <= element.top ) { + module.debug('Fixed element reached top of container'); + module.setInitialPosition(); + } + else if( (element.height + scroll.top - elementScroll) >= context.bottom ) { + module.debug('Fixed element reached bottom of container'); + module.bindBottom(); + } + // scroll element if larger than screen + else if(doesntFit) { + module.set.scroll(elementScroll); + module.save.lastScroll(scroll.top); + module.save.elementScroll(elementScroll); + } + } + + // currently fixed bottom + else if(module.is.bottom() ) { + + // top edge + if( (scroll.bottom - element.height) <= element.top) { + module.debug('Bottom fixed rail has reached top of container'); + module.setInitialPosition(); + } + // bottom edge + else if(scroll.bottom >= context.bottom) { + module.debug('Bottom fixed rail has reached bottom of container'); + module.bindBottom(); + } + // scroll element if larger than screen + else if(doesntFit) { + module.set.scroll(elementScroll); + module.save.lastScroll(scroll.top); + module.save.elementScroll(elementScroll); + } + + } + } + else if( module.is.bottom() ) { + if( scroll.top <= element.top ) { + module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button'); + module.setInitialPosition(); + } + else { + if(settings.pushing) { + if(module.is.bound() && scroll.bottom <= context.bottom ) { + module.debug('Fixing bottom attached element to bottom of browser.'); + module.fixBottom(); + } + } + else { + if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) { + module.debug('Fixing bottom attached element to top of browser.'); + module.fixTop(); + } + } + } + } + } + }, + + bindTop: function() { + module.debug('Binding element to top of parent container'); + module.remove.offset(); + $module + .css({ + left : '', + top : '', + marginBottom : '' + }) + .removeClass(className.fixed) + .removeClass(className.bottom) + .addClass(className.bound) + .addClass(className.top) + ; + settings.onTop.call(element); + settings.onUnstick.call(element); + }, + bindBottom: function() { + module.debug('Binding element to bottom of parent container'); + module.remove.offset(); + $module + .css({ + left : '', + top : '' + }) + .removeClass(className.fixed) + .removeClass(className.top) + .addClass(className.bound) + .addClass(className.bottom) + ; + settings.onBottom.call(element); + settings.onUnstick.call(element); + }, + + setInitialPosition: function() { + module.debug('Returning to initial position'); + module.unfix(); + module.unbind(); + }, + + + fixTop: function() { + module.debug('Fixing element to top of page'); + if(settings.setSize) { + module.set.size(); + } + module.set.minimumSize(); + module.set.offset(); + $module + .css({ + left : module.cache.element.left, + bottom : '', + marginBottom : '' + }) + .removeClass(className.bound) + .removeClass(className.bottom) + .addClass(className.fixed) + .addClass(className.top) + ; + settings.onStick.call(element); + }, + + fixBottom: function() { + module.debug('Sticking element to bottom of page'); + if(settings.setSize) { + module.set.size(); + } + module.set.minimumSize(); + module.set.offset(); + $module + .css({ + left : module.cache.element.left, + bottom : '', + marginBottom : '' + }) + .removeClass(className.bound) + .removeClass(className.top) + .addClass(className.fixed) + .addClass(className.bottom) + ; + settings.onStick.call(element); + }, + + unbind: function() { + if( module.is.bound() ) { + module.debug('Removing container bound position on element'); + module.remove.offset(); + $module + .removeClass(className.bound) + .removeClass(className.top) + .removeClass(className.bottom) + ; + } + }, + + unfix: function() { + if( module.is.fixed() ) { + module.debug('Removing fixed position on element'); + module.remove.minimumSize(); + module.remove.offset(); + $module + .removeClass(className.fixed) + .removeClass(className.top) + .removeClass(className.bottom) + ; + settings.onUnstick.call(element); + } + }, + + reset: function() { + module.debug('Resetting elements position'); + module.unbind(); + module.unfix(); + module.resetCSS(); + module.remove.offset(); + module.remove.lastScroll(); + }, + + resetCSS: function() { + $module + .css({ + width : '', + height : '' + }) + ; + $container + .css({ + height: '' + }) + ; + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + settings[name] = value; + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 0); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.sticky.settings = { + + name : 'Sticky', + namespace : 'sticky', + + silent : false, + debug : false, + verbose : true, + performance : true, + + // whether to stick in the opposite direction on scroll up + pushing : false, + + context : false, + container : false, + + // Context to watch scroll events + scrollContext : window, + + // Offset to adjust scroll + offset : 0, + + // Offset to adjust scroll when attached to bottom of screen + bottomOffset : 0, + + // will only set container height if difference between context and container is larger than this number + jitter : 5, + + // set width of sticky element when it is fixed to page (used to make sure 100% width is maintained if no fixed size set) + setSize : true, + + // Whether to automatically observe changes with Mutation Observers + observeChanges : false, + + // Called when position is recalculated + onReposition : function(){}, + + // Called on each scroll + onScroll : function(){}, + + // Called when element is stuck to viewport + onStick : function(){}, + + // Called when element is unstuck from viewport + onUnstick : function(){}, + + // Called when element reaches top of context + onTop : function(){}, + + // Called when element reaches bottom of context + onBottom : function(){}, + + error : { + container : 'Sticky element must be inside a relative container', + visible : 'Element is hidden, you must call refresh after element becomes visible. Use silent setting to surpress this warning in production.', + method : 'The method you called is not defined.', + invalidContext : 'Context specified does not exist', + elementSize : 'Sticky element is larger than its container, cannot create sticky.' + }, + + className : { + bound : 'bound', + fixed : 'fixed', + supported : 'native', + top : 'top', + bottom : 'bottom' + } + +}; + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Tab + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.tab = function(parameters) { + + var + // use window context if none specified + $allModules = $.isFunction(this) + ? $(window) + : $(this), + + moduleSelector = $allModules.selector || '', + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + initializedHistory = false, + returnedValue + ; + + $allModules + .each(function() { + var + + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.tab.settings, parameters) + : $.extend({}, $.fn.tab.settings), + + className = settings.className, + metadata = settings.metadata, + selector = settings.selector, + error = settings.error, + + eventNamespace = '.' + settings.namespace, + moduleNamespace = 'module-' + settings.namespace, + + $module = $(this), + $context, + $tabs, + + cache = {}, + firstLoad = true, + recursionDepth = 0, + element = this, + instance = $module.data(moduleNamespace), + + activeTabPath, + parameterArray, + module, + + historyEvent + + ; + + module = { + + initialize: function() { + module.debug('Initializing tab menu item', $module); + module.fix.callbacks(); + module.determineTabs(); + + module.debug('Determining tabs', settings.context, $tabs); + // set up automatic routing + if(settings.auto) { + module.set.auto(); + } + module.bind.events(); + + if(settings.history && !initializedHistory) { + module.initializeHistory(); + initializedHistory = true; + } + + module.instantiate(); + }, + + instantiate: function () { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, module) + ; + }, + + destroy: function() { + module.debug('Destroying tabs', $module); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + bind: { + events: function() { + // if using $.tab don't add events + if( !$.isWindow( element ) ) { + module.debug('Attaching tab activation events to element', $module); + $module + .on('click' + eventNamespace, module.event.click) + ; + } + } + }, + + determineTabs: function() { + var + $reference + ; + + // determine tab context + if(settings.context === 'parent') { + if($module.closest(selector.ui).length > 0) { + $reference = $module.closest(selector.ui); + module.verbose('Using closest UI element as parent', $reference); + } + else { + $reference = $module; + } + $context = $reference.parent(); + module.verbose('Determined parent element for creating context', $context); + } + else if(settings.context) { + $context = $(settings.context); + module.verbose('Using selector for tab context', settings.context, $context); + } + else { + $context = $('body'); + } + // find tabs + if(settings.childrenOnly) { + $tabs = $context.children(selector.tabs); + module.debug('Searching tab context children for tabs', $context, $tabs); + } + else { + $tabs = $context.find(selector.tabs); + module.debug('Searching tab context for tabs', $context, $tabs); + } + }, + + fix: { + callbacks: function() { + if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) { + if(parameters.onTabLoad) { + parameters.onLoad = parameters.onTabLoad; + delete parameters.onTabLoad; + module.error(error.legacyLoad, parameters.onLoad); + } + if(parameters.onTabInit) { + parameters.onFirstLoad = parameters.onTabInit; + delete parameters.onTabInit; + module.error(error.legacyInit, parameters.onFirstLoad); + } + settings = $.extend(true, {}, $.fn.tab.settings, parameters); + } + } + }, + + initializeHistory: function() { + module.debug('Initializing page state'); + if( $.address === undefined ) { + module.error(error.state); + return false; + } + else { + if(settings.historyType == 'state') { + module.debug('Using HTML5 to manage state'); + if(settings.path !== false) { + $.address + .history(true) + .state(settings.path) + ; + } + else { + module.error(error.path); + return false; + } + } + $.address + .bind('change', module.event.history.change) + ; + } + }, + + event: { + click: function(event) { + var + tabPath = $(this).data(metadata.tab) + ; + if(tabPath !== undefined) { + if(settings.history) { + module.verbose('Updating page state', event); + $.address.value(tabPath); + } + else { + module.verbose('Changing tab', event); + module.changeTab(tabPath); + } + event.preventDefault(); + } + else { + module.debug('No tab specified'); + } + }, + history: { + change: function(event) { + var + tabPath = event.pathNames.join('/') || module.get.initialPath(), + pageTitle = settings.templates.determineTitle(tabPath) || false + ; + module.performance.display(); + module.debug('History change event', tabPath, event); + historyEvent = event; + if(tabPath !== undefined) { + module.changeTab(tabPath); + } + if(pageTitle) { + $.address.title(pageTitle); + } + } + } + }, + + refresh: function() { + if(activeTabPath) { + module.debug('Refreshing tab', activeTabPath); + module.changeTab(activeTabPath); + } + }, + + cache: { + + read: function(cacheKey) { + return (cacheKey !== undefined) + ? cache[cacheKey] + : false + ; + }, + add: function(cacheKey, content) { + cacheKey = cacheKey || activeTabPath; + module.debug('Adding cached content for', cacheKey); + cache[cacheKey] = content; + }, + remove: function(cacheKey) { + cacheKey = cacheKey || activeTabPath; + module.debug('Removing cached content for', cacheKey); + delete cache[cacheKey]; + } + }, + + set: { + auto: function() { + var + url = (typeof settings.path == 'string') + ? settings.path.replace(/\/$/, '') + '/{$tab}' + : '/{$tab}' + ; + module.verbose('Setting up automatic tab retrieval from server', url); + if($.isPlainObject(settings.apiSettings)) { + settings.apiSettings.url = url; + } + else { + settings.apiSettings = { + url: url + }; + } + }, + loading: function(tabPath) { + var + $tab = module.get.tabElement(tabPath), + isLoading = $tab.hasClass(className.loading) + ; + if(!isLoading) { + module.verbose('Setting loading state for', $tab); + $tab + .addClass(className.loading) + .siblings($tabs) + .removeClass(className.active + ' ' + className.loading) + ; + if($tab.length > 0) { + settings.onRequest.call($tab[0], tabPath); + } + } + }, + state: function(state) { + $.address.value(state); + } + }, + + changeTab: function(tabPath) { + var + pushStateAvailable = (window.history && window.history.pushState), + shouldIgnoreLoad = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad), + remoteContent = (settings.auto || $.isPlainObject(settings.apiSettings) ), + // only add default path if not remote content + pathArray = (remoteContent && !shouldIgnoreLoad) + ? module.utilities.pathToArray(tabPath) + : module.get.defaultPathArray(tabPath) + ; + tabPath = module.utilities.arrayToPath(pathArray); + $.each(pathArray, function(index, tab) { + var + currentPathArray = pathArray.slice(0, index + 1), + currentPath = module.utilities.arrayToPath(currentPathArray), + + isTab = module.is.tab(currentPath), + isLastIndex = (index + 1 == pathArray.length), + + $tab = module.get.tabElement(currentPath), + $anchor, + nextPathArray, + nextPath, + isLastTab + ; + module.verbose('Looking for tab', tab); + if(isTab) { + module.verbose('Tab was found', tab); + // scope up + activeTabPath = currentPath; + parameterArray = module.utilities.filterArray(pathArray, currentPathArray); + + if(isLastIndex) { + isLastTab = true; + } + else { + nextPathArray = pathArray.slice(0, index + 2); + nextPath = module.utilities.arrayToPath(nextPathArray); + isLastTab = ( !module.is.tab(nextPath) ); + if(isLastTab) { + module.verbose('Tab parameters found', nextPathArray); + } + } + if(isLastTab && remoteContent) { + if(!shouldIgnoreLoad) { + module.activate.navigation(currentPath); + module.fetch.content(currentPath, tabPath); + } + else { + module.debug('Ignoring remote content on first tab load', currentPath); + firstLoad = false; + module.cache.add(tabPath, $tab.html()); + module.activate.all(currentPath); + settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); + settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + return false; + } + else { + module.debug('Opened local tab', currentPath); + module.activate.all(currentPath); + if( !module.cache.read(currentPath) ) { + module.cache.add(currentPath, true); + module.debug('First time tab loaded calling tab init'); + settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + + } + else if(tabPath.search('/') == -1 && tabPath !== '') { + // look for in page anchor + $anchor = $('#' + tabPath + ', a[name="' + tabPath + '"]'); + currentPath = $anchor.closest('[data-tab]').data(metadata.tab); + $tab = module.get.tabElement(currentPath); + // if anchor exists use parent tab + if($anchor && $anchor.length > 0 && currentPath) { + module.debug('Anchor link used, opening parent tab', $tab, $anchor); + if( !$tab.hasClass(className.active) ) { + setTimeout(function() { + module.scrollTo($anchor); + }, 0); + } + module.activate.all(currentPath); + if( !module.cache.read(currentPath) ) { + module.cache.add(currentPath, true); + module.debug('First time tab loaded calling tab init'); + settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent); + } + settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent); + return false; + } + } + else { + module.error(error.missingTab, $module, $context, currentPath); + return false; + } + }); + }, + + scrollTo: function($element) { + var + scrollOffset = ($element && $element.length > 0) + ? $element.offset().top + : false + ; + if(scrollOffset !== false) { + module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element); + $(document).scrollTop(scrollOffset); + } + }, + + update: { + content: function(tabPath, html, evaluateScripts) { + var + $tab = module.get.tabElement(tabPath), + tab = $tab[0] + ; + evaluateScripts = (evaluateScripts !== undefined) + ? evaluateScripts + : settings.evaluateScripts + ; + if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') { + $tab + .empty() + .append($(html).clone(true)) + ; + } + else { + if(evaluateScripts) { + module.debug('Updating HTML and evaluating inline scripts', tabPath, html); + $tab.html(html); + } + else { + module.debug('Updating HTML', tabPath, html); + tab.innerHTML = html; + } + } + } + }, + + fetch: { + + content: function(tabPath, fullTabPath) { + var + $tab = module.get.tabElement(tabPath), + apiSettings = { + dataType : 'html', + encodeParameters : false, + on : 'now', + cache : settings.alwaysRefresh, + headers : { + 'X-Remote': true + }, + onSuccess : function(response) { + if(settings.cacheType == 'response') { + module.cache.add(fullTabPath, response); + } + module.update.content(tabPath, response); + if(tabPath == activeTabPath) { + module.debug('Content loaded', tabPath); + module.activate.tab(tabPath); + } + else { + module.debug('Content loaded in background', tabPath); + } + settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent); + settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); + + if(settings.loadOnce) { + module.cache.add(fullTabPath, true); + } + else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) { + setTimeout(function() { + var + $clone = $tab.children().clone(true) + ; + $clone = $clone.not('script'); + module.cache.add(fullTabPath, $clone); + }, 0); + } + else { + module.cache.add(fullTabPath, $tab.html()); + } + }, + urlData: { + tab: fullTabPath + } + }, + request = $tab.api('get request') || false, + existingRequest = ( request && request.state() === 'pending' ), + requestSettings, + cachedContent + ; + + fullTabPath = fullTabPath || tabPath; + cachedContent = module.cache.read(fullTabPath); + + + if(settings.cache && cachedContent) { + module.activate.tab(tabPath); + module.debug('Adding cached content', fullTabPath); + if(!settings.loadOnce) { + if(settings.evaluateScripts == 'once') { + module.update.content(tabPath, cachedContent, false); + } + else { + module.update.content(tabPath, cachedContent); + } + } + settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent); + } + else if(existingRequest) { + module.set.loading(tabPath); + module.debug('Content is already loading', fullTabPath); + } + else if($.api !== undefined) { + requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings); + module.debug('Retrieving remote content', fullTabPath, requestSettings); + module.set.loading(tabPath); + $tab.api(requestSettings); + } + else { + module.error(error.api); + } + } + }, + + activate: { + all: function(tabPath) { + module.activate.tab(tabPath); + module.activate.navigation(tabPath); + }, + tab: function(tabPath) { + var + $tab = module.get.tabElement(tabPath), + $deactiveTabs = (settings.deactivate == 'siblings') + ? $tab.siblings($tabs) + : $tabs.not($tab), + isActive = $tab.hasClass(className.active) + ; + module.verbose('Showing tab content for', $tab); + if(!isActive) { + $tab + .addClass(className.active) + ; + $deactiveTabs + .removeClass(className.active + ' ' + className.loading) + ; + if($tab.length > 0) { + settings.onVisible.call($tab[0], tabPath); + } + } + }, + navigation: function(tabPath) { + var + $navigation = module.get.navElement(tabPath), + $deactiveNavigation = (settings.deactivate == 'siblings') + ? $navigation.siblings($allModules) + : $allModules.not($navigation), + isActive = $navigation.hasClass(className.active) + ; + module.verbose('Activating tab navigation for', $navigation, tabPath); + if(!isActive) { + $navigation + .addClass(className.active) + ; + $deactiveNavigation + .removeClass(className.active + ' ' + className.loading) + ; + } + } + }, + + deactivate: { + all: function() { + module.deactivate.navigation(); + module.deactivate.tabs(); + }, + navigation: function() { + $allModules + .removeClass(className.active) + ; + }, + tabs: function() { + $tabs + .removeClass(className.active + ' ' + className.loading) + ; + } + }, + + is: { + tab: function(tabName) { + return (tabName !== undefined) + ? ( module.get.tabElement(tabName).length > 0 ) + : false + ; + } + }, + + get: { + initialPath: function() { + return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab); + }, + path: function() { + return $.address.value(); + }, + // adds default tabs to tab path + defaultPathArray: function(tabPath) { + return module.utilities.pathToArray( module.get.defaultPath(tabPath) ); + }, + defaultPath: function(tabPath) { + var + $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0), + defaultTab = $defaultNav.data(metadata.tab) || false + ; + if( defaultTab ) { + module.debug('Found default tab', defaultTab); + if(recursionDepth < settings.maxDepth) { + recursionDepth++; + return module.get.defaultPath(defaultTab); + } + module.error(error.recursion); + } + else { + module.debug('No default tabs found for', tabPath, $tabs); + } + recursionDepth = 0; + return tabPath; + }, + navElement: function(tabPath) { + tabPath = tabPath || activeTabPath; + return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); + }, + tabElement: function(tabPath) { + var + $fullPathTab, + $simplePathTab, + tabPathArray, + lastTab + ; + tabPath = tabPath || activeTabPath; + tabPathArray = module.utilities.pathToArray(tabPath); + lastTab = module.utilities.last(tabPathArray); + $fullPathTab = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]'); + $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]'); + return ($fullPathTab.length > 0) + ? $fullPathTab + : $simplePathTab + ; + }, + tab: function() { + return activeTabPath; + } + }, + + utilities: { + filterArray: function(keepArray, removeArray) { + return $.grep(keepArray, function(keepValue) { + return ( $.inArray(keepValue, removeArray) == -1); + }); + }, + last: function(array) { + return $.isArray(array) + ? array[ array.length - 1] + : false + ; + }, + pathToArray: function(pathName) { + if(pathName === undefined) { + pathName = activeTabPath; + } + return typeof pathName == 'string' + ? pathName.split('/') + : [pathName] + ; + }, + arrayToPath: function(pathArray) { + return $.isArray(pathArray) + ? pathArray.join('/') + : false + ; + } + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + return (returnedValue !== undefined) + ? returnedValue + : this + ; + +}; + +// shortcut for tabbed content with no defined navigation +$.tab = function() { + $(window).tab.apply(this, arguments); +}; + +$.fn.tab.settings = { + + name : 'Tab', + namespace : 'tab', + + silent : false, + debug : false, + verbose : false, + performance : true, + + auto : false, // uses pjax style endpoints fetching content from same url with remote-content headers + history : false, // use browser history + historyType : 'hash', // #/ or html5 state + path : false, // base path of url + + context : false, // specify a context that tabs must appear inside + childrenOnly : false, // use only tabs that are children of context + maxDepth : 25, // max depth a tab can be nested + + deactivate : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together + + alwaysRefresh : false, // load tab content new every tab click + cache : true, // cache the content requests to pull locally + loadOnce : false, // Whether tab data should only be loaded once when using remote content + cacheType : 'response', // Whether to cache exact response, or to html cache contents after scripts execute + ignoreFirstLoad : false, // don't load remote content on first load + + apiSettings : false, // settings for api call + evaluateScripts : 'once', // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content + + onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded + onLoad : function(tabPath, parameterArray, historyEvent) {}, // called on every load + onVisible : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible + onRequest : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content + + templates : { + determineTitle: function(tabArray) {} // returns page title for path + }, + + error: { + api : 'You attempted to load content without API module', + method : 'The method you called is not defined', + missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.', + noContent : 'The tab you specified is missing a content url.', + path : 'History enabled, but no path was specified', + recursion : 'Max recursive depth reached', + legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.', + legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code', + state : 'History requires Asual\'s Address library ' + }, + + metadata : { + tab : 'tab', + loaded : 'loaded', + promise: 'promise' + }, + + className : { + loading : 'loading', + active : 'active' + }, + + selector : { + tabs : '.ui.tab', + ui : '.ui' + } + +}; + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Transition + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.transition = function() { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + moduleArguments = arguments, + query = moduleArguments[0], + queryArguments = [].slice.call(arguments, 1), + methodInvoked = (typeof query === 'string'), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + returnedValue + ; + $allModules + .each(function(index) { + var + $module = $(this), + element = this, + + // set at run time + settings, + instance, + + error, + className, + metadata, + animationEnd, + animationName, + + namespace, + moduleNamespace, + eventNamespace, + module + ; + + module = { + + initialize: function() { + + // get full settings + settings = module.get.settings.apply(element, moduleArguments); + + // shorthand + className = settings.className; + error = settings.error; + metadata = settings.metadata; + + // define namespace + eventNamespace = '.' + settings.namespace; + moduleNamespace = 'module-' + settings.namespace; + instance = $module.data(moduleNamespace) || module; + + // get vendor specific events + animationEnd = module.get.animationEndEvent(); + + if(methodInvoked) { + methodInvoked = module.invoke(query); + } + + // method not invoked, lets run an animation + if(methodInvoked === false) { + module.verbose('Converted arguments into settings object', settings); + if(settings.interval) { + module.delay(settings.animate); + } + else { + module.animate(); + } + module.instantiate(); + } + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module for', element); + $module + .removeData(moduleNamespace) + ; + }, + + refresh: function() { + module.verbose('Refreshing display type on next animation'); + delete module.displayType; + }, + + forceRepaint: function() { + module.verbose('Forcing element repaint'); + var + $parentElement = $module.parent(), + $nextElement = $module.next() + ; + if($nextElement.length === 0) { + $module.detach().appendTo($parentElement); + } + else { + $module.detach().insertBefore($nextElement); + } + }, + + repaint: function() { + module.verbose('Repainting element'); + var + fakeAssignment = element.offsetWidth + ; + }, + + delay: function(interval) { + var + direction = module.get.animationDirection(), + shouldReverse, + delay + ; + if(!direction) { + direction = module.can.transition() + ? module.get.direction() + : 'static' + ; + } + interval = (interval !== undefined) + ? interval + : settings.interval + ; + shouldReverse = (settings.reverse == 'auto' && direction == className.outward); + delay = (shouldReverse || settings.reverse == true) + ? ($allModules.length - index) * settings.interval + : index * settings.interval + ; + module.debug('Delaying animation by', delay); + setTimeout(module.animate, delay); + }, + + animate: function(overrideSettings) { + settings = overrideSettings || settings; + if(!module.is.supported()) { + module.error(error.support); + return false; + } + module.debug('Preparing animation', settings.animation); + if(module.is.animating()) { + if(settings.queue) { + if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) { + module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation); + } + else { + module.queue(settings.animation); + } + return false; + } + else if(!settings.allowRepeats && module.is.occurring()) { + module.debug('Animation is already occurring, will not execute repeated animation', settings.animation); + return false; + } + else { + module.debug('New animation started, completing previous early', settings.animation); + instance.complete(); + } + } + if( module.can.animate() ) { + module.set.animating(settings.animation); + } + else { + module.error(error.noAnimation, settings.animation, element); + } + }, + + reset: function() { + module.debug('Resetting animation to beginning conditions'); + module.remove.animationCallbacks(); + module.restore.conditions(); + module.remove.animating(); + }, + + queue: function(animation) { + module.debug('Queueing animation of', animation); + module.queuing = true; + $module + .one(animationEnd + '.queue' + eventNamespace, function() { + module.queuing = false; + module.repaint(); + module.animate.apply(this, settings); + }) + ; + }, + + complete: function (event) { + module.debug('Animation complete', settings.animation); + module.remove.completeCallback(); + module.remove.failSafe(); + if(!module.is.looping()) { + if( module.is.outward() ) { + module.verbose('Animation is outward, hiding element'); + module.restore.conditions(); + module.hide(); + } + else if( module.is.inward() ) { + module.verbose('Animation is outward, showing element'); + module.restore.conditions(); + module.show(); + } + else { + module.verbose('Static animation completed'); + module.restore.conditions(); + settings.onComplete.call(element); + } + } + }, + + force: { + visible: function() { + var + style = $module.attr('style'), + userStyle = module.get.userStyle(), + displayType = module.get.displayType(), + overrideStyle = userStyle + 'display: ' + displayType + ' !important;', + currentDisplay = $module.css('display'), + emptyStyle = (style === undefined || style === '') + ; + if(currentDisplay !== displayType) { + module.verbose('Overriding default display to show element', displayType); + $module + .attr('style', overrideStyle) + ; + } + else if(emptyStyle) { + $module.removeAttr('style'); + } + }, + hidden: function() { + var + style = $module.attr('style'), + currentDisplay = $module.css('display'), + emptyStyle = (style === undefined || style === '') + ; + if(currentDisplay !== 'none' && !module.is.hidden()) { + module.verbose('Overriding default display to hide element'); + $module + .css('display', 'none') + ; + } + else if(emptyStyle) { + $module + .removeAttr('style') + ; + } + } + }, + + has: { + direction: function(animation) { + var + hasDirection = false + ; + animation = animation || settings.animation; + if(typeof animation === 'string') { + animation = animation.split(' '); + $.each(animation, function(index, word){ + if(word === className.inward || word === className.outward) { + hasDirection = true; + } + }); + } + return hasDirection; + }, + inlineDisplay: function() { + var + style = $module.attr('style') || '' + ; + return $.isArray(style.match(/display.*?;/, '')); + } + }, + + set: { + animating: function(animation) { + var + animationClass, + direction + ; + // remove previous callbacks + module.remove.completeCallback(); + + // determine exact animation + animation = animation || settings.animation; + animationClass = module.get.animationClass(animation); + + // save animation class in cache to restore class names + module.save.animation(animationClass); + + // override display if necessary so animation appears visibly + module.force.visible(); + + module.remove.hidden(); + module.remove.direction(); + + module.start.animation(animationClass); + + }, + duration: function(animationName, duration) { + duration = duration || settings.duration; + duration = (typeof duration == 'number') + ? duration + 'ms' + : duration + ; + if(duration || duration === 0) { + module.verbose('Setting animation duration', duration); + $module + .css({ + 'animation-duration': duration + }) + ; + } + }, + direction: function(direction) { + direction = direction || module.get.direction(); + if(direction == className.inward) { + module.set.inward(); + } + else { + module.set.outward(); + } + }, + looping: function() { + module.debug('Transition set to loop'); + $module + .addClass(className.looping) + ; + }, + hidden: function() { + $module + .addClass(className.transition) + .addClass(className.hidden) + ; + }, + inward: function() { + module.debug('Setting direction to inward'); + $module + .removeClass(className.outward) + .addClass(className.inward) + ; + }, + outward: function() { + module.debug('Setting direction to outward'); + $module + .removeClass(className.inward) + .addClass(className.outward) + ; + }, + visible: function() { + $module + .addClass(className.transition) + .addClass(className.visible) + ; + } + }, + + start: { + animation: function(animationClass) { + animationClass = animationClass || module.get.animationClass(); + module.debug('Starting tween', animationClass); + $module + .addClass(animationClass) + .one(animationEnd + '.complete' + eventNamespace, module.complete) + ; + if(settings.useFailSafe) { + module.add.failSafe(); + } + module.set.duration(settings.duration); + settings.onStart.call(element); + } + }, + + save: { + animation: function(animation) { + if(!module.cache) { + module.cache = {}; + } + module.cache.animation = animation; + }, + displayType: function(displayType) { + if(displayType !== 'none') { + $module.data(metadata.displayType, displayType); + } + }, + transitionExists: function(animation, exists) { + $.fn.transition.exists[animation] = exists; + module.verbose('Saving existence of transition', animation, exists); + } + }, + + restore: { + conditions: function() { + var + animation = module.get.currentAnimation() + ; + if(animation) { + $module + .removeClass(animation) + ; + module.verbose('Removing animation class', module.cache); + } + module.remove.duration(); + } + }, + + add: { + failSafe: function() { + var + duration = module.get.duration() + ; + module.timer = setTimeout(function() { + $module.triggerHandler(animationEnd); + }, duration + settings.failSafeDelay); + module.verbose('Adding fail safe timer', module.timer); + } + }, + + remove: { + animating: function() { + $module.removeClass(className.animating); + }, + animationCallbacks: function() { + module.remove.queueCallback(); + module.remove.completeCallback(); + }, + queueCallback: function() { + $module.off('.queue' + eventNamespace); + }, + completeCallback: function() { + $module.off('.complete' + eventNamespace); + }, + display: function() { + $module.css('display', ''); + }, + direction: function() { + $module + .removeClass(className.inward) + .removeClass(className.outward) + ; + }, + duration: function() { + $module + .css('animation-duration', '') + ; + }, + failSafe: function() { + module.verbose('Removing fail safe timer', module.timer); + if(module.timer) { + clearTimeout(module.timer); + } + }, + hidden: function() { + $module.removeClass(className.hidden); + }, + visible: function() { + $module.removeClass(className.visible); + }, + looping: function() { + module.debug('Transitions are no longer looping'); + if( module.is.looping() ) { + module.reset(); + $module + .removeClass(className.looping) + ; + } + }, + transition: function() { + $module + .removeClass(className.visible) + .removeClass(className.hidden) + ; + } + }, + get: { + settings: function(animation, duration, onComplete) { + // single settings object + if(typeof animation == 'object') { + return $.extend(true, {}, $.fn.transition.settings, animation); + } + // all arguments provided + else if(typeof onComplete == 'function') { + return $.extend({}, $.fn.transition.settings, { + animation : animation, + onComplete : onComplete, + duration : duration + }); + } + // only duration provided + else if(typeof duration == 'string' || typeof duration == 'number') { + return $.extend({}, $.fn.transition.settings, { + animation : animation, + duration : duration + }); + } + // duration is actually settings object + else if(typeof duration == 'object') { + return $.extend({}, $.fn.transition.settings, duration, { + animation : animation + }); + } + // duration is actually callback + else if(typeof duration == 'function') { + return $.extend({}, $.fn.transition.settings, { + animation : animation, + onComplete : duration + }); + } + // only animation provided + else { + return $.extend({}, $.fn.transition.settings, { + animation : animation + }); + } + }, + animationClass: function(animation) { + var + animationClass = animation || settings.animation, + directionClass = (module.can.transition() && !module.has.direction()) + ? module.get.direction() + ' ' + : '' + ; + return className.animating + ' ' + + className.transition + ' ' + + directionClass + + animationClass + ; + }, + currentAnimation: function() { + return (module.cache && module.cache.animation !== undefined) + ? module.cache.animation + : false + ; + }, + currentDirection: function() { + return module.is.inward() + ? className.inward + : className.outward + ; + }, + direction: function() { + return module.is.hidden() || !module.is.visible() + ? className.inward + : className.outward + ; + }, + animationDirection: function(animation) { + var + direction + ; + animation = animation || settings.animation; + if(typeof animation === 'string') { + animation = animation.split(' '); + // search animation name for out/in class + $.each(animation, function(index, word){ + if(word === className.inward) { + direction = className.inward; + } + else if(word === className.outward) { + direction = className.outward; + } + }); + } + // return found direction + if(direction) { + return direction; + } + return false; + }, + duration: function(duration) { + duration = duration || settings.duration; + if(duration === false) { + duration = $module.css('animation-duration') || 0; + } + return (typeof duration === 'string') + ? (duration.indexOf('ms') > -1) + ? parseFloat(duration) + : parseFloat(duration) * 1000 + : duration + ; + }, + displayType: function(shouldDetermine) { + shouldDetermine = (shouldDetermine !== undefined) + ? shouldDetermine + : true + ; + if(settings.displayType) { + return settings.displayType; + } + if(shouldDetermine && $module.data(metadata.displayType) === undefined) { + // create fake element to determine display state + module.can.transition(true); + } + return $module.data(metadata.displayType); + }, + userStyle: function(style) { + style = style || $module.attr('style') || ''; + return style.replace(/display.*?;/, ''); + }, + transitionExists: function(animation) { + return $.fn.transition.exists[animation]; + }, + animationStartEvent: function() { + var + element = document.createElement('div'), + animations = { + 'animation' :'animationstart', + 'OAnimation' :'oAnimationStart', + 'MozAnimation' :'mozAnimationStart', + 'WebkitAnimation' :'webkitAnimationStart' + }, + animation + ; + for(animation in animations){ + if( element.style[animation] !== undefined ){ + return animations[animation]; + } + } + return false; + }, + animationEndEvent: function() { + var + element = document.createElement('div'), + animations = { + 'animation' :'animationend', + 'OAnimation' :'oAnimationEnd', + 'MozAnimation' :'mozAnimationEnd', + 'WebkitAnimation' :'webkitAnimationEnd' + }, + animation + ; + for(animation in animations){ + if( element.style[animation] !== undefined ){ + return animations[animation]; + } + } + return false; + } + + }, + + can: { + transition: function(forced) { + var + animation = settings.animation, + transitionExists = module.get.transitionExists(animation), + displayType = module.get.displayType(false), + elementClass, + tagName, + $clone, + currentAnimation, + inAnimation, + directionExists + ; + if( transitionExists === undefined || forced) { + module.verbose('Determining whether animation exists'); + elementClass = $module.attr('class'); + tagName = $module.prop('tagName'); + + $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module); + currentAnimation = $clone + .addClass(animation) + .removeClass(className.inward) + .removeClass(className.outward) + .addClass(className.animating) + .addClass(className.transition) + .css('animationName') + ; + inAnimation = $clone + .addClass(className.inward) + .css('animationName') + ; + if(!displayType) { + displayType = $clone + .attr('class', elementClass) + .removeAttr('style') + .removeClass(className.hidden) + .removeClass(className.visible) + .show() + .css('display') + ; + module.verbose('Determining final display state', displayType); + module.save.displayType(displayType); + } + + $clone.remove(); + if(currentAnimation != inAnimation) { + module.debug('Direction exists for animation', animation); + directionExists = true; + } + else if(currentAnimation == 'none' || !currentAnimation) { + module.debug('No animation defined in css', animation); + return; + } + else { + module.debug('Static animation found', animation, displayType); + directionExists = false; + } + module.save.transitionExists(animation, directionExists); + } + return (transitionExists !== undefined) + ? transitionExists + : directionExists + ; + }, + animate: function() { + // can transition does not return a value if animation does not exist + return (module.can.transition() !== undefined); + } + }, + + is: { + animating: function() { + return $module.hasClass(className.animating); + }, + inward: function() { + return $module.hasClass(className.inward); + }, + outward: function() { + return $module.hasClass(className.outward); + }, + looping: function() { + return $module.hasClass(className.looping); + }, + occurring: function(animation) { + animation = animation || settings.animation; + animation = '.' + animation.replace(' ', '.'); + return ( $module.filter(animation).length > 0 ); + }, + visible: function() { + return $module.is(':visible'); + }, + hidden: function() { + return $module.css('visibility') === 'hidden'; + }, + supported: function() { + return(animationEnd !== false); + } + }, + + hide: function() { + module.verbose('Hiding element'); + if( module.is.animating() ) { + module.reset(); + } + element.blur(); // IE will trigger focus change if element is not blurred before hiding + module.remove.display(); + module.remove.visible(); + module.set.hidden(); + module.force.hidden(); + settings.onHide.call(element); + settings.onComplete.call(element); + // module.repaint(); + }, + + show: function(display) { + module.verbose('Showing element', display); + module.remove.hidden(); + module.set.visible(); + module.force.visible(); + settings.onShow.call(element); + settings.onComplete.call(element); + // module.repaint(); + }, + + toggle: function() { + if( module.is.visible() ) { + module.hide(); + } + else { + module.show(); + } + }, + + stop: function() { + module.debug('Stopping current animation'); + $module.triggerHandler(animationEnd); + }, + + stopAll: function() { + module.debug('Stopping all animation'); + module.remove.queueCallback(); + $module.triggerHandler(animationEnd); + }, + + clear: { + queue: function() { + module.debug('Clearing animation queue'); + module.remove.queueCallback(); + } + }, + + enable: function() { + module.verbose('Starting animation'); + $module.removeClass(className.disabled); + }, + + disable: function() { + module.debug('Stopping animation'); + $module.addClass(className.disabled); + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if($allModules.length > 1) { + title += ' ' + '(' + $allModules.length + ')'; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + // modified for transition to return invoke success + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return (found !== undefined) + ? found + : false + ; + } + }; + module.initialize(); + }) + ; + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +// Records if CSS transition is available +$.fn.transition.exists = {}; + +$.fn.transition.settings = { + + // module info + name : 'Transition', + + // hide all output from this component regardless of other settings + silent : false, + + // debug content outputted to console + debug : false, + + // verbose debug output + verbose : false, + + // performance data output + performance : true, + + // event namespace + namespace : 'transition', + + // delay between animations in group + interval : 0, + + // whether group animations should be reversed + reverse : 'auto', + + // animation callback event + onStart : function() {}, + onComplete : function() {}, + onShow : function() {}, + onHide : function() {}, + + // whether timeout should be used to ensure callback fires in cases animationend does not + useFailSafe : true, + + // delay in ms for fail safe + failSafeDelay : 100, + + // whether EXACT animation can occur twice in a row + allowRepeats : false, + + // Override final display type on visible + displayType : false, + + // animation duration + animation : 'fade', + duration : false, + + // new animations will occur after previous ones + queue : true, + + metadata : { + displayType: 'display' + }, + + className : { + animating : 'animating', + disabled : 'disabled', + hidden : 'hidden', + inward : 'in', + loading : 'loading', + looping : 'looping', + outward : 'out', + transition : 'transition', + visible : 'visible' + }, + + // possible errors + error: { + noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.', + repeated : 'That animation is already occurring, cancelling repeated animation', + method : 'The method you called is not defined', + support : 'This browser does not support CSS animations' + } + +}; + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - API + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +var + window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.api = $.fn.api = function(parameters) { + + var + // use window context if none specified + $allModules = $.isFunction(this) + ? $(window) + : $(this), + moduleSelector = $allModules.selector || '', + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + + returnedValue + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.api.settings, parameters) + : $.extend({}, $.fn.api.settings), + + // internal aliases + namespace = settings.namespace, + metadata = settings.metadata, + selector = settings.selector, + error = settings.error, + className = settings.className, + + // define namespaces for modules + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + // element that creates request + $module = $(this), + $form = $module.closest(selector.form), + + // context used for state + $context = (settings.stateContext) + ? $(settings.stateContext) + : $module, + + // request details + ajaxSettings, + requestSettings, + url, + data, + requestStartTime, + + // standard module + element = this, + context = $context[0], + instance = $module.data(moduleNamespace), + module + ; + + module = { + + initialize: function() { + if(!methodInvoked) { + module.bind.events(); + } + module.instantiate(); + }, + + instantiate: function() { + module.verbose('Storing instance of module', module); + instance = module; + $module + .data(moduleNamespace, instance) + ; + }, + + destroy: function() { + module.verbose('Destroying previous module for', element); + $module + .removeData(moduleNamespace) + .off(eventNamespace) + ; + }, + + bind: { + events: function() { + var + triggerEvent = module.get.event() + ; + if( triggerEvent ) { + module.verbose('Attaching API events to element', triggerEvent); + $module + .on(triggerEvent + eventNamespace, module.event.trigger) + ; + } + else if(settings.on == 'now') { + module.debug('Querying API endpoint immediately'); + module.query(); + } + } + }, + + decode: { + json: function(response) { + if(response !== undefined && typeof response == 'string') { + try { + response = JSON.parse(response); + } + catch(e) { + // isnt json string + } + } + return response; + } + }, + + read: { + cachedResponse: function(url) { + var + response + ; + if(window.Storage === undefined) { + module.error(error.noStorage); + return; + } + response = sessionStorage.getItem(url); + module.debug('Using cached response', url, response); + response = module.decode.json(response); + return response; + } + }, + write: { + cachedResponse: function(url, response) { + if(response && response === '') { + module.debug('Response empty, not caching', response); + return; + } + if(window.Storage === undefined) { + module.error(error.noStorage); + return; + } + if( $.isPlainObject(response) ) { + response = JSON.stringify(response); + } + sessionStorage.setItem(url, response); + module.verbose('Storing cached response for url', url, response); + } + }, + + query: function() { + + if(module.is.disabled()) { + module.debug('Element is disabled API request aborted'); + return; + } + + if(module.is.loading()) { + if(settings.interruptRequests) { + module.debug('Interrupting previous request'); + module.abort(); + } + else { + module.debug('Cancelling request, previous request is still pending'); + return; + } + } + + // pass element metadata to url (value, text) + if(settings.defaultData) { + $.extend(true, settings.urlData, module.get.defaultData()); + } + + // Add form content + if(settings.serializeForm) { + settings.data = module.add.formData(settings.data); + } + + // call beforesend and get any settings changes + requestSettings = module.get.settings(); + + // check if before send cancelled request + if(requestSettings === false) { + module.cancelled = true; + module.error(error.beforeSend); + return; + } + else { + module.cancelled = false; + } + + // get url + url = module.get.templatedURL(); + + if(!url && !module.is.mocked()) { + module.error(error.missingURL); + return; + } + + // replace variables + url = module.add.urlData( url ); + // missing url parameters + if( !url && !module.is.mocked()) { + return; + } + + requestSettings.url = settings.base + url; + + // look for jQuery ajax parameters in settings + ajaxSettings = $.extend(true, {}, settings, { + type : settings.method || settings.type, + data : data, + url : settings.base + url, + beforeSend : settings.beforeXHR, + success : function() {}, + failure : function() {}, + complete : function() {} + }); + + module.debug('Querying URL', ajaxSettings.url); + module.verbose('Using AJAX settings', ajaxSettings); + if(settings.cache === 'local' && module.read.cachedResponse(url)) { + module.debug('Response returned from local cache'); + module.request = module.create.request(); + module.request.resolveWith(context, [ module.read.cachedResponse(url) ]); + return; + } + + if( !settings.throttle ) { + module.debug('Sending request', data, ajaxSettings.method); + module.send.request(); + } + else { + if(!settings.throttleFirstRequest && !module.timer) { + module.debug('Sending request', data, ajaxSettings.method); + module.send.request(); + module.timer = setTimeout(function(){}, settings.throttle); + } + else { + module.debug('Throttling request', settings.throttle); + clearTimeout(module.timer); + module.timer = setTimeout(function() { + if(module.timer) { + delete module.timer; + } + module.debug('Sending throttled request', data, ajaxSettings.method); + module.send.request(); + }, settings.throttle); + } + } + + }, + + should: { + removeError: function() { + return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) ); + } + }, + + is: { + disabled: function() { + return ($module.filter(selector.disabled).length > 0); + }, + expectingJSON: function() { + return settings.dataType === 'json' || settings.dataType === 'jsonp'; + }, + form: function() { + return $module.is('form') || $context.is('form'); + }, + mocked: function() { + return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync); + }, + input: function() { + return $module.is('input'); + }, + loading: function() { + return (module.request) + ? (module.request.state() == 'pending') + : false + ; + }, + abortedRequest: function(xhr) { + if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) { + module.verbose('XHR request determined to be aborted'); + return true; + } + else { + module.verbose('XHR request was not aborted'); + return false; + } + }, + validResponse: function(response) { + if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) { + module.verbose('Response is not JSON, skipping validation', settings.successTest, response); + return true; + } + module.debug('Checking JSON returned success', settings.successTest, response); + if( settings.successTest(response) ) { + module.debug('Response passed success test', response); + return true; + } + else { + module.debug('Response failed success test', response); + return false; + } + } + }, + + was: { + cancelled: function() { + return (module.cancelled || false); + }, + succesful: function() { + return (module.request && module.request.state() == 'resolved'); + }, + failure: function() { + return (module.request && module.request.state() == 'rejected'); + }, + complete: function() { + return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') ); + } + }, + + add: { + urlData: function(url, urlData) { + var + requiredVariables, + optionalVariables + ; + if(url) { + requiredVariables = url.match(settings.regExp.required); + optionalVariables = url.match(settings.regExp.optional); + urlData = urlData || settings.urlData; + if(requiredVariables) { + module.debug('Looking for required URL variables', requiredVariables); + $.each(requiredVariables, function(index, templatedString) { + var + // allow legacy {$var} style + variable = (templatedString.indexOf('$') !== -1) + ? templatedString.substr(2, templatedString.length - 3) + : templatedString.substr(1, templatedString.length - 2), + value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) + ? urlData[variable] + : ($module.data(variable) !== undefined) + ? $module.data(variable) + : ($context.data(variable) !== undefined) + ? $context.data(variable) + : urlData[variable] + ; + // remove value + if(value === undefined) { + module.error(error.requiredParameter, variable, url); + url = false; + return false; + } + else { + module.verbose('Found required variable', variable, value); + value = (settings.encodeParameters) + ? module.get.urlEncodedValue(value) + : value + ; + url = url.replace(templatedString, value); + } + }); + } + if(optionalVariables) { + module.debug('Looking for optional URL variables', requiredVariables); + $.each(optionalVariables, function(index, templatedString) { + var + // allow legacy {/$var} style + variable = (templatedString.indexOf('$') !== -1) + ? templatedString.substr(3, templatedString.length - 4) + : templatedString.substr(2, templatedString.length - 3), + value = ($.isPlainObject(urlData) && urlData[variable] !== undefined) + ? urlData[variable] + : ($module.data(variable) !== undefined) + ? $module.data(variable) + : ($context.data(variable) !== undefined) + ? $context.data(variable) + : urlData[variable] + ; + // optional replacement + if(value !== undefined) { + module.verbose('Optional variable Found', variable, value); + url = url.replace(templatedString, value); + } + else { + module.verbose('Optional variable not found', variable); + // remove preceding slash if set + if(url.indexOf('/' + templatedString) !== -1) { + url = url.replace('/' + templatedString, ''); + } + else { + url = url.replace(templatedString, ''); + } + } + }); + } + } + return url; + }, + formData: function(data) { + var + canSerialize = ($.fn.serializeObject !== undefined), + formData = (canSerialize) + ? $form.serializeObject() + : $form.serialize(), + hasOtherData + ; + data = data || settings.data; + hasOtherData = $.isPlainObject(data); + + if(hasOtherData) { + if(canSerialize) { + module.debug('Extending existing data with form data', data, formData); + data = $.extend(true, {}, data, formData); + } + else { + module.error(error.missingSerialize); + module.debug('Cant extend data. Replacing data with form data', data, formData); + data = formData; + } + } + else { + module.debug('Adding form data', formData); + data = formData; + } + return data; + } + }, + + send: { + request: function() { + module.set.loading(); + module.request = module.create.request(); + if( module.is.mocked() ) { + module.mockedXHR = module.create.mockedXHR(); + } + else { + module.xhr = module.create.xhr(); + } + settings.onRequest.call(context, module.request, module.xhr); + } + }, + + event: { + trigger: function(event) { + module.query(); + if(event.type == 'submit' || event.type == 'click') { + event.preventDefault(); + } + }, + xhr: { + always: function() { + // nothing special + }, + done: function(response, textStatus, xhr) { + var + context = this, + elapsedTime = (new Date().getTime() - requestStartTime), + timeLeft = (settings.loadingDuration - elapsedTime), + translatedResponse = ( $.isFunction(settings.onResponse) ) + ? module.is.expectingJSON() + ? settings.onResponse.call(context, $.extend(true, {}, response)) + : settings.onResponse.call(context, response) + : false + ; + timeLeft = (timeLeft > 0) + ? timeLeft + : 0 + ; + if(translatedResponse) { + module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response); + response = translatedResponse; + } + if(timeLeft > 0) { + module.debug('Response completed early delaying state change by', timeLeft); + } + setTimeout(function() { + if( module.is.validResponse(response) ) { + module.request.resolveWith(context, [response, xhr]); + } + else { + module.request.rejectWith(context, [xhr, 'invalid']); + } + }, timeLeft); + }, + fail: function(xhr, status, httpMessage) { + var + context = this, + elapsedTime = (new Date().getTime() - requestStartTime), + timeLeft = (settings.loadingDuration - elapsedTime) + ; + timeLeft = (timeLeft > 0) + ? timeLeft + : 0 + ; + if(timeLeft > 0) { + module.debug('Response completed early delaying state change by', timeLeft); + } + setTimeout(function() { + if( module.is.abortedRequest(xhr) ) { + module.request.rejectWith(context, [xhr, 'aborted', httpMessage]); + } + else { + module.request.rejectWith(context, [xhr, 'error', status, httpMessage]); + } + }, timeLeft); + } + }, + request: { + done: function(response, xhr) { + module.debug('Successful API Response', response); + if(settings.cache === 'local' && url) { + module.write.cachedResponse(url, response); + module.debug('Saving server response locally', module.cache); + } + settings.onSuccess.call(context, response, $module, xhr); + }, + complete: function(firstParameter, secondParameter) { + var + xhr, + response + ; + // have to guess callback parameters based on request success + if( module.was.succesful() ) { + response = firstParameter; + xhr = secondParameter; + } + else { + xhr = firstParameter; + response = module.get.responseFromXHR(xhr); + } + module.remove.loading(); + settings.onComplete.call(context, response, $module, xhr); + }, + fail: function(xhr, status, httpMessage) { + var + // pull response from xhr if available + response = module.get.responseFromXHR(xhr), + errorMessage = module.get.errorFromRequest(response, status, httpMessage) + ; + if(status == 'aborted') { + module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage); + settings.onAbort.call(context, status, $module, xhr); + return true; + } + else if(status == 'invalid') { + module.debug('JSON did not pass success test. A server-side error has most likely occurred', response); + } + else if(status == 'error') { + if(xhr !== undefined) { + module.debug('XHR produced a server error', status, httpMessage); + // make sure we have an error to display to console + if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') { + module.error(error.statusMessage + httpMessage, ajaxSettings.url); + } + settings.onError.call(context, errorMessage, $module, xhr); + } + } + + if(settings.errorDuration && status !== 'aborted') { + module.debug('Adding error state'); + module.set.error(); + if( module.should.removeError() ) { + setTimeout(module.remove.error, settings.errorDuration); + } + } + module.debug('API Request failed', errorMessage, xhr); + settings.onFailure.call(context, response, $module, xhr); + } + } + }, + + create: { + + request: function() { + // api request promise + return $.Deferred() + .always(module.event.request.complete) + .done(module.event.request.done) + .fail(module.event.request.fail) + ; + }, + + mockedXHR: function () { + var + // xhr does not simulate these properties of xhr but must return them + textStatus = false, + status = false, + httpMessage = false, + responder = settings.mockResponse || settings.response, + asyncResponder = settings.mockResponseAsync || settings.responseAsync, + asyncCallback, + response, + mockedXHR + ; + + mockedXHR = $.Deferred() + .always(module.event.xhr.complete) + .done(module.event.xhr.done) + .fail(module.event.xhr.fail) + ; + + if(responder) { + if( $.isFunction(responder) ) { + module.debug('Using specified synchronous callback', responder); + response = responder.call(context, requestSettings); + } + else { + module.debug('Using settings specified response', responder); + response = responder; + } + // simulating response + mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); + } + else if( $.isFunction(asyncResponder) ) { + asyncCallback = function(response) { + module.debug('Async callback returned response', response); + + if(response) { + mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]); + } + else { + mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]); + } + }; + module.debug('Using specified async response callback', asyncResponder); + asyncResponder.call(context, requestSettings, asyncCallback); + } + return mockedXHR; + }, + + xhr: function() { + var + xhr + ; + // ajax request promise + xhr = $.ajax(ajaxSettings) + .always(module.event.xhr.always) + .done(module.event.xhr.done) + .fail(module.event.xhr.fail) + ; + module.verbose('Created server request', xhr, ajaxSettings); + return xhr; + } + }, + + set: { + error: function() { + module.verbose('Adding error state to element', $context); + $context.addClass(className.error); + }, + loading: function() { + module.verbose('Adding loading state to element', $context); + $context.addClass(className.loading); + requestStartTime = new Date().getTime(); + } + }, + + remove: { + error: function() { + module.verbose('Removing error state from element', $context); + $context.removeClass(className.error); + }, + loading: function() { + module.verbose('Removing loading state from element', $context); + $context.removeClass(className.loading); + } + }, + + get: { + responseFromXHR: function(xhr) { + return $.isPlainObject(xhr) + ? (module.is.expectingJSON()) + ? module.decode.json(xhr.responseText) + : xhr.responseText + : false + ; + }, + errorFromRequest: function(response, status, httpMessage) { + return ($.isPlainObject(response) && response.error !== undefined) + ? response.error // use json error message + : (settings.error[status] !== undefined) // use server error message + ? settings.error[status] + : httpMessage + ; + }, + request: function() { + return module.request || false; + }, + xhr: function() { + return module.xhr || false; + }, + settings: function() { + var + runSettings + ; + runSettings = settings.beforeSend.call(context, settings); + if(runSettings) { + if(runSettings.success !== undefined) { + module.debug('Legacy success callback detected', runSettings); + module.error(error.legacyParameters, runSettings.success); + runSettings.onSuccess = runSettings.success; + } + if(runSettings.failure !== undefined) { + module.debug('Legacy failure callback detected', runSettings); + module.error(error.legacyParameters, runSettings.failure); + runSettings.onFailure = runSettings.failure; + } + if(runSettings.complete !== undefined) { + module.debug('Legacy complete callback detected', runSettings); + module.error(error.legacyParameters, runSettings.complete); + runSettings.onComplete = runSettings.complete; + } + } + if(runSettings === undefined) { + module.error(error.noReturnedValue); + } + if(runSettings === false) { + return runSettings; + } + return (runSettings !== undefined) + ? $.extend(true, {}, runSettings) + : $.extend(true, {}, settings) + ; + }, + urlEncodedValue: function(value) { + var + decodedValue = window.decodeURIComponent(value), + encodedValue = window.encodeURIComponent(value), + alreadyEncoded = (decodedValue !== value) + ; + if(alreadyEncoded) { + module.debug('URL value is already encoded, avoiding double encoding', value); + return value; + } + module.verbose('Encoding value using encodeURIComponent', value, encodedValue); + return encodedValue; + }, + defaultData: function() { + var + data = {} + ; + if( !$.isWindow(element) ) { + if( module.is.input() ) { + data.value = $module.val(); + } + else if( module.is.form() ) { + + } + else { + data.text = $module.text(); + } + } + return data; + }, + event: function() { + if( $.isWindow(element) || settings.on == 'now' ) { + module.debug('API called without element, no events attached'); + return false; + } + else if(settings.on == 'auto') { + if( $module.is('input') ) { + return (element.oninput !== undefined) + ? 'input' + : (element.onpropertychange !== undefined) + ? 'propertychange' + : 'keyup' + ; + } + else if( $module.is('form') ) { + return 'submit'; + } + else { + return 'click'; + } + } + else { + return settings.on; + } + }, + templatedURL: function(action) { + action = action || $module.data(metadata.action) || settings.action || false; + url = $module.data(metadata.url) || settings.url || false; + if(url) { + module.debug('Using specified url', url); + return url; + } + if(action) { + module.debug('Looking up url for action', action, settings.api); + if(settings.api[action] === undefined && !module.is.mocked()) { + module.error(error.missingAction, settings.action, settings.api); + return; + } + url = settings.api[action]; + } + else if( module.is.form() ) { + url = $module.attr('action') || $context.attr('action') || false; + module.debug('No url or action specified, defaulting to form action', url); + } + return url; + } + }, + + abort: function() { + var + xhr = module.get.xhr() + ; + if( xhr && xhr.state() !== 'resolved') { + module.debug('Cancelling API request'); + xhr.abort(); + } + }, + + // reset state + reset: function() { + module.remove.error(); + module.remove.loading(); + }, + + setting: function(name, value) { + module.debug('Changing setting', name, value); + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + if($.isPlainObject(settings[name])) { + $.extend(true, settings[name], value); + } + else { + settings[name] = value; + } + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + //'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.api.settings = { + + name : 'API', + namespace : 'api', + + debug : false, + verbose : false, + performance : true, + + // object containing all templates endpoints + api : {}, + + // whether to cache responses + cache : true, + + // whether new requests should abort previous requests + interruptRequests : true, + + // event binding + on : 'auto', + + // context for applying state classes + stateContext : false, + + // duration for loading state + loadingDuration : 0, + + // whether to hide errors after a period of time + hideError : 'auto', + + // duration for error state + errorDuration : 2000, + + // whether parameters should be encoded with encodeURIComponent + encodeParameters : true, + + // API action to use + action : false, + + // templated URL to use + url : false, + + // base URL to apply to all endpoints + base : '', + + // data that will + urlData : {}, + + // whether to add default data to url data + defaultData : true, + + // whether to serialize closest form + serializeForm : false, + + // how long to wait before request should occur + throttle : 0, + + // whether to throttle first request or only repeated + throttleFirstRequest : true, + + // standard ajax settings + method : 'get', + data : {}, + dataType : 'json', + + // mock response + mockResponse : false, + mockResponseAsync : false, + + // aliases for mock + response : false, + responseAsync : false, + + // callbacks before request + beforeSend : function(settings) { return settings; }, + beforeXHR : function(xhr) {}, + onRequest : function(promise, xhr) {}, + + // after request + onResponse : false, // function(response) { }, + + // response was successful, if JSON passed validation + onSuccess : function(response, $module) {}, + + // request finished without aborting + onComplete : function(response, $module) {}, + + // failed JSON success test + onFailure : function(response, $module) {}, + + // server error + onError : function(errorMessage, $module) {}, + + // request aborted + onAbort : function(errorMessage, $module) {}, + + successTest : false, + + // errors + error : { + beforeSend : 'The before send function has aborted the request', + error : 'There was an error with your request', + exitConditions : 'API Request Aborted. Exit conditions met', + JSONParse : 'JSON could not be parsed during error handling', + legacyParameters : 'You are using legacy API success callback names', + method : 'The method you called is not defined', + missingAction : 'API action used but no url was defined', + missingSerialize : 'jquery-serialize-object is required to add form data to an existing data object', + missingURL : 'No URL specified for api event', + noReturnedValue : 'The beforeSend callback must return a settings object, beforeSend ignored.', + noStorage : 'Caching responses locally requires session storage', + parseError : 'There was an error parsing your request', + requiredParameter : 'Missing a required URL parameter: ', + statusMessage : 'Server gave an error: ', + timeout : 'Your request timed out' + }, + + regExp : { + required : /\{\$*[A-z0-9]+\}/g, + optional : /\{\/\$*[A-z0-9]+\}/g, + }, + + className: { + loading : 'loading', + error : 'error' + }, + + selector: { + disabled : '.disabled', + form : 'form' + }, + + metadata: { + action : 'action', + url : 'url' + } +}; + + + +})( jQuery, window, document ); + +/*! + * # Semantic UI 2.4.1 - Visibility + * http://github.com/semantic-org/semantic-ui/ + * + * + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ + +;(function ($, window, document, undefined) { + +'use strict'; + +window = (typeof window != 'undefined' && window.Math == Math) + ? window + : (typeof self != 'undefined' && self.Math == Math) + ? self + : Function('return this')() +; + +$.fn.visibility = function(parameters) { + var + $allModules = $(this), + moduleSelector = $allModules.selector || '', + + time = new Date().getTime(), + performance = [], + + query = arguments[0], + methodInvoked = (typeof query == 'string'), + queryArguments = [].slice.call(arguments, 1), + returnedValue, + + moduleCount = $allModules.length, + loadedCount = 0 + ; + + $allModules + .each(function() { + var + settings = ( $.isPlainObject(parameters) ) + ? $.extend(true, {}, $.fn.visibility.settings, parameters) + : $.extend({}, $.fn.visibility.settings), + + className = settings.className, + namespace = settings.namespace, + error = settings.error, + metadata = settings.metadata, + + eventNamespace = '.' + namespace, + moduleNamespace = 'module-' + namespace, + + $window = $(window), + + $module = $(this), + $context = $(settings.context), + + $placeholder, + + selector = $module.selector || '', + instance = $module.data(moduleNamespace), + + requestAnimationFrame = window.requestAnimationFrame + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame + || window.msRequestAnimationFrame + || function(callback) { setTimeout(callback, 0); }, + + element = this, + disabled = false, + + contextObserver, + observer, + module + ; + + module = { + + initialize: function() { + module.debug('Initializing', settings); + + module.setup.cache(); + + if( module.should.trackChanges() ) { + + if(settings.type == 'image') { + module.setup.image(); + } + if(settings.type == 'fixed') { + module.setup.fixed(); + } + + if(settings.observeChanges) { + module.observeChanges(); + } + module.bind.events(); + } + + module.save.position(); + if( !module.is.visible() ) { + module.error(error.visible, $module); + } + + if(settings.initialCheck) { + module.checkVisibility(); + } + module.instantiate(); + }, + + instantiate: function() { + module.debug('Storing instance', module); + $module + .data(moduleNamespace, module) + ; + instance = module; + }, + + destroy: function() { + module.verbose('Destroying previous module'); + if(observer) { + observer.disconnect(); + } + if(contextObserver) { + contextObserver.disconnect(); + } + $window + .off('load' + eventNamespace, module.event.load) + .off('resize' + eventNamespace, module.event.resize) + ; + $context + .off('scroll' + eventNamespace, module.event.scroll) + .off('scrollchange' + eventNamespace, module.event.scrollchange) + ; + if(settings.type == 'fixed') { + module.resetFixed(); + module.remove.placeholder(); + } + $module + .off(eventNamespace) + .removeData(moduleNamespace) + ; + }, + + observeChanges: function() { + if('MutationObserver' in window) { + contextObserver = new MutationObserver(module.event.contextChanged); + observer = new MutationObserver(module.event.changed); + contextObserver.observe(document, { + childList : true, + subtree : true + }); + observer.observe(element, { + childList : true, + subtree : true + }); + module.debug('Setting up mutation observer', observer); + } + }, + + bind: { + events: function() { + module.verbose('Binding visibility events to scroll and resize'); + if(settings.refreshOnLoad) { + $window + .on('load' + eventNamespace, module.event.load) + ; + } + $window + .on('resize' + eventNamespace, module.event.resize) + ; + // pub/sub pattern + $context + .off('scroll' + eventNamespace) + .on('scroll' + eventNamespace, module.event.scroll) + .on('scrollchange' + eventNamespace, module.event.scrollchange) + ; + } + }, + + event: { + changed: function(mutations) { + module.verbose('DOM tree modified, updating visibility calculations'); + module.timer = setTimeout(function() { + module.verbose('DOM tree modified, updating sticky menu'); + module.refresh(); + }, 100); + }, + contextChanged: function(mutations) { + [].forEach.call(mutations, function(mutation) { + if(mutation.removedNodes) { + [].forEach.call(mutation.removedNodes, function(node) { + if(node == element || $(node).find(element).length > 0) { + module.debug('Element removed from DOM, tearing down events'); + module.destroy(); + } + }); + } + }); + }, + resize: function() { + module.debug('Window resized'); + if(settings.refreshOnResize) { + requestAnimationFrame(module.refresh); + } + }, + load: function() { + module.debug('Page finished loading'); + requestAnimationFrame(module.refresh); + }, + // publishes scrollchange event on one scroll + scroll: function() { + if(settings.throttle) { + clearTimeout(module.timer); + module.timer = setTimeout(function() { + $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]); + }, settings.throttle); + } + else { + requestAnimationFrame(function() { + $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]); + }); + } + }, + // subscribes to scrollchange + scrollchange: function(event, scrollPosition) { + module.checkVisibility(scrollPosition); + }, + }, + + precache: function(images, callback) { + if (!(images instanceof Array)) { + images = [images]; + } + var + imagesLength = images.length, + loadedCounter = 0, + cache = [], + cacheImage = document.createElement('img'), + handleLoad = function() { + loadedCounter++; + if (loadedCounter >= images.length) { + if ($.isFunction(callback)) { + callback(); + } + } + } + ; + while (imagesLength--) { + cacheImage = document.createElement('img'); + cacheImage.onload = handleLoad; + cacheImage.onerror = handleLoad; + cacheImage.src = images[imagesLength]; + cache.push(cacheImage); + } + }, + + enableCallbacks: function() { + module.debug('Allowing callbacks to occur'); + disabled = false; + }, + + disableCallbacks: function() { + module.debug('Disabling all callbacks temporarily'); + disabled = true; + }, + + should: { + trackChanges: function() { + if(methodInvoked) { + module.debug('One time query, no need to bind events'); + return false; + } + module.debug('Callbacks being attached'); + return true; + } + }, + + setup: { + cache: function() { + module.cache = { + occurred : {}, + screen : {}, + element : {}, + }; + }, + image: function() { + var + src = $module.data(metadata.src) + ; + if(src) { + module.verbose('Lazy loading image', src); + settings.once = true; + settings.observeChanges = false; + + // show when top visible + settings.onOnScreen = function() { + module.debug('Image on screen', element); + module.precache(src, function() { + module.set.image(src, function() { + loadedCount++; + if(loadedCount == moduleCount) { + settings.onAllLoaded.call(this); + } + settings.onLoad.call(this); + }); + }); + }; + } + }, + fixed: function() { + module.debug('Setting up fixed'); + settings.once = false; + settings.observeChanges = false; + settings.initialCheck = true; + settings.refreshOnLoad = true; + if(!parameters.transition) { + settings.transition = false; + } + module.create.placeholder(); + module.debug('Added placeholder', $placeholder); + settings.onTopPassed = function() { + module.debug('Element passed, adding fixed position', $module); + module.show.placeholder(); + module.set.fixed(); + if(settings.transition) { + if($.fn.transition !== undefined) { + $module.transition(settings.transition, settings.duration); + } + } + }; + settings.onTopPassedReverse = function() { + module.debug('Element returned to position, removing fixed', $module); + module.hide.placeholder(); + module.remove.fixed(); + }; + } + }, + + create: { + placeholder: function() { + module.verbose('Creating fixed position placeholder'); + $placeholder = $module + .clone(false) + .css('display', 'none') + .addClass(className.placeholder) + .insertAfter($module) + ; + } + }, + + show: { + placeholder: function() { + module.verbose('Showing placeholder'); + $placeholder + .css('display', 'block') + .css('visibility', 'hidden') + ; + } + }, + hide: { + placeholder: function() { + module.verbose('Hiding placeholder'); + $placeholder + .css('display', 'none') + .css('visibility', '') + ; + } + }, + + set: { + fixed: function() { + module.verbose('Setting element to fixed position'); + $module + .addClass(className.fixed) + .css({ + position : 'fixed', + top : settings.offset + 'px', + left : 'auto', + zIndex : settings.zIndex + }) + ; + settings.onFixed.call(element); + }, + image: function(src, callback) { + $module + .attr('src', src) + ; + if(settings.transition) { + if( $.fn.transition !== undefined) { + if($module.hasClass(className.visible)) { + module.debug('Transition already occurred on this image, skipping animation'); + return; + } + $module.transition(settings.transition, settings.duration, callback); + } + else { + $module.fadeIn(settings.duration, callback); + } + } + else { + $module.show(); + } + } + }, + + is: { + onScreen: function() { + var + calculations = module.get.elementCalculations() + ; + return calculations.onScreen; + }, + offScreen: function() { + var + calculations = module.get.elementCalculations() + ; + return calculations.offScreen; + }, + visible: function() { + if(module.cache && module.cache.element) { + return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0); + } + return false; + }, + verticallyScrollableContext: function() { + var + overflowY = ($context.get(0) !== window) + ? $context.css('overflow-y') + : false + ; + return (overflowY == 'auto' || overflowY == 'scroll'); + }, + horizontallyScrollableContext: function() { + var + overflowX = ($context.get(0) !== window) + ? $context.css('overflow-x') + : false + ; + return (overflowX == 'auto' || overflowX == 'scroll'); + } + }, + + refresh: function() { + module.debug('Refreshing constants (width/height)'); + if(settings.type == 'fixed') { + module.resetFixed(); + } + module.reset(); + module.save.position(); + if(settings.checkOnRefresh) { + module.checkVisibility(); + } + settings.onRefresh.call(element); + }, + + resetFixed: function () { + module.remove.fixed(); + module.remove.occurred(); + }, + + reset: function() { + module.verbose('Resetting all cached values'); + if( $.isPlainObject(module.cache) ) { + module.cache.screen = {}; + module.cache.element = {}; + } + }, + + checkVisibility: function(scroll) { + module.verbose('Checking visibility of element', module.cache.element); + + if( !disabled && module.is.visible() ) { + + // save scroll position + module.save.scroll(scroll); + + // update calculations derived from scroll + module.save.calculations(); + + // percentage + module.passed(); + + // reverse (must be first) + module.passingReverse(); + module.topVisibleReverse(); + module.bottomVisibleReverse(); + module.topPassedReverse(); + module.bottomPassedReverse(); + + // one time + module.onScreen(); + module.offScreen(); + module.passing(); + module.topVisible(); + module.bottomVisible(); + module.topPassed(); + module.bottomPassed(); + + // on update callback + if(settings.onUpdate) { + settings.onUpdate.call(element, module.get.elementCalculations()); + } + } + }, + + passed: function(amount, newCallback) { + var + calculations = module.get.elementCalculations(), + amountInPixels + ; + // assign callback + if(amount && newCallback) { + settings.onPassed[amount] = newCallback; + } + else if(amount !== undefined) { + return (module.get.pixelsPassed(amount) > calculations.pixelsPassed); + } + else if(calculations.passing) { + $.each(settings.onPassed, function(amount, callback) { + if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) { + module.execute(callback, amount); + } + else if(!settings.once) { + module.remove.occurred(callback); + } + }); + } + }, + + onScreen: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onOnScreen, + callbackName = 'onScreen' + ; + if(newCallback) { + module.debug('Adding callback for onScreen', newCallback); + settings.onOnScreen = newCallback; + } + if(calculations.onScreen) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return calculations.onOnScreen; + } + }, + + offScreen: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onOffScreen, + callbackName = 'offScreen' + ; + if(newCallback) { + module.debug('Adding callback for offScreen', newCallback); + settings.onOffScreen = newCallback; + } + if(calculations.offScreen) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return calculations.onOffScreen; + } + }, + + passing: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onPassing, + callbackName = 'passing' + ; + if(newCallback) { + module.debug('Adding callback for passing', newCallback); + settings.onPassing = newCallback; + } + if(calculations.passing) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return calculations.passing; + } + }, + + + topVisible: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopVisible, + callbackName = 'topVisible' + ; + if(newCallback) { + module.debug('Adding callback for top visible', newCallback); + settings.onTopVisible = newCallback; + } + if(calculations.topVisible) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.topVisible; + } + }, + + bottomVisible: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomVisible, + callbackName = 'bottomVisible' + ; + if(newCallback) { + module.debug('Adding callback for bottom visible', newCallback); + settings.onBottomVisible = newCallback; + } + if(calculations.bottomVisible) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.bottomVisible; + } + }, + + topPassed: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopPassed, + callbackName = 'topPassed' + ; + if(newCallback) { + module.debug('Adding callback for top passed', newCallback); + settings.onTopPassed = newCallback; + } + if(calculations.topPassed) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.topPassed; + } + }, + + bottomPassed: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomPassed, + callbackName = 'bottomPassed' + ; + if(newCallback) { + module.debug('Adding callback for bottom passed', newCallback); + settings.onBottomPassed = newCallback; + } + if(calculations.bottomPassed) { + module.execute(callback, callbackName); + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return calculations.bottomPassed; + } + }, + + passingReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onPassingReverse, + callbackName = 'passingReverse' + ; + if(newCallback) { + module.debug('Adding callback for passing reverse', newCallback); + settings.onPassingReverse = newCallback; + } + if(!calculations.passing) { + if(module.get.occurred('passing')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback !== undefined) { + return !calculations.passing; + } + }, + + + topVisibleReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopVisibleReverse, + callbackName = 'topVisibleReverse' + ; + if(newCallback) { + module.debug('Adding callback for top visible reverse', newCallback); + settings.onTopVisibleReverse = newCallback; + } + if(!calculations.topVisible) { + if(module.get.occurred('topVisible')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.topVisible; + } + }, + + bottomVisibleReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomVisibleReverse, + callbackName = 'bottomVisibleReverse' + ; + if(newCallback) { + module.debug('Adding callback for bottom visible reverse', newCallback); + settings.onBottomVisibleReverse = newCallback; + } + if(!calculations.bottomVisible) { + if(module.get.occurred('bottomVisible')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.bottomVisible; + } + }, + + topPassedReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onTopPassedReverse, + callbackName = 'topPassedReverse' + ; + if(newCallback) { + module.debug('Adding callback for top passed reverse', newCallback); + settings.onTopPassedReverse = newCallback; + } + if(!calculations.topPassed) { + if(module.get.occurred('topPassed')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.onTopPassed; + } + }, + + bottomPassedReverse: function(newCallback) { + var + calculations = module.get.elementCalculations(), + callback = newCallback || settings.onBottomPassedReverse, + callbackName = 'bottomPassedReverse' + ; + if(newCallback) { + module.debug('Adding callback for bottom passed reverse', newCallback); + settings.onBottomPassedReverse = newCallback; + } + if(!calculations.bottomPassed) { + if(module.get.occurred('bottomPassed')) { + module.execute(callback, callbackName); + } + } + else if(!settings.once) { + module.remove.occurred(callbackName); + } + if(newCallback === undefined) { + return !calculations.bottomPassed; + } + }, + + execute: function(callback, callbackName) { + var + calculations = module.get.elementCalculations(), + screen = module.get.screenCalculations() + ; + callback = callback || false; + if(callback) { + if(settings.continuous) { + module.debug('Callback being called continuously', callbackName, calculations); + callback.call(element, calculations, screen); + } + else if(!module.get.occurred(callbackName)) { + module.debug('Conditions met', callbackName, calculations); + callback.call(element, calculations, screen); + } + } + module.save.occurred(callbackName); + }, + + remove: { + fixed: function() { + module.debug('Removing fixed position'); + $module + .removeClass(className.fixed) + .css({ + position : '', + top : '', + left : '', + zIndex : '' + }) + ; + settings.onUnfixed.call(element); + }, + placeholder: function() { + module.debug('Removing placeholder content'); + if($placeholder) { + $placeholder.remove(); + } + }, + occurred: function(callback) { + if(callback) { + var + occurred = module.cache.occurred + ; + if(occurred[callback] !== undefined && occurred[callback] === true) { + module.debug('Callback can now be called again', callback); + module.cache.occurred[callback] = false; + } + } + else { + module.cache.occurred = {}; + } + } + }, + + save: { + calculations: function() { + module.verbose('Saving all calculations necessary to determine positioning'); + module.save.direction(); + module.save.screenCalculations(); + module.save.elementCalculations(); + }, + occurred: function(callback) { + if(callback) { + if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) { + module.verbose('Saving callback occurred', callback); + module.cache.occurred[callback] = true; + } + } + }, + scroll: function(scrollPosition) { + scrollPosition = scrollPosition + settings.offset || $context.scrollTop() + settings.offset; + module.cache.scroll = scrollPosition; + }, + direction: function() { + var + scroll = module.get.scroll(), + lastScroll = module.get.lastScroll(), + direction + ; + if(scroll > lastScroll && lastScroll) { + direction = 'down'; + } + else if(scroll < lastScroll && lastScroll) { + direction = 'up'; + } + else { + direction = 'static'; + } + module.cache.direction = direction; + return module.cache.direction; + }, + elementPosition: function() { + var + element = module.cache.element, + screen = module.get.screenSize() + ; + module.verbose('Saving element position'); + // (quicker than $.extend) + element.fits = (element.height < screen.height); + element.offset = $module.offset(); + element.width = $module.outerWidth(); + element.height = $module.outerHeight(); + // compensate for scroll in context + if(module.is.verticallyScrollableContext()) { + element.offset.top += $context.scrollTop() - $context.offset().top; + } + if(module.is.horizontallyScrollableContext()) { + element.offset.left += $context.scrollLeft - $context.offset().left; + } + // store + module.cache.element = element; + return element; + }, + elementCalculations: function() { + var + screen = module.get.screenCalculations(), + element = module.get.elementPosition() + ; + // offset + if(settings.includeMargin) { + element.margin = {}; + element.margin.top = parseInt($module.css('margin-top'), 10); + element.margin.bottom = parseInt($module.css('margin-bottom'), 10); + element.top = element.offset.top - element.margin.top; + element.bottom = element.offset.top + element.height + element.margin.bottom; + } + else { + element.top = element.offset.top; + element.bottom = element.offset.top + element.height; + } + + // visibility + element.topPassed = (screen.top >= element.top); + element.bottomPassed = (screen.top >= element.bottom); + element.topVisible = (screen.bottom >= element.top) && !element.topPassed; + element.bottomVisible = (screen.bottom >= element.bottom) && !element.bottomPassed; + element.pixelsPassed = 0; + element.percentagePassed = 0; + + // meta calculations + element.onScreen = ((element.topVisible || element.passing) && !element.bottomPassed); + element.passing = (element.topPassed && !element.bottomPassed); + element.offScreen = (!element.onScreen); + + // passing calculations + if(element.passing) { + element.pixelsPassed = (screen.top - element.top); + element.percentagePassed = (screen.top - element.top) / element.height; + } + module.cache.element = element; + module.verbose('Updated element calculations', element); + return element; + }, + screenCalculations: function() { + var + scroll = module.get.scroll() + ; + module.save.direction(); + module.cache.screen.top = scroll; + module.cache.screen.bottom = scroll + module.cache.screen.height; + return module.cache.screen; + }, + screenSize: function() { + module.verbose('Saving window position'); + module.cache.screen = { + height: $context.height() + }; + }, + position: function() { + module.save.screenSize(); + module.save.elementPosition(); + } + }, + + get: { + pixelsPassed: function(amount) { + var + element = module.get.elementCalculations() + ; + if(amount.search('%') > -1) { + return ( element.height * (parseInt(amount, 10) / 100) ); + } + return parseInt(amount, 10); + }, + occurred: function(callback) { + return (module.cache.occurred !== undefined) + ? module.cache.occurred[callback] || false + : false + ; + }, + direction: function() { + if(module.cache.direction === undefined) { + module.save.direction(); + } + return module.cache.direction; + }, + elementPosition: function() { + if(module.cache.element === undefined) { + module.save.elementPosition(); + } + return module.cache.element; + }, + elementCalculations: function() { + if(module.cache.element === undefined) { + module.save.elementCalculations(); + } + return module.cache.element; + }, + screenCalculations: function() { + if(module.cache.screen === undefined) { + module.save.screenCalculations(); + } + return module.cache.screen; + }, + screenSize: function() { + if(module.cache.screen === undefined) { + module.save.screenSize(); + } + return module.cache.screen; + }, + scroll: function() { + if(module.cache.scroll === undefined) { + module.save.scroll(); + } + return module.cache.scroll; + }, + lastScroll: function() { + if(module.cache.screen === undefined) { + module.debug('First scroll event, no last scroll could be found'); + return false; + } + return module.cache.screen.top; + } + }, + + setting: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, settings, name); + } + else if(value !== undefined) { + settings[name] = value; + } + else { + return settings[name]; + } + }, + internal: function(name, value) { + if( $.isPlainObject(name) ) { + $.extend(true, module, name); + } + else if(value !== undefined) { + module[name] = value; + } + else { + return module[name]; + } + }, + debug: function() { + if(!settings.silent && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.debug.apply(console, arguments); + } + } + }, + verbose: function() { + if(!settings.silent && settings.verbose && settings.debug) { + if(settings.performance) { + module.performance.log(arguments); + } + else { + module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':'); + module.verbose.apply(console, arguments); + } + } + }, + error: function() { + if(!settings.silent) { + module.error = Function.prototype.bind.call(console.error, console, settings.name + ':'); + module.error.apply(console, arguments); + } + }, + performance: { + log: function(message) { + var + currentTime, + executionTime, + previousTime + ; + if(settings.performance) { + currentTime = new Date().getTime(); + previousTime = time || currentTime; + executionTime = currentTime - previousTime; + time = currentTime; + performance.push({ + 'Name' : message[0], + 'Arguments' : [].slice.call(message, 1) || '', + 'Element' : element, + 'Execution Time' : executionTime + }); + } + clearTimeout(module.performance.timer); + module.performance.timer = setTimeout(module.performance.display, 500); + }, + display: function() { + var + title = settings.name + ':', + totalTime = 0 + ; + time = false; + clearTimeout(module.performance.timer); + $.each(performance, function(index, data) { + totalTime += data['Execution Time']; + }); + title += ' ' + totalTime + 'ms'; + if(moduleSelector) { + title += ' \'' + moduleSelector + '\''; + } + if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) { + console.groupCollapsed(title); + if(console.table) { + console.table(performance); + } + else { + $.each(performance, function(index, data) { + console.log(data['Name'] + ': ' + data['Execution Time']+'ms'); + }); + } + console.groupEnd(); + } + performance = []; + } + }, + invoke: function(query, passedArguments, context) { + var + object = instance, + maxDepth, + found, + response + ; + passedArguments = passedArguments || queryArguments; + context = element || context; + if(typeof query == 'string' && object !== undefined) { + query = query.split(/[\. ]/); + maxDepth = query.length - 1; + $.each(query, function(depth, value) { + var camelCaseValue = (depth != maxDepth) + ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1) + : query + ; + if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) { + object = object[camelCaseValue]; + } + else if( object[camelCaseValue] !== undefined ) { + found = object[camelCaseValue]; + return false; + } + else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) { + object = object[value]; + } + else if( object[value] !== undefined ) { + found = object[value]; + return false; + } + else { + module.error(error.method, query); + return false; + } + }); + } + if ( $.isFunction( found ) ) { + response = found.apply(context, passedArguments); + } + else if(found !== undefined) { + response = found; + } + if($.isArray(returnedValue)) { + returnedValue.push(response); + } + else if(returnedValue !== undefined) { + returnedValue = [returnedValue, response]; + } + else if(response !== undefined) { + returnedValue = response; + } + return found; + } + }; + + if(methodInvoked) { + if(instance === undefined) { + module.initialize(); + } + instance.save.scroll(); + instance.save.calculations(); + module.invoke(query); + } + else { + if(instance !== undefined) { + instance.invoke('destroy'); + } + module.initialize(); + } + }) + ; + + return (returnedValue !== undefined) + ? returnedValue + : this + ; +}; + +$.fn.visibility.settings = { + + name : 'Visibility', + namespace : 'visibility', + + debug : false, + verbose : false, + performance : true, + + // whether to use mutation observers to follow changes + observeChanges : true, + + // check position immediately on init + initialCheck : true, + + // whether to refresh calculations after all page images load + refreshOnLoad : true, + + // whether to refresh calculations after page resize event + refreshOnResize : true, + + // should call callbacks on refresh event (resize, etc) + checkOnRefresh : true, + + // callback should only occur one time + once : true, + + // callback should fire continuously whe evaluates to true + continuous : false, + + // offset to use with scroll top + offset : 0, + + // whether to include margin in elements position + includeMargin : false, + + // scroll context for visibility checks + context : window, + + // visibility check delay in ms (defaults to animationFrame) + throttle : false, + + // special visibility type (image, fixed) + type : false, + + // z-index to use with visibility 'fixed' + zIndex : '10', + + // image only animation settings + transition : 'fade in', + duration : 1000, + + // array of callbacks for percentage + onPassed : {}, + + // standard callbacks + onOnScreen : false, + onOffScreen : false, + onPassing : false, + onTopVisible : false, + onBottomVisible : false, + onTopPassed : false, + onBottomPassed : false, + + // reverse callbacks + onPassingReverse : false, + onTopVisibleReverse : false, + onBottomVisibleReverse : false, + onTopPassedReverse : false, + onBottomPassedReverse : false, + + // special callbacks for image + onLoad : function() {}, + onAllLoaded : function() {}, + + // special callbacks for fixed position + onFixed : function() {}, + onUnfixed : function() {}, + + // utility callbacks + onUpdate : false, // disabled by default for performance + onRefresh : function(){}, + + metadata : { + src: 'src' + }, + + className: { + fixed : 'fixed', + placeholder : 'placeholder', + visible : 'visible' + }, + + error : { + method : 'The method you called is not defined.', + visible : 'Element is hidden, you must call refresh after element becomes visible' + } + +}; + +})( jQuery, window, document ); diff --git a/semantic.min.js b/semantic.min.js new file mode 100644 index 0000000..b574823 --- /dev/null +++ b/semantic.min.js @@ -0,0 +1,11 @@ + /* + * # Semantic UI - 2.4.1 + * https://github.com/Semantic-Org/Semantic-UI + * http://www.semantic-ui.com/ + * + * Copyright 2014 Contributors + * Released under the MIT license + * http://opensource.org/licenses/MIT + * + */ +!function(p,h,v,b){p.site=p.fn.site=function(e){var s,l,i=(new Date).getTime(),o=[],t=e,n="string"==typeof t,c=[].slice.call(arguments,1),u=p.isPlainObject(e)?p.extend(!0,{},p.site.settings,e):p.extend({},p.site.settings),a=u.namespace,d=u.error,r="module-"+a,f=p(v),m=this,g=f.data(r);return s={initialize:function(){s.instantiate()},instantiate:function(){s.verbose("Storing instance of site",s),g=s,f.data(r,s)},normalize:function(){s.fix.console(),s.fix.requestAnimationFrame()},fix:{console:function(){s.debug("Normalizing window.console"),console!==b&&console.log!==b||(s.verbose("Console not available, normalizing events"),s.disable.console()),void 0!==console.group&&void 0!==console.groupEnd&&void 0!==console.groupCollapsed||(s.verbose("Console group not available, normalizing events"),h.console.group=function(){},h.console.groupEnd=function(){},h.console.groupCollapsed=function(){}),void 0===console.markTimeline&&(s.verbose("Mark timeline not available, normalizing events"),h.console.markTimeline=function(){})},consoleClear:function(){s.debug("Disabling programmatic console clearing"),h.console.clear=function(){}},requestAnimationFrame:function(){s.debug("Normalizing requestAnimationFrame"),h.requestAnimationFrame===b&&(s.debug("RequestAnimationFrame not available, normalizing event"),h.requestAnimationFrame=h.requestAnimationFrame||h.mozRequestAnimationFrame||h.webkitRequestAnimationFrame||h.msRequestAnimationFrame||function(e){setTimeout(e,0)})}},moduleExists:function(e){return p.fn[e]!==b&&p.fn[e].settings!==b},enabled:{modules:function(e){var n=[];return e=e||u.modules,p.each(e,function(e,t){s.moduleExists(t)&&n.push(t)}),n}},disabled:{modules:function(e){var n=[];return e=e||u.modules,p.each(e,function(e,t){s.moduleExists(t)||n.push(t)}),n}},change:{setting:function(o,a,e,r){e="string"==typeof e?"all"===e?u.modules:[e]:e||u.modules,r=r===b||r,p.each(e,function(e,t){var n,i=!s.moduleExists(t)||(p.fn[t].settings.namespace||!1);s.moduleExists(t)&&(s.verbose("Changing default setting",o,a,t),p.fn[t].settings[o]=a,r&&i&&0<(n=p(":data(module-"+i+")")).length&&(s.verbose("Modifying existing settings",n),n[t]("setting",o,a)))})},settings:function(i,e,o){e="string"==typeof e?[e]:e||u.modules,o=o===b||o,p.each(e,function(e,t){var n;s.moduleExists(t)&&(s.verbose("Changing default setting",i,t),p.extend(!0,p.fn[t].settings,i),o&&a&&0<(n=p(":data(module-"+a+")")).length&&(s.verbose("Modifying existing settings",n),n[t]("setting",i)))})}},enable:{console:function(){s.console(!0)},debug:function(e,t){e=e||u.modules,s.debug("Enabling debug for modules",e),s.change.setting("debug",!0,e,t)},verbose:function(e,t){e=e||u.modules,s.debug("Enabling verbose debug for modules",e),s.change.setting("verbose",!0,e,t)}},disable:{console:function(){s.console(!1)},debug:function(e,t){e=e||u.modules,s.debug("Disabling debug for modules",e),s.change.setting("debug",!1,e,t)},verbose:function(e,t){e=e||u.modules,s.debug("Disabling verbose debug for modules",e),s.change.setting("verbose",!1,e,t)}},console:function(e){if(e){if(g.cache.console===b)return void s.error(d.console);s.debug("Restoring console function"),h.console=g.cache.console}else s.debug("Disabling console function"),g.cache.console=h.console,h.console={clear:function(){},error:function(){},group:function(){},groupCollapsed:function(){},groupEnd:function(){},info:function(){},log:function(){},markTimeline:function(){},warn:function(){}}},destroy:function(){s.verbose("Destroying previous site for",f),f.removeData(r)},cache:{},setting:function(e,t){if(p.isPlainObject(e))p.extend(!0,u,e);else{if(t===b)return u[e];u[e]=t}},internal:function(e,t){if(p.isPlainObject(e))p.extend(!0,s,e);else{if(t===b)return s[e];s[e]=t}},debug:function(){u.debug&&(u.performance?s.performance.log(arguments):(s.debug=Function.prototype.bind.call(console.info,console,u.name+":"),s.debug.apply(console,arguments)))},verbose:function(){u.verbose&&u.debug&&(u.performance?s.performance.log(arguments):(s.verbose=Function.prototype.bind.call(console.info,console,u.name+":"),s.verbose.apply(console,arguments)))},error:function(){s.error=Function.prototype.bind.call(console.error,console,u.name+":"),s.error.apply(console,arguments)},performance:{log:function(e){var t,n;u.performance&&(n=(t=(new Date).getTime())-(i||t),i=t,o.push({Element:m,Name:e[0],Arguments:[].slice.call(e,1)||"","Execution Time":n})),clearTimeout(s.performance.timer),s.performance.timer=setTimeout(s.performance.display,500)},display:function(){var e=u.name+":",n=0;i=!1,clearTimeout(s.performance.timer),p.each(o,function(e,t){n+=t["Execution Time"]}),e+=" "+n+"ms",(console.group!==b||console.table!==b)&&0")},fields:function(e){var n=F();return F.each(e,function(e,t){n=n.add(h.get.field(t))}),n},validation:function(n){var i,o;return!!c&&(F.each(c,function(e,t){o=t.identifier||e,h.get.field(o)[0]==n[0]&&(t.identifier=o,i=t)}),i||!1)},value:function(e){var t=[];return t.push(e),h.get.values.call(v,t)[e]},values:function(e){var t=F.isArray(e)?h.get.fields(e):n,c={};return t.each(function(e,t){var n=F(t),i=(n.prop("type"),n.prop("name")),o=n.val(),a=n.is(f.checkbox),r=n.is(f.radio),s=-1!==i.indexOf("[]"),l=!!a&&n.is(":checked");i&&(s?(i=i.replace("[]",""),c[i]||(c[i]=[]),a?l?c[i].push(o||!0):c[i].push(!1):c[i].push(o)):r?c[i]!==D&&0!=c[i]||(c[i]=!!l&&(o||!0)):c[i]=a?!!l&&(o||!0):o)}),c}},has:{field:function(e){return h.verbose("Checking for existence of a field with identifier",e),"string"!=typeof(e=h.escape.string(e))&&h.error(s.identifier,e),0"}),F(n+="")},prompt:function(e){return F("
").addClass("ui basic red pointing prompt label").html(e[0])}},rules:{empty:function(e){return!(e===D||""===e||F.isArray(e)&&0===e.length)},checked:function(){return 0=t},length:function(e,t){return e!==D&&e.length>=t},exactLength:function(e,t){return e!==D&&e.length==t},maxLength:function(e,t){return e!==D&&e.length<=t},match:function(e,t){var n;F(this);return 0=t)},exactCount:function(e,t){return 0==t?""===e:1==t?""!==e&&-1===e.search(","):e.split(",").length==t},maxCount:function(e,t){return 0!=t&&(1==t?-1===e.search(","):e.split(",").length<=t)}}}}(jQuery,window,document),function(S,k,e,T){"use strict";k=void 0!==k&&k.Math==Math?k:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),S.fn.accordion=function(a){var v,r=S(this),b=(new Date).getTime(),y=[],x=a,C="string"==typeof x,w=[].slice.call(arguments,1);k.requestAnimationFrame||k.mozRequestAnimationFrame||k.webkitRequestAnimationFrame||k.msRequestAnimationFrame;return r.each(function(){var e,c,u=S.isPlainObject(a)?S.extend(!0,{},S.fn.accordion.settings,a):S.extend({},S.fn.accordion.settings),d=u.className,t=u.namespace,f=u.selector,s=u.error,n="."+t,i="module-"+t,o=r.selector||"",m=S(this),g=m.find(f.title),p=m.find(f.content),l=this,h=m.data(i);c={initialize:function(){c.debug("Initializing",m),c.bind.events(),u.observeChanges&&c.observeChanges(),c.instantiate()},instantiate:function(){h=c,m.data(i,c)},destroy:function(){c.debug("Destroying previous instance",m),m.off(n).removeData(i)},refresh:function(){g=m.find(f.title),p=m.find(f.content)},observeChanges:function(){"MutationObserver"in k&&((e=new MutationObserver(function(e){c.debug("DOM tree modified, updating selector cache"),c.refresh()})).observe(l,{childList:!0,subtree:!0}),c.debug("Setting up mutation observer",e))},bind:{events:function(){c.debug("Binding delegated events"),m.on(u.on+n,f.trigger,c.event.click)}},event:{click:function(){c.toggle.call(this)}},toggle:function(e){var t=e!==T?"number"==typeof e?g.eq(e):S(e).closest(f.title):S(this).closest(f.title),n=t.next(p),i=n.hasClass(d.animating),o=n.hasClass(d.active),a=o&&!i,r=!o&&i;c.debug("Toggling visibility of content",t),a||r?u.collapsible?c.close.call(t):c.debug("Cannot close accordion content collapsing is disabled"):c.open.call(t)},open:function(e){var t=e!==T?"number"==typeof e?g.eq(e):S(e).closest(f.title):S(this).closest(f.title),n=t.next(p),i=n.hasClass(d.animating);n.hasClass(d.active)||i?c.debug("Accordion already open, skipping",n):(c.debug("Opening accordion content",t),u.onOpening.call(n),u.onChanging.call(n),u.exclusive&&c.closeOthers.call(t),t.addClass(d.active),n.stop(!0,!0).addClass(d.animating),u.animateChildren&&(S.fn.transition!==T&&m.transition("is supported")?n.children().transition({animation:"fade in",queue:!1,useFailSafe:!0,debug:u.debug,verbose:u.verbose,duration:u.duration}):n.children().stop(!0,!0).animate({opacity:1},u.duration,c.resetOpacity)),n.slideDown(u.duration,u.easing,function(){n.removeClass(d.animating).addClass(d.active),c.reset.display.call(this),u.onOpen.call(this),u.onChange.call(this)}))},close:function(e){var t=e!==T?"number"==typeof e?g.eq(e):S(e).closest(f.title):S(this).closest(f.title),n=t.next(p),i=n.hasClass(d.animating),o=n.hasClass(d.active);!o&&!(!o&&i)||o&&i||(c.debug("Closing accordion content",n),u.onClosing.call(n),u.onChanging.call(n),t.removeClass(d.active),n.stop(!0,!0).addClass(d.animating),u.animateChildren&&(S.fn.transition!==T&&m.transition("is supported")?n.children().transition({animation:"fade out",queue:!1,useFailSafe:!0,debug:u.debug,verbose:u.verbose,duration:u.duration}):n.children().stop(!0,!0).animate({opacity:0},u.duration,c.resetOpacity)),n.slideUp(u.duration,u.easing,function(){n.removeClass(d.animating).removeClass(d.active),c.reset.display.call(this),u.onClose.call(this),u.onChange.call(this)}))},closeOthers:function(e){var t,n,i,o=e!==T?g.eq(e):S(this).closest(f.title),a=o.parents(f.content).prev(f.title),r=o.closest(f.accordion),s=f.title+"."+d.active+":visible",l=f.content+"."+d.active+":visible";i=u.closeNested?(t=r.find(s).not(a)).next(p):(t=r.find(s).not(a),n=r.find(l).find(s).not(a),(t=t.not(n)).next(p)),0 adjusting invoked element"),c=c.closest(o.checkbox),s.refresh())}},setup:function(){s.set.initialLoad(),s.is.indeterminate()?(s.debug("Initial value is indeterminate"),s.indeterminate()):s.is.checked()?(s.debug("Initial value is checked"),s.check()):(s.debug("Initial value is unchecked"),s.uncheck()),s.remove.initialLoad()},refresh:function(){u=c.children(o.label),d=c.children(o.input),f=d[0]},hide:{input:function(){s.verbose("Modifying z-index to be unselectable"),d.addClass(t.hidden)}},show:{input:function(){s.verbose("Modifying z-index to be selectable"),d.removeClass(t.hidden)}},observeChanges:function(){"MutationObserver"in A&&((e=new MutationObserver(function(e){s.debug("DOM tree modified, updating selector cache"),s.refresh()})).observe(h,{childList:!0,subtree:!0}),s.debug("Setting up mutation observer",e))},attachEvents:function(e,t){var n=T(e);t=T.isFunction(s[t])?s[t]:s.toggle,0").insertAfter(d),s.debug("Creating label",u))}},has:{label:function(){return 0 .ui.dimmer",content:".ui.dimmer > .content, .ui.dimmer > .content > .center"},template:{dimmer:function(){return S("
").attr("class","ui dimmer")}}}}(jQuery,window,document),function(Y,Z,K,J){"use strict";Z=void 0!==Z&&Z.Math==Math?Z:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")(),Y.fn.dropdown=function(M){var L,V=Y(this),N=Y(K),H=V.selector||"",U="ontouchstart"in K.documentElement,W=(new Date).getTime(),B=[],Q=M,X="string"==typeof Q,$=[].slice.call(arguments,1);return V.each(function(n){var e,t,i,o,a,r,s,g,p=Y.isPlainObject(M)?Y.extend(!0,{},Y.fn.dropdown.settings,M):Y.extend({},Y.fn.dropdown.settings),h=p.className,c=p.message,l=p.fields,v=p.keys,b=p.metadata,u=p.namespace,d=p.regExp,y=p.selector,f=p.error,m=p.templates,x="."+u,C="module-"+u,w=Y(this),S=Y(p.context),k=w.find(y.text),T=w.find(y.search),A=w.find(y.sizer),R=w.find(y.input),P=w.find(y.icon),E=0").html(o).attr("data-"+b.value,t).attr("data-"+b.text,t).addClass(h.addition).addClass(h.item),p.hideAdditions&&i.addClass(h.hidden),n=n===J?i:n.add(i),g.verbose("Creating user choices for value",t,i))}),n)},userLabels:function(e){var t=g.get.userValues();t&&(g.debug("Adding user labels",t),Y.each(t,function(e,t){g.verbose("Adding custom user value"),g.add.label(t,t)}))},menu:function(){F=Y("
").addClass(h.menu).appendTo(w)},sizer:function(){A=Y("").addClass(h.sizer).insertAfter(T)}},search:function(e){e=e!==J?e:g.get.query(),g.verbose("Searching for query",e),g.has.minCharacters(e)?g.filter(e):g.hide()},select:{firstUnfiltered:function(){g.verbose("Selecting first non-filtered element"),g.remove.selectedItem(),O.not(y.unselectable).not(y.addition+y.hidden).eq(0).addClass(h.selected)},nextAvailable:function(e){var t=(e=e.eq(0)).nextAll(y.item).not(y.unselectable).eq(0),n=e.prevAll(y.item).not(y.unselectable).eq(0);0").addClass(h.search).prop("autocomplete","off").insertBefore(k)),g.is.multiple()&&g.is.searchSelection()&&!g.has.sizer()&&g.create.sizer(),p.allowTab&&g.set.tabbable()},select:function(){var e=g.get.selectValues();g.debug("Dropdown initialized on a select",e),w.is("select")&&(R=w),0").attr("class",R.attr("class")).addClass(h.selection).addClass(h.dropdown).html(m.dropdown(e)).insertBefore(R),R.hasClass(h.multiple)&&!1===R.prop("multiple")&&(g.error(f.missingMultiple),R.prop("multiple",!0)),R.is("[multiple]")&&g.set.multiple(),R.prop("disabled")&&(g.debug("Disabling dropdown"),w.addClass(h.disabled)),R.removeAttr("class").detach().prependTo(w)),g.refresh()},menu:function(e){F.html(m.menu(e,l)),O=F.find(y.item)},reference:function(){g.debug("Dropdown behavior was called on select, replacing with closest dropdown"),w=w.parent(y.dropdown),I=w.data(C),z=w.get(0),g.refresh(),g.setup.returnedObject()},returnedObject:function(){var e=V.slice(0,n),t=V.slice(n+1);V=e.add(w).add(t)}},refresh:function(){g.refreshSelectors(),g.refreshData()},refreshItems:function(){O=F.find(y.item)},refreshSelectors:function(){g.verbose("Refreshing selector cache"),k=w.find(y.text),T=w.find(y.search),R=w.find(y.input),P=w.find(y.icon),E=0 modified, recreating menu");var n=!1;Y.each(e,function(e,t){if(Y(t.target).is("select")||Y(t.addedNodes).is("select"))return n=!0}),n&&(g.disconnect.selectObserver(),g.refresh(),g.setup.select(),g.set.selected(),g.observe.select())}},menu:{mutation:function(e){var t=e[0],n=t.addedNodes?Y(t.addedNodes[0]):Y(!1),i=t.removedNodes?Y(t.removedNodes[0]):Y(!1),o=n.add(i),a=o.is(y.addition)||0t.name?1:-1}),g.debug("Retrieved and sorted values from select",o)):g.debug("Retrieved values from select",o),o},activeItem:function(){return O.filter("."+h.active)},selectedItem:function(){var e=O.not(y.unselectable).filter("."+h.selected);return 0=p.maxSelections?(g.debug("Maximum selection count reached"),p.useLabels&&(O.addClass(h.filtered),g.add.message(c.maxSelections)),!0):(g.verbose("No longer at maximum selection count"),g.remove.message(),g.remove.filteredItem(),g.is.searchSelection()&&g.filterItems(),!1))}},restore:{defaults:function(){g.clear(),g.restore.defaultText(),g.restore.defaultValue()},defaultText:function(){var e=g.get.defaultText();e===g.get.placeholderText?(g.debug("Restoring default placeholder text",e),g.set.placeholderText(e)):(g.debug("Restoring default text",e),g.set.text(e))},placeholderText:function(){g.set.placeholderText()},defaultValue:function(){var e=g.get.defaultValue();e!==J&&(g.debug("Restoring default value",e),""!==e?(g.set.value(e),g.set.selected()):(g.remove.activeItem(),g.remove.selectedItem()))},labels:function(){p.allowAdditions&&(p.useLabels||(g.error(f.labels),p.useLabels=!0),g.debug("Restoring selected values"),g.create.userLabels()),g.check.maxSelections()},selected:function(){g.restore.values(),g.is.multiple()?(g.debug("Restoring previously selected values and labels"),g.restore.labels()):g.debug("Restoring previously selected values")},values:function(){g.set.initialLoad(),p.apiSettings&&p.saveRemoteData&&g.get.remoteValues()?g.restore.remoteValues():g.set.selected(),g.remove.initialLoad()},remoteValues:function(){var e=g.get.remoteValues();g.debug("Recreating selected from session data",e),e&&(g.is.single()?Y.each(e,function(e,t){g.set.text(t)}):Y.each(e,function(e,t){g.add.label(e,t)}))}},read:{remoteData:function(e){var t;if(Z.Storage!==J)return(t=sessionStorage.getItem(e))!==J&&t;g.error(f.noStorage)}},save:{defaults:function(){g.save.defaultText(),g.save.placeholderText(),g.save.defaultValue()},defaultValue:function(){var e=g.get.value();g.verbose("Saving default value as",e),w.data(b.defaultValue,e)},defaultText:function(){var e=g.get.text();g.verbose("Saving default text as",e),w.data(b.defaultText,e)},placeholderText:function(){var e;!1!==p.placeholder&&k.hasClass(h.placeholder)&&(e=g.get.text(),g.verbose("Saving placeholder text as",e),w.data(b.placeholderText,e))},remoteData:function(e,t){Z.Storage!==J?(g.verbose("Saving remote data to session storage",t,e),sessionStorage.setItem(t,e)):g.error(f.noStorage)}},clear:function(){g.is.multiple()&&p.useLabels?g.remove.labels():(g.remove.activeItem(),g.remove.selectedItem()),g.set.placeholderText(),g.clearValue()},clearValue:function(){g.set.value("")},scrollPage:function(e,t){var n,i,o=t||g.get.selectedItem(),a=o.closest(y.menu),r=a.outerHeight(),s=a.scrollTop(),l=O.eq(0).outerHeight(),c=Math.floor(r/l),u=(a.prop("scrollHeight"),"up"==e?s-l*c:s+l*c),d=O.not(y.unselectable);i="up"==e?d.index(o)-c:d.index(o)+c,0<(n=("up"==e?0<=i:i").addClass(h.label).attr("data-"+b.value,a).html(m.label(a,t)),i=p.onLabelCreate.call(i,a,t),g.has.label(e)?g.debug("User selection already exists, skipping",a):(p.label.variation&&i.addClass(p.label.variation),!0===n?(g.debug("Animating in label",i),i.addClass(h.hidden).insertBefore(o).transition(p.label.transition,p.label.duration)):(g.debug("Adding selection label",i),i.insertBefore(o)))},message:function(e){var t=F.children(y.message),n=p.templates.message(g.add.variables(e));0").html(n).addClass(h.message).appendTo(F)},optionValue:function(e){var t=g.escape.value(e);0").prop("value",t).addClass(h.addition).html(e).appendTo(R),g.verbose("Adding user addition as an
+

Currency Converter

+ +

@@ -221,14 +224,14 @@

Currency Converter

-

Exchange Rate:

-

+

Exchange Rate:

+


-

Exchange Rate:

-

+

Exchange Rate:

+


@@ -236,8 +239,7 @@

Currency Converter

-

Date :

-

+
@@ -246,7 +248,7 @@

Currency Converter

-
+

CURRENCY I HAVE:

@@ -254,7 +256,7 @@

Currency Converter

-
+

CURRENCY I NEED:

@@ -262,11 +264,6 @@

Currency Converter

- - - - -
@@ -278,13 +275,14 @@

Currency Converter

+
-
+
diff --git a/style/custom.css b/style/custom.css index 4792c81..11c7f8d 100644 --- a/style/custom.css +++ b/style/custom.css @@ -172,6 +172,9 @@ h4 { .currencyTitle{ font-family: 'Open Sans', sans-serif!important; font-size: 50px!important; + text-transform: uppercase!important; + font-weight: 700!important; + color: lightgray!important; } #center-currency{ @@ -196,6 +199,11 @@ h4 { input { border-radius: 25px; } +.weatherBackground{ + + background-color:#B1AFD1; + background-image: url(./assets/images/greece-01.png); +} i.home .icon{ width:10px; @@ -273,6 +281,77 @@ i.home .icon{ } */ +.currencyBackground{ + background-color: lightgray; +} + +.exchangeRate{ + font-family: serif!important; + font-size: 1.5rem!important; + text-align: center; +} + +.rate1 { + font-family: serif!important; + font-size: 1.5rem!important; + text-align: center; + font-weight: 700!important; + position: relative; + top: 85px; +} +.rate2{ + font-family: serif!important; + font-size: 1.5rem!important; + text-align: center; + font-weight: 700!important; + position: relative; + top: 85px; +} + +.ui .input .currencyInput{ + width: 200px; +} + +#currBg{ + background-image: url(../assets/images/ffinalBGsecond-01.png); + background-size: cover; + + +} + +.box{ + position: absolute; + top: 50%; + left:50%; + transform: translate(-50%, -50%); + width: 200px; + height: 80px; + background: #111845a6; + box-sizing: border-box; + overflow: hidden; + box-shadow: 0 20px 50px rgb(23, 32, 90); + border: 2px solid #2a3cad; + color: white; + padding: 20px; +} + +.box:before{ + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height:100%; + background: rgba(255,255,255,0.1); + transition:0.5s; + pointer-events: none; +} + +.box:hover:before{ + left:-50%; + transform: skewX(-5deg) +} + .ui.grid.weather{ position: relative; width: 2000px; diff --git a/style/script.js b/style/script.js index 39c30ad..9f9c49c 100644 --- a/style/script.js +++ b/style/script.js @@ -4,6 +4,8 @@ const API_URL = 'https://api.exchangeratesapi.io/latest'; let html = ''; $("#currentDay").text(moment().format("DD/M/YYYY")); +$("#currentDayForCurrency").text(moment().format("dddd do YYYY")); + $("#searchBtn").click(function(event) { console.log('button clicked') @@ -19,7 +21,11 @@ $("#searchBtn").click(function(event) { let queryURL = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=73b47f542215050a64d2b287364ee1d1`; console.log('weather infor', queryURL); - + let cities = []; + cities.push(cityName); + let cityList = JSON.stringify(cities); + localStorage.setItem( "search-cities" , cityList); + let KELVIN = 273.15; $.ajax ({ From fcafab51df9f53143ddf1ff26037e185254f5378 Mon Sep 17 00:00:00 2001 From: Sumaya Hassan Date: Fri, 6 Nov 2020 21:15:00 +0000 Subject: [PATCH 7/7] local storage for currencies --- assets/images/backgroundTwo.jpg | Bin 0 -> 169243 bytes assets/images/weather-bg.jpg | Bin 0 -> 64089 bytes index.html | 331 ++++++++++++++---------- script.js | 446 ++++++++++++++++++++++++++++++-- style/custom.css | 143 ++++++---- style/script.js | 50 +++- 6 files changed, 751 insertions(+), 219 deletions(-) create mode 100644 assets/images/backgroundTwo.jpg create mode 100644 assets/images/weather-bg.jpg diff --git a/assets/images/backgroundTwo.jpg b/assets/images/backgroundTwo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a9f1ed1ca577691cf93ddebacdf1ff2ee29b182 GIT binary patch literal 169243 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

j}7u1wN{T>#8Xy9L+x4Yp@+-Ukj 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

JcB8qSX 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 ZY91j%A?-*S;fj^ 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 A-v9sr literal 0 HcmV?d00001 diff --git a/index.html b/index.html index 5036b87..1f6a877 100644 --- a/index.html +++ b/index.html @@ -26,28 +26,9 @@ - - - - - - - - + + @@ -62,12 +43,7 @@

- +
+
-
+
+
+
+
+

Currency Converter

@@ -135,86 +116,87 @@

Currency Converter

- +
- @@ -248,18 +230,18 @@

Currency Converter

- + + + + + + + + @@ -336,6 +397,6 @@

- + \ No newline at end of file diff --git a/script.js b/script.js index 1d0b440..1cdc3c7 100644 --- a/script.js +++ b/script.js @@ -2,42 +2,438 @@ var currency1; var currency2; var rate1; var rate2; +function callCurrenciesAndRates() { + currency1 = + currencyCodes[$("input[name='country1']").val().toUpperCase()]; + currency2 = + currencyCodes[$("input[name='country2']").val().toUpperCase()]; + console.log("first Currency", currency1); + console.log("second Currency", currency2); + if (currency1 && currency2) { + $.get( + "https://api.exchangeratesapi.io/latest?symbols=" + + currency1 + + "," + + currency2, + function (data, status) { + //$("input[name='amount1']").val(data.rates[currency1]); + //$("input[name='amount2']").val(data.rates[currency2]); + rate1 = data.rates[currency1]; + rate2 = data.rates[currency2]; + $(".rate1").html(rate1); + $(".rate2").html(rate2); + $(".date").html(data.date); + } + ); + } + } +$(document).ready(function () { + $(".ui.sidebar").sidebar("attach events", ".toc.item"); -$(document).ready(function(){ + $(".ui.dropdown").dropdown(); + $(".ui.buttons .dropdown.button").dropdown({ + action: "combo", + }); + loadCurrencyLocally(); + callCurrenciesAndRates(); + $(".dropdown").click(function () { + callCurrenciesAndRates(); -; - $(".dropdown").click(function(){ -currency1=currencyCodes[$("input[name='country1']").val().toUpperCase()]; -currency2=currencyCodes[$("input[name='country2']").val().toUpperCase()]; -$.get("https://api.exchangeratesapi.io/latest?symbols="+currency1+","+currency2, function(data, status){ -//$("input[name='amount1']").val(data.rates[currency1]); -//$("input[name='amount2']").val(data.rates[currency2]); -rate1 = data.rates[currency1]; -rate2 = data.rates[currency2]; -$(".rate1").html(rate1); -$(".rate2").html(rate2); -$(".date").html(data.date); + }); + + $("input[name='amount1']").keyup(function () { + var val1 = $("input[name='amount1']").val(); + var convertedVal = (val1 / rate1) * rate2; + $("input[name='amount2']").val(convertedVal); + }); + $("input[name='amount2']").keyup(function () { + var val1 = $("input[name='amount2']").val(); + var convertedVal = (val1 / rate2) * rate1; + + $("input[name='amount1']").val(convertedVal); + }); }); - }); +var currencyCodes = { + BD: "BDT", + BE: "EUR", + BF: "XOF", + BG: "BGN", + BA: "BAM", + BB: "BBD", + WF: "XPF", + BL: "EUR", + BM: "BMD", + BN: "BND", + BO: "BOB", + BH: "BHD", + BI: "BIF", + BJ: "XOF", + BT: "BTN", + JM: "JMD", + BV: "NOK", + BW: "BWP", + WS: "WST", + BQ: "USD", + BR: "BRL", + BS: "BSD", + JE: "GBP", + BY: "BYR", + BZ: "BZD", + RU: "RUB", + RW: "RWF", + RS: "RSD", + TL: "USD", + RE: "EUR", + TM: "TMT", + TJ: "TJS", + RO: "RON", + TK: "NZD", + GW: "XOF", + GU: "USD", + GT: "GTQ", + GS: "GBP", + GR: "EUR", + GQ: "XAF", + GP: "EUR", + JP: "JPY", + GY: "GYD", + GG: "GBP", + GF: "EUR", + GE: "GEL", + GD: "XCD", + GB: "GBP", + GA: "XAF", + SV: "USD", + GN: "GNF", + GM: "GMD", + GL: "DKK", + GI: "GIP", + GH: "GHS", + OM: "OMR", + TN: "TND", + JO: "JOD", + HR: "HRK", + HT: "HTG", + HU: "HUF", + HK: "HKD", + HN: "HNL", + HM: "AUD", + VE: "VEF", + PR: "USD", + PS: "ILS", + PW: "USD", + PT: "EUR", + SJ: "NOK", + PY: "PYG", + IQ: "IQD", + PA: "PAB", + PF: "XPF", + PG: "PGK", + PE: "PEN", + PK: "PKR", + PH: "PHP", + PN: "NZD", + PL: "PLN", + PM: "EUR", + ZM: "ZMK", + EH: "MAD", + EE: "EUR", + EG: "EGP", + ZA: "ZAR", + EC: "USD", + IT: "EUR", + VN: "VND", + SB: "SBD", + ET: "ETB", + SO: "SOS", + ZW: "ZWL", + SA: "SAR", + ES: "EUR", + ER: "ERN", + ME: "EUR", + MD: "MDL", + MG: "MGA", + MF: "EUR", + MA: "MAD", + MC: "EUR", + UZ: "UZS", + MM: "MMK", + ML: "XOF", + MO: "MOP", + MN: "MNT", + MH: "USD", + MK: "MKD", + MU: "MUR", + MT: "EUR", + MW: "MWK", + MV: "MVR", + MQ: "EUR", + MP: "USD", + MS: "XCD", + MR: "MRO", + IM: "GBP", + UG: "UGX", + TZ: "TZS", + MY: "MYR", + MX: "MXN", + IL: "ILS", + FR: "EUR", + IO: "USD", + SH: "SHP", + FI: "EUR", + FJ: "FJD", + FK: "FKP", + FM: "USD", + FO: "DKK", + NI: "NIO", + NL: "EUR", + NO: "NOK", + NA: "NAD", + VU: "VUV", + NC: "XPF", + NE: "XOF", + NF: "AUD", + NG: "NGN", + NZ: "NZD", + NP: "NPR", + NR: "AUD", + NU: "NZD", + CK: "NZD", + XK: "EUR", + CI: "XOF", + CH: "CHF", + CO: "COP", + CN: "CNY", + CM: "XAF", + CL: "CLP", + CC: "AUD", + CA: "CAD", + CG: "XAF", + CF: "XAF", + CD: "CDF", + CZ: "CZK", + CY: "EUR", + CX: "AUD", + CR: "CRC", + CW: "ANG", + CV: "CVE", + CU: "CUP", + SZ: "SZL", + SY: "SYP", + SX: "ANG", + KG: "KGS", + KE: "KES", + SS: "SSP", + SR: "SRD", + KI: "AUD", + KH: "KHR", + KN: "XCD", + KM: "KMF", + ST: "STD", + SK: "EUR", + KR: "KRW", + SI: "EUR", + KP: "KPW", + KW: "KWD", + SN: "XOF", + SM: "EUR", + SL: "SLL", + SC: "SCR", + KZ: "KZT", + KY: "KYD", + SG: "SGD", + SE: "SEK", + SD: "SDG", + DO: "DOP", + DM: "XCD", + DJ: "DJF", + DK: "DKK", + VG: "USD", + DE: "EUR", + YE: "YER", + DZ: "DZD", + US: "USD", + UY: "UYU", + YT: "EUR", + UM: "USD", + LB: "LBP", + LC: "XCD", + LA: "LAK", + TV: "AUD", + TW: "TWD", + TT: "TTD", + TR: "TRY", + LK: "LKR", + LI: "CHF", + LV: "EUR", + TO: "TOP", + LT: "LTL", + LU: "EUR", + LR: "LRD", + LS: "LSL", + TH: "THB", + TF: "EUR", + TG: "XOF", + TD: "XAF", + TC: "USD", + LY: "LYD", + VA: "EUR", + VC: "XCD", + AE: "AED", + AD: "EUR", + AG: "XCD", + AF: "AFN", + AI: "XCD", + VI: "USD", + IS: "ISK", + IR: "IRR", + AM: "AMD", + AL: "ALL", + AO: "AOA", + AQ: "", + AS: "USD", + AR: "ARS", + AU: "AUD", + AT: "EUR", + AW: "AWG", + IN: "INR", + AX: "EUR", + AZ: "AZN", + IE: "EUR", + ID: "IDR", + UA: "UAH", + QA: "QAR", + MZ: "MZN", +}; +const select = document.querySelectorAll("select"); +const input = document.querySelectorAll("input"); +const API_URL = "https://api.exchangeratesapi.io/latest"; +let html = ""; +$("#currentDay").text(moment().format("DD/M/YYYY")); +$("#currentDayForCurrency").text(moment().format("dddd do MMMM YYYY")); - $("input[name='amount1']").keyup(function(){ - var val1 = $("input[name='amount1']").val(); -var convertedVal = (val1/rate1)*rate2; -$("input[name='amount2']").val(convertedVal); - }); - $("input[name='amount2']").keyup(function(){ - var val1 = $("input[name='amount2']").val(); -var convertedVal =(val1/rate2)*rate1; -$("input[name='amount1']").val(convertedVal); - }); +$("#searchBtn").click(function (event) { + console.log("button ccclicked"); + getWeather(); + getFiveDayForcast(); + saveWeatherToStorage(); }); -var currencyCodes = {"BD": "BDT", "BE": "EUR", "BF": "XOF", "BG": "BGN", "BA": "BAM", "BB": "BBD", "WF": "XPF", "BL": "EUR", "BM": "BMD", "BN": "BND", "BO": "BOB", "BH": "BHD", "BI": "BIF", "BJ": "XOF", "BT": "BTN", "JM": "JMD", "BV": "NOK", "BW": "BWP", "WS": "WST", "BQ": "USD", "BR": "BRL", "BS": "BSD", "JE": "GBP", "BY": "BYR", "BZ": "BZD", "RU": "RUB", "RW": "RWF", "RS": "RSD", "TL": "USD", "RE": "EUR", "TM": "TMT", "TJ": "TJS", "RO": "RON", "TK": "NZD", "GW": "XOF", "GU": "USD", "GT": "GTQ", "GS": "GBP", "GR": "EUR", "GQ": "XAF", "GP": "EUR", "JP": "JPY", "GY": "GYD", "GG": "GBP", "GF": "EUR", "GE": "GEL", "GD": "XCD", "GB": "GBP", "GA": "XAF", "SV": "USD", "GN": "GNF", "GM": "GMD", "GL": "DKK", "GI": "GIP", "GH": "GHS", "OM": "OMR", "TN": "TND", "JO": "JOD", "HR": "HRK", "HT": "HTG", "HU": "HUF", "HK": "HKD", "HN": "HNL", "HM": "AUD", "VE": "VEF", "PR": "USD", "PS": "ILS", "PW": "USD", "PT": "EUR", "SJ": "NOK", "PY": "PYG", "IQ": "IQD", "PA": "PAB", "PF": "XPF", "PG": "PGK", "PE": "PEN", "PK": "PKR", "PH": "PHP", "PN": "NZD", "PL": "PLN", "PM": "EUR", "ZM": "ZMK", "EH": "MAD", "EE": "EUR", "EG": "EGP", "ZA": "ZAR", "EC": "USD", "IT": "EUR", "VN": "VND", "SB": "SBD", "ET": "ETB", "SO": "SOS", "ZW": "ZWL", "SA": "SAR", "ES": "EUR", "ER": "ERN", "ME": "EUR", "MD": "MDL", "MG": "MGA", "MF": "EUR", "MA": "MAD", "MC": "EUR", "UZ": "UZS", "MM": "MMK", "ML": "XOF", "MO": "MOP", "MN": "MNT", "MH": "USD", "MK": "MKD", "MU": "MUR", "MT": "EUR", "MW": "MWK", "MV": "MVR", "MQ": "EUR", "MP": "USD", "MS": "XCD", "MR": "MRO", "IM": "GBP", "UG": "UGX", "TZ": "TZS", "MY": "MYR", "MX": "MXN", "IL": "ILS", "FR": "EUR", "IO": "USD", "SH": "SHP", "FI": "EUR", "FJ": "FJD", "FK": "FKP", "FM": "USD", "FO": "DKK", "NI": "NIO", "NL": "EUR", "NO": "NOK", "NA": "NAD", "VU": "VUV", "NC": "XPF", "NE": "XOF", "NF": "AUD", "NG": "NGN", "NZ": "NZD", "NP": "NPR", "NR": "AUD", "NU": "NZD", "CK": "NZD", "XK": "EUR", "CI": "XOF", "CH": "CHF", "CO": "COP", "CN": "CNY", "CM": "XAF", "CL": "CLP", "CC": "AUD", "CA": "CAD", "CG": "XAF", "CF": "XAF", "CD": "CDF", "CZ": "CZK", "CY": "EUR", "CX": "AUD", "CR": "CRC", "CW": "ANG", "CV": "CVE", "CU": "CUP", "SZ": "SZL", "SY": "SYP", "SX": "ANG", "KG": "KGS", "KE": "KES", "SS": "SSP", "SR": "SRD", "KI": "AUD", "KH": "KHR", "KN": "XCD", "KM": "KMF", "ST": "STD", "SK": "EUR", "KR": "KRW", "SI": "EUR", "KP": "KPW", "KW": "KWD", "SN": "XOF", "SM": "EUR", "SL": "SLL", "SC": "SCR", "KZ": "KZT", "KY": "KYD", "SG": "SGD", "SE": "SEK", "SD": "SDG", "DO": "DOP", "DM": "XCD", "DJ": "DJF", "DK": "DKK", "VG": "USD", "DE": "EUR", "YE": "YER", "DZ": "DZD", "US": "USD", "UY": "UYU", "YT": "EUR", "UM": "USD", "LB": "LBP", "LC": "XCD", "LA": "LAK", "TV": "AUD", "TW": "TWD", "TT": "TTD", "TR": "TRY", "LK": "LKR", "LI": "CHF", "LV": "EUR", "TO": "TOP", "LT": "LTL", "LU": "EUR", "LR": "LRD", "LS": "LSL", "TH": "THB", "TF": "EUR", "TG": "XOF", "TD": "XAF", "TC": "USD", "LY": "LYD", "VA": "EUR", "VC": "XCD", "AE": "AED", "AD": "EUR", "AG": "XCD", "AF": "AFN", "AI": "XCD", "VI": "USD", "IS": "ISK", "IR": "IRR", "AM": "AMD", "AL": "ALL", "AO": "AOA", "AQ": "", "AS": "USD", "AR": "ARS", "AU": "AUD", "AT": "EUR", "AW": "AWG", "IN": "INR", "AX": "EUR", "AZ": "AZN", "IE": "EUR", "ID": "IDR", "UA": "UAH", "QA": "QAR", "MZ": "MZN"}; +$(".currencyVal").on("change", function (e) { + console.log("currency selected"); + saveCurrencyLocally(); +}); + +///Get weather for today +function getWeather() { + console.log("getWeather"); + let cityName = $("#cityname").val(); + let queryURL = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=73b47f542215050a64d2b287364ee1d1`; + console.log("weather infor", queryURL); + + let KELVIN = 273.15; + + $.ajax({ + url: queryURL, + success: function (result) { + console.log(result); + + const mainIcon = result.weather[0].icon; + const mainIconLink = + "https://openweathermap.org/img/wn/" + mainIcon + ".png"; + $("#mainIcon").attr("src", mainIconLink); + $(".location").text(result.name); + let C = Math.round(result.main.temp - KELVIN); + let Celsius = C.toString(); + $(".temp").text(Celsius + " \u00B0C"); + $(".humidityNr").text(result.main.humidity + " %"); + $(".windValue").text(result.wind.speed + " MPH"); + + $(".description").text(result.weather[0].description); + }, + }); +} + +function getFiveDayForcast() { + console.log("get forcast"); + let cityName = $("#cityname").val(); + let forcastUrl = `https://api.openweathermap.org/data/2.5/forecast?q=${cityName}&appid=73b47f542215050a64d2b287364ee1d1`; + let KELVIN = 273.15; + + $.ajax({ + url: forcastUrl, + success: function (resultForcast) { + console.log(resultForcast); + + let C = Math.round(resultForcast.list[1].main.temp - KELVIN); + let Celsius = C.toString(); + + const day1Icon = resultForcast.list[1].weather[0].icon; + const day1Link = "https://openweathermap.org/img/wn/" + day1Icon + ".png"; + $(".day1icon").attr("src", day1Link); + $("#tempDay1").text(Celsius + " \u00B0C"); + $("#humidityDay1").text(resultForcast.list[1].main.humidity + " %"); + $("#Date1").text(moment().add(1, "day").format("DD/M/YYYY")); + + //day 2 + + C.toString(); + const day2Icon = resultForcast.list[2].weather[0].icon; + const day2Link = "https://openweathermap.org/img/wn/" + day2Icon + ".png"; + $(".day2icon").attr("src", day2Link); + $("#tempDay2").text(Celsius + " \u00B0C"); + $("#humidityDay2").text(resultForcast.list[2].main.humidity + " %"); + $("#Date2").text(moment().add(2, "day").format("DD/M/YYYY")); + }, + }); +} + +// function saveCurrencyToStorage(){ +// let cityCurrencyValue = $(".country").HTML(); + +// let currency; +// if(localStorage.getItem('currency-searched') === null){ +// currency = []; +// }else{ +// currency = JSON.parse(localStorage.getItem('currency-searched')) +// } +// currency.push(cityCurrencyValue); +// localStorage.setItem('currency-searched', JSON.stringify(currency)); +// } + +function saveCurrencyLocally() { + let currencyObj = { + currencyOne: $("#countryOne").dropdown("get value"), + currencyTwo: $("#countryTwo").dropdown("get value"), + }; + + //currencyOne.push(firstCountry); + localStorage.setItem("currency-searched", JSON.stringify(currencyObj)); +} + +function loadCurrencyLocally() { + const loadCurLocally = JSON.parse(localStorage.getItem("currency-searched")); + console.log("search currency", loadCurLocally); + $("#countryOne").dropdown("set selected", loadCurLocally.currencyOne); + $("#countryTwo").dropdown("set selected", loadCurLocally.currencyTwo); +} + +function saveWeatherToStorage() { + let citySavedNames = $("#cityname").val(); + let cities; + if (localStorage.getItem("input-Cities") === null) { + cities = []; + } else { + cities = JSON.parse(localStorage.getItem("input-Cities")); + } + cities.push(citySavedNames); + localStorage.setItem("input-Cities", JSON.stringify(cities)); +} diff --git a/style/custom.css b/style/custom.css index 11c7f8d..3a39c55 100644 --- a/style/custom.css +++ b/style/custom.css @@ -28,9 +28,7 @@ header { } -.text{ - margin-top: 200px; -} + .ui.weather { font-family: Georgia, 'Times New Roman', Times, serif; @@ -150,7 +148,7 @@ body div h2 span{ border-radius: 15px; } #liveWeatherBtn{ - top: -50px; + top: -50px; border: 0.1px white; border-radius: 15px; } @@ -158,23 +156,34 @@ body div h2 span{ input { border-radius: 25px; } -/* -Moved to allign to the middle section of the page Rk -*/ h4 { font-size: 36px; font-style: inherit; text-align: center; - } -.currencyTitle{ +.currencyTitle { font-family: 'Open Sans', sans-serif!important; font-size: 50px!important; text-transform: uppercase!important; - font-weight: 700!important; - color: lightgray!important; + color: #868a8f!important; +} + +.weatherTitle{ + font-family: 'Open Sans', sans-serif!important; + font-size: 50px!important; + text-transform: uppercase!important; + color: #868a8f!important; +} + + +#currentDayForCurrency{ + text-align: center; + margin: 30px; + font-family: 'Open Sans', sans-serif; + font-size: 1.5rem; + font-weight: 800; } #center-currency{ @@ -186,9 +195,6 @@ h4 { } - - - #liveWeatherBtn{ top: 70px; box-shadow: 1px 1px 10px black; @@ -200,9 +206,9 @@ input { border-radius: 25px; } .weatherBackground{ - - background-color:#B1AFD1; - background-image: url(./assets/images/greece-01.png); + background-image: url(../assets/images/weather-bg.jpg); + background-repeat: no-repeat; + background-size: cover; } i.home .icon{ @@ -237,14 +243,14 @@ i.home .icon{ } .searchTerm:focus{ - color: #00B4CC; + color: #5E5BA5; } .searchButton { width: 40px; height: 36px; - border: 1px solid #00B4CC; - background: #00B4CC; + border: 1px solid #5E5BA5; + background: #5E5BA5; text-align: center; color: #fff; border-radius: 0 5px 5px 0; @@ -252,7 +258,36 @@ i.home .icon{ font-size: 20px; } -/*Resize the wrap to see the search bar change!*/ +.ui.segment.weather{ + height: 220px; + transition: 0.3s ease-in-out; +} + +.ui.segment.weather:hover{ + height: 520px; +} + +.ui.segment.weather .weatherInfo{ + position: relative; + margin-top: -150px; + padding: 10px 15px; + visibility: hidden; + opacity: 0; + transition: 0.3s ease-in-out; +} + +.ui.segment.weather:hover .weatherInfo{ + visibility: visible; + opacity: 1; + margin-top: 10px; + +} + +.ui.segment.weather:hover .hideText{ + display: none; + opacity: 0; +} + .wrap{ width: 30%; position: absolute; @@ -261,25 +296,10 @@ i.home .icon{ transform: translate(-50%, -50%); } -/*.item{ - color: white; - margin-right: 20px; - padding: 0px 10px; - word-wrap: normal; - position: relative; - left: 1350px; - top: 25px; +.location{ + font-family: sans-serif; + font-size: 4rem; } -/* -.logo{ - margin-top: 30px; - width: 100px; - height: 100px; - margin-left: 50px; - border: 2px solid purple; - display: inline-block; -} -*/ .currencyBackground{ background-color: lightgray; @@ -312,24 +332,38 @@ i.home .icon{ width: 200px; } +.ui .search .selection .dropdown{ + width: 200px; +} + #currBg{ - background-image: url(../assets/images/ffinalBGsecond-01.png); + background-image: url(../assets/images/backgroundTwo.jpg); background-size: cover; - + background-attachment: fixed; } + + +.customHeightDropdown{ + height: 25px; +} +.countryHeightDropdown{ + position: relative; + top: 50px; +} + .box{ position: absolute; top: 50%; left:50%; transform: translate(-50%, -50%); width: 200px; - height: 80px; + height: 75px; background: #111845a6; box-sizing: border-box; overflow: hidden; - box-shadow: 0 20px 50px rgb(23, 32, 90); + box-shadow: 0 7px 30px rgb(23, 32, 90); border: 2px solid #2a3cad; color: white; padding: 20px; @@ -383,19 +417,18 @@ i.home .icon{ height: 530px; } - - -.ui.grid .ui.card .imgBx{ - position: relative; - width: 260px; - height: 260px; - top: -60px; - left: 45px; +.dateSize{ + font-size: 15px!important; - z-index: 1; - box-shadow: 1 5px 20px rgba(0,0,0,0.2); } +.location{ + font-size: 40px; + text-transform: uppercase; + color: gray; +} + + .ui.grid.weather .ui.card .imgBx img{ max-width: 100%; border-radius: 4px; @@ -479,6 +512,10 @@ i.home .icon{ cursor: pointer; } +.country{ + color: black!important; +} + @media (max-width: 798px) { .ui.fixed.menu { diff --git a/style/script.js b/style/script.js index 9f9c49c..6db01fb 100644 --- a/style/script.js +++ b/style/script.js @@ -8,9 +8,10 @@ $("#currentDayForCurrency").text(moment().format("dddd do YYYY")); $("#searchBtn").click(function(event) { - console.log('button clicked') + console.log('button ccclicked') getWeather (); getFiveDayForcast (); + saveToStorage(); }); @@ -21,11 +22,31 @@ $("#searchBtn").click(function(event) { let queryURL = `https://api.openweathermap.org/data/2.5/weather?q=${cityName}&appid=73b47f542215050a64d2b287364ee1d1`; console.log('weather infor', queryURL); - let cities = []; - cities.push(cityName); - let cityList = JSON.stringify(cities); - localStorage.setItem( "search-cities" , cityList); - + // let cities = []; + // cities.push(cityName); + // //console.log('my cities', cities); + + // let existingCities = JSON.parse(localStorage.getItem("new-cities")); + // //console.log("previously search", existingCities); + // let concatCities = cities.concat(existingCities); + // console.log("new cities", concatCities); + + // let cityList = JSON.stringify(concatCities); + // console.log("hiya", cityList); + + // localStorage.setItem("new-cities", cityList); + // cities.push(cityName); + // //get item takes one argument + // let existingList = JSON.parse(localStorage.getItem("new-cities")); + // let concatCities = cities.concat(existingList); + // console.log("new city", concatCities); + // let cityList = JSON.stringify(concatCities); + // /// set item takes on two arguments + // localStorage.setItem( "new-cities" , cityList); + + localStorage.clear; + + let KELVIN = 273.15; $.ajax ({ @@ -89,4 +110,21 @@ $("#searchBtn").click(function(event) { $('#tempDay2').text(Celsius + " \u00B0C"); $('#humidityDay2').text(resultForcast.list[2].main.humidity + " %"); $('#Date2').text(moment().add(2, 'day').format("DD/M/YYYY")) + } + }) + } + function saveToStorage(){ + let citySavedNames = $("#cityname").val(); + + let cities; + if(localStorage.getItem('T-Cities') === null){ + cities = []; + }else{ + cities = JSON.parse(localStorage.getItem('T-Cities')) + } + cities.push(citySavedNames); + localStorage.setItem('T-Cities', JSON.stringify(cities)); + } + + \ No newline at end of file