From 7255fa42ceb89e74f6b0b03d4868e6fec9162e39 Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Tue, 28 Mar 2017 14:42:35 +0100 Subject: [PATCH] Version 2.7.7 --- assets/scripts/dist/choices.js | 49 ++++++++++++++++++------------ assets/scripts/dist/choices.js.map | 2 +- assets/scripts/dist/choices.min.js | 6 ++-- bower.json | 2 +- index.html | 6 ++-- package.json | 2 +- 6 files changed, 39 insertions(+), 28 deletions(-) diff --git a/assets/scripts/dist/choices.js b/assets/scripts/dist/choices.js index 4066d70b7..de09ba6ce 100644 --- a/assets/scripts/dist/choices.js +++ b/assets/scripts/dist/choices.js @@ -1,4 +1,4 @@ -/*! choices.js v2.7.6 | (c) 2017 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ +/*! choices.js v2.7.7 | (c) 2017 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); @@ -754,6 +754,7 @@ return /******/ (function(modules) { // webpackBootstrap this.containerOuter.classList.add(this.config.classNames.openState); this.containerOuter.setAttribute('aria-expanded', 'true'); this.dropdown.classList.add(this.config.classNames.activeState); + this.dropdown.setAttribute('aria-expanded', 'true'); var dimensions = this.dropdown.getBoundingClientRect(); var dropdownPos = Math.ceil(dimensions.top + window.scrollY + dimensions.height); @@ -799,6 +800,7 @@ return /******/ (function(modules) { // webpackBootstrap this.containerOuter.classList.remove(this.config.classNames.openState); this.containerOuter.setAttribute('aria-expanded', 'false'); this.dropdown.classList.remove(this.config.classNames.activeState); + this.dropdown.setAttribute('aria-expanded', 'false'); if (isFlipped) { this.containerOuter.classList.remove(this.config.classNames.flippedState); @@ -1204,6 +1206,10 @@ return /******/ (function(modules) { // webpackBootstrap var choice = this.store.getChoiceById(id); var hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState); + (0, _utils.triggerEvent)(this.passedElement, 'choice', { + choice: choice + }); + if (choice && !choice.selected && !choice.disabled) { var canAddItem = this._canAddItem(activeItems, choice.value); @@ -1809,13 +1815,15 @@ return /******/ (function(modules) { // webpackBootstrap value: function _onMouseDown(e) { var target = e.target; if (this.containerOuter.contains(target) && target !== this.input) { + var foundTarget = void 0; var activeItems = this.store.getItemsFilteredByActive(); var hasShiftKey = e.shiftKey; - var foundTarget = void 0; - if (foundTarget = (0, _utils.findAncestorByAttr)(target, 'data-item')) { + if (foundTarget = (0, _utils.findAncestorByAttrName)(target, 'data-button')) { + this._handleButtonAction(activeItems, foundTarget); + } else if (foundTarget = (0, _utils.findAncestorByAttrName)(target, 'data-item')) { this._handleItemAction(activeItems, foundTarget, hasShiftKey); - } else if (foundTarget = (0, _utils.findAncestorByAttr)(target, 'data-choice')) { + } else if (foundTarget = (0, _utils.findAncestorByAttrName)(target, 'data-choice')) { this._handleChoiceAction(activeItems, foundTarget); } @@ -2377,43 +2385,43 @@ return /******/ (function(modules) { // webpackBootstrap var classNames = this.config.classNames; var templates = { containerOuter: function containerOuter(direction) { - return (0, _utils.strToEl)('\n \n '); + return (0, _utils.strToEl)('\n \n '); }, containerInner: function containerInner() { - return (0, _utils.strToEl)('\n
\n '); + return (0, _utils.strToEl)('\n
\n '); }, itemList: function itemList() { - return (0, _utils.strToEl)('\n
\n '); + return (0, _utils.strToEl)('\n
\n '); }, placeholder: function placeholder(value) { - return (0, _utils.strToEl)('\n
' + value + '
\n '); + return (0, _utils.strToEl)('\n
' + value + '
\n '); }, item: function item(data) { if (_this22.config.removeItemButton) { - return (0, _utils.strToEl)('\n
\n ' + data.label + '\n
\n '); + return (0, _utils.strToEl)('\n
\n ' + data.label + '\n
\n '); } - return (0, _utils.strToEl)('\n
\n ' + data.label + '\n
\n '); + return (0, _utils.strToEl)('\n
\n ' + data.label + '\n
\n '); }, choiceList: function choiceList() { - return (0, _utils.strToEl)('\n
\n '); + return (0, _utils.strToEl)('\n
\n '); }, choiceGroup: function choiceGroup(data) { - return (0, _utils.strToEl)('\n
\n
' + data.value + '
\n
\n '); + return (0, _utils.strToEl)('\n
\n
' + data.value + '
\n
\n '); }, choice: function choice(data) { - return (0, _utils.strToEl)('\n
0 ? 'role="treeitem"' : 'role="option"') + '>\n ' + data.label + '\n
\n '); + return (0, _utils.strToEl)('\n
0 ? 'role="treeitem"' : 'role="option"') + '>\n ' + data.label + '\n
\n '); }, input: function input() { - return (0, _utils.strToEl)('\n \n '); + return (0, _utils.strToEl)('\n \n '); }, dropdown: function dropdown() { - return (0, _utils.strToEl)('\n \n '); + return (0, _utils.strToEl)('\n \n '); }, notice: function notice(label) { - return (0, _utils.strToEl)('\n
' + label + '
\n '); + return (0, _utils.strToEl)('\n
' + label + '
\n '); }, option: function option(data) { - return (0, _utils.strToEl)('\n \n '); + return (0, _utils.strToEl)('\n \n '); } }; @@ -2671,7 +2679,10 @@ return /******/ (function(modules) { // webpackBootstrap * @param {!Object} options */ function Fuse (list, options) { + var i + var len var key + var keys this.list = list this.options = options = options || {} @@ -2690,7 +2701,7 @@ return /******/ (function(modules) { // webpackBootstrap } } - Fuse.VERSION = '2.6.2' + Fuse.VERSION = '2.6.0' /** * Sets a new list for Fuse to match against. @@ -5294,7 +5305,7 @@ return /******/ (function(modules) { // webpackBootstrap * @param {string} attr Attribute name of parent * @return {?NodeElement} Found parent element or null */ - var findAncestorByAttr = exports.findAncestorByAttr = function findAncestorByAttr(el, attr) { + var findAncestorByAttrName = exports.findAncestorByAttrName = function findAncestorByAttrName(el, attr) { var target = el; while (target) { diff --git a/assets/scripts/dist/choices.js.map b/assets/scripts/dist/choices.js.map index 65377356b..cd761bb29 100644 --- a/assets/scripts/dist/choices.js.map +++ b/assets/scripts/dist/choices.js.map @@ -1 +1 @@ -{"version":3,"file":"choices.js","sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap c3995e09953402c75410","webpack:///assets/scripts/src/choices.js","webpack:///./~/fuse.js/src/fuse.js","webpack:///assets/scripts/src/store/index.js","webpack:///./~/redux/lib/index.js","webpack:///./~/redux/lib/createStore.js","webpack:///./~/lodash/isPlainObject.js","webpack:///./~/lodash/_baseGetTag.js","webpack:///./~/lodash/_Symbol.js","webpack:///./~/lodash/_root.js","webpack:///./~/lodash/_freeGlobal.js","webpack:///./~/lodash/_getRawTag.js","webpack:///./~/lodash/_objectToString.js","webpack:///./~/lodash/_getPrototype.js","webpack:///./~/lodash/_overArg.js","webpack:///./~/lodash/isObjectLike.js","webpack:///./~/symbol-observable/index.js","webpack:///./~/symbol-observable/lib/index.js","webpack:///(webpack)/buildin/module.js","webpack:///./~/symbol-observable/lib/ponyfill.js","webpack:///./~/redux/lib/combineReducers.js","webpack:///./~/redux/lib/utils/warning.js","webpack:///./~/redux/lib/bindActionCreators.js","webpack:///./~/redux/lib/applyMiddleware.js","webpack:///./~/redux/lib/compose.js","webpack:///assets/scripts/src/reducers/index.js","webpack:///assets/scripts/src/reducers/items.js","webpack:///assets/scripts/src/reducers/groups.js","webpack:///assets/scripts/src/reducers/choices.js","webpack:///assets/scripts/src/actions/index.js","webpack:///assets/scripts/src/lib/utils.js","webpack:///assets/scripts/src/lib/polyfills.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Choices\"] = factory();\n\telse\n\t\troot[\"Choices\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/assets/scripts/dist/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap c3995e09953402c75410","import Fuse from 'fuse.js';\nimport Store from './store/index.js';\nimport {\n addItem,\n removeItem,\n highlightItem,\n addChoice,\n filterChoices,\n activateChoices,\n addGroup,\n clearAll,\n clearChoices,\n}\nfrom './actions/index';\nimport {\n isScrolledIntoView,\n getAdjacentEl,\n wrap,\n getType,\n isType,\n isElement,\n strToEl,\n extend,\n getWidthOfInput,\n sortByAlpha,\n sortByScore,\n triggerEvent,\n findAncestorByAttr\n}\nfrom './lib/utils.js';\nimport './lib/polyfills.js';\n\n\n/**\n * Choices\n */\nclass Choices {\n constructor(element = '[data-choice]', userConfig = {}) {\n // If there are multiple elements, create a new instance\n // for each element besides the first one (as that already has an instance)\n if (isType('String', element)) {\n const elements = document.querySelectorAll(element);\n if (elements.length > 1) {\n for (let i = 1; i < elements.length; i++) {\n const el = elements[i];\n new Choices(el, userConfig);\n }\n }\n }\n\n const defaultConfig = {\n items: [],\n choices: [],\n maxItemCount: -1,\n addItems: true,\n removeItems: true,\n removeItemButton: false,\n editItems: false,\n duplicateItems: true,\n delimiter: ',',\n paste: true,\n search: true,\n searchFloor: 1,\n position: 'auto',\n resetScrollPosition: true,\n regexFilter: null,\n shouldSort: true,\n sortFilter: sortByAlpha,\n sortFields: ['label', 'value'],\n placeholder: true,\n placeholderValue: null,\n prependValue: null,\n appendValue: null,\n loadingText: 'Loading...',\n noResultsText: 'No results found',\n noChoicesText: 'No choices to choose from',\n itemSelectText: 'Press to select',\n addItemText: (value) => {\n return `Press Enter to add \"${value}\"`;\n },\n maxItemText: (maxItemCount) => {\n return `Only ${maxItemCount} values can be added.`;\n },\n uniqueItemText: 'Only unique values can be added.',\n classNames: {\n containerOuter: 'choices',\n containerInner: 'choices__inner',\n input: 'choices__input',\n inputCloned: 'choices__input--cloned',\n list: 'choices__list',\n listItems: 'choices__list--multiple',\n listSingle: 'choices__list--single',\n listDropdown: 'choices__list--dropdown',\n item: 'choices__item',\n itemSelectable: 'choices__item--selectable',\n itemDisabled: 'choices__item--disabled',\n itemChoice: 'choices__item--choice',\n placeholder: 'choices__placeholder',\n group: 'choices__group',\n groupHeading: 'choices__heading',\n button: 'choices__button',\n activeState: 'is-active',\n focusState: 'is-focused',\n openState: 'is-open',\n disabledState: 'is-disabled',\n highlightedState: 'is-highlighted',\n hiddenState: 'is-hidden',\n flippedState: 'is-flipped',\n loadingState: 'is-loading',\n },\n fuseOptions: {\n include: 'score',\n },\n callbackOnInit: null,\n callbackOnCreateTemplates: null,\n };\n\n // Merge options with user options\n this.config = extend(defaultConfig, userConfig);\n\n // Create data store\n this.store = new Store(this.render);\n\n // State tracking\n this.initialised = false;\n this.currentState = {};\n this.prevState = {};\n this.currentValue = '';\n\n // Retrieve triggering element (i.e. element with 'data-choice' trigger)\n this.element = element;\n this.passedElement = isType('String', element) ? document.querySelector(element) : element;\n this.isSelectElement = this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple';\n this.isTextElement = this.passedElement.type === 'text';\n\n if (!this.passedElement) {\n console.error('Passed element not found');\n return;\n }\n\n this.highlightPosition = 0;\n this.canSearch = this.config.search;\n\n // Assing preset choices from passed object\n this.presetChoices = this.config.choices;\n\n // Assign preset items from passed object first\n this.presetItems = this.config.items;\n\n // Then add any values passed from attribute\n if (this.passedElement.value) {\n this.presetItems = this.presetItems.concat(this.passedElement.value.split(this.config.delimiter));\n }\n\n // Bind methods\n this.init = this.init.bind(this);\n this.render = this.render.bind(this);\n this.destroy = this.destroy.bind(this);\n this.disable = this.disable.bind(this);\n\n // Bind event handlers\n this._onFocus = this._onFocus.bind(this);\n this._onBlur = this._onBlur.bind(this);\n this._onKeyUp = this._onKeyUp.bind(this);\n this._onKeyDown = this._onKeyDown.bind(this);\n this._onClick = this._onClick.bind(this);\n this._onTouchMove = this._onTouchMove.bind(this);\n this._onTouchEnd = this._onTouchEnd.bind(this);\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onMouseOver = this._onMouseOver.bind(this);\n this._onPaste = this._onPaste.bind(this);\n this._onInput = this._onInput.bind(this);\n\n // Monitor touch taps/scrolls\n this.wasTap = true;\n\n // Cutting the mustard\n const cuttingTheMustard = 'classList' in document.documentElement;\n if (!cuttingTheMustard) console.error('Choices: Your browser doesn\\'t support Choices');\n\n // Input type check\n const isValidType = ['select-one', 'select-multiple', 'text'].some(type => type === this.passedElement.type);\n const canInit = isElement(this.passedElement) && isValidType;\n\n if (canInit) {\n // If element has already been initalised with Choices\n if (this.passedElement.getAttribute('data-choice') === 'active') return;\n\n // Let's go\n this.init();\n } else {\n console.error('Incompatible input passed');\n }\n }\n\n /*========================================\n = Public functions =\n ========================================*/\n\n /**\n * Initialise Choices\n * @return\n * @public\n */\n init() {\n if (this.initialised === true) return;\n\n const callback = this.config.callbackOnInit;\n\n // Set initialise flag\n this.initialised = true;\n // Create required elements\n this._createTemplates();\n // Generate input markup\n this._createInput();\n // Subscribe store to render method\n this.store.subscribe(this.render);\n // Render any items\n this.render();\n // Trigger event listeners\n this._addEventListeners();\n\n // Run callback if it is a function\n if (callback) {\n if (isType('Function', callback)) {\n callback.call(this);\n }\n }\n }\n\n /**\n * Destroy Choices and nullify values\n * @return\n * @public\n */\n destroy() {\n if (this.initialised === false) return;\n\n // Remove all event listeners\n this._removeEventListeners();\n\n // Reinstate passed element\n this.passedElement.classList.remove(this.config.classNames.input, this.config.classNames.hiddenState);\n this.passedElement.removeAttribute('tabindex');\n this.passedElement.removeAttribute('style', 'display:none;');\n this.passedElement.removeAttribute('aria-hidden');\n this.passedElement.removeAttribute('data-choice', 'active');\n\n // Re-assign values - this is weird, I know\n this.passedElement.value = this.passedElement.value;\n\n // Move passed element back to original position\n this.containerOuter.parentNode.insertBefore(this.passedElement, this.containerOuter);\n // Remove added elements\n this.containerOuter.parentNode.removeChild(this.containerOuter);\n\n // Clear data store\n this.clearStore();\n\n // Nullify instance-specific data\n this.config.templates = null;\n\n // Uninitialise\n this.initialised = false;\n }\n\n /**\n * Render group choices into a DOM fragment and append to choice list\n * @param {Array} groups Groups to add to list\n * @param {Array} choices Choices to add to groups\n * @param {DocumentFragment} fragment Fragment to add groups and options to (optional)\n * @return {DocumentFragment} Populated options fragment\n * @private\n */\n renderGroups(groups, choices, fragment) {\n const groupFragment = fragment || document.createDocumentFragment();\n const filter = this.config.sortFilter;\n\n // If sorting is enabled, filter groups\n if (this.config.shouldSort) {\n groups.sort(filter);\n }\n\n groups.forEach((group) => {\n // Grab options that are children of this group\n const groupChoices = choices.filter((choice) => {\n if (this.passedElement.type === 'select-one') {\n return choice.groupId === group.id;\n }\n return choice.groupId === group.id && !choice.selected;\n });\n\n if (groupChoices.length >= 1) {\n const dropdownGroup = this._getTemplate('choiceGroup', group);\n groupFragment.appendChild(dropdownGroup);\n this.renderChoices(groupChoices, groupFragment);\n }\n });\n\n return groupFragment;\n }\n\n /**\n * Render choices into a DOM fragment and append to choice list\n * @param {Array} choices Choices to add to list\n * @param {DocumentFragment} fragment Fragment to add choices to (optional)\n * @return {DocumentFragment} Populated choices fragment\n * @private\n */\n renderChoices(choices, fragment) {\n // Create a fragment to store our list items (so we don't have to update the DOM for each item)\n const choicesFragment = fragment || document.createDocumentFragment();\n const filter = this.isSearching ? sortByScore : this.config.sortFilter;\n\n // If sorting is enabled or the user is searching, filter choices\n if (this.config.shouldSort || this.isSearching) {\n choices.sort(filter);\n }\n\n choices.forEach((choice) => {\n const dropdownItem = this._getTemplate('choice', choice);\n const shouldRender = this.passedElement.type === 'select-one' || !choice.selected;\n if (shouldRender) {\n choicesFragment.appendChild(dropdownItem);\n }\n });\n\n return choicesFragment;\n }\n\n /**\n * Render items into a DOM fragment and append to items list\n * @param {Array} items Items to add to list\n * @param {DocumentFragment} fragment Fragrment to add items to (optional)\n * @return\n * @private\n */\n renderItems(items, fragment) {\n // Create fragment to add elements to\n const itemListFragment = fragment || document.createDocumentFragment();\n // Simplify store data to just values\n const itemsFiltered = this.store.getItemsReducedToValues(items);\n\n if (this.isTextElement) {\n // Assign hidden input array of values\n this.passedElement.setAttribute('value', itemsFiltered.join(this.config.delimiter));\n } else {\n const selectedOptionsFragment = document.createDocumentFragment();\n\n // Add each list item to list\n items.forEach((item) => {\n // Create a standard select option\n const option = this._getTemplate('option', item);\n // Append it to fragment\n selectedOptionsFragment.appendChild(option);\n });\n\n // Update selected choices\n this.passedElement.innerHTML = '';\n this.passedElement.appendChild(selectedOptionsFragment);\n }\n\n // Add each list item to list\n items.forEach((item) => {\n // Create new list element\n const listItem = this._getTemplate('item', item);\n // Append it to list\n itemListFragment.appendChild(listItem);\n });\n\n return itemListFragment;\n }\n\n /**\n * Render DOM with values\n * @return\n * @private\n */\n render() {\n this.currentState = this.store.getState();\n\n // Only render if our state has actually changed\n if (this.currentState !== this.prevState) {\n // Choices\n if (this.currentState.choices !== this.prevState.choices ||\n this.currentState.groups !== this.prevState.groups) {\n if (this.passedElement.type === 'select-multiple' ||\n this.passedElement.type === 'select-one') {\n // Get active groups/choices\n const activeGroups = this.store.getGroupsFilteredByActive();\n const activeChoices = this.store.getChoicesFilteredByActive();\n\n let choiceListFragment = document.createDocumentFragment();\n\n // Clear choices\n this.choiceList.innerHTML = '';\n\n // Scroll back to top of choices list\n if(this.config.resetScrollPosition){\n this.choiceList.scrollTop = 0;\n }\n\n // If we have grouped options\n if (activeGroups.length >= 1 && this.isSearching !== true) {\n choiceListFragment = this.renderGroups(activeGroups, activeChoices, choiceListFragment);\n } else if (activeChoices.length >= 1) {\n choiceListFragment = this.renderChoices(activeChoices, choiceListFragment);\n }\n\n if (choiceListFragment.childNodes && choiceListFragment.childNodes.length > 0) {\n // If we actually have anything to add to our dropdown\n // append it and highlight the first choice\n this.choiceList.appendChild(choiceListFragment);\n this._highlightChoice();\n } else {\n // Otherwise show a notice\n let dropdownItem;\n let notice;\n\n if (this.isSearching) {\n notice = isType('Function', this.config.noResultsText) ? this.config.noResultsText() : this.config.noResultsText;\n dropdownItem = this._getTemplate('notice', notice);\n } else {\n notice = isType('Function', this.config.noChoicesText) ? this.config.noChoicesText() : this.config.noChoicesText;\n dropdownItem = this._getTemplate('notice', notice);\n }\n\n this.choiceList.appendChild(dropdownItem);\n }\n }\n }\n\n // Items\n if (this.currentState.items !== this.prevState.items) {\n const activeItems = this.store.getItemsFilteredByActive();\n if (activeItems) {\n // Create a fragment to store our list items\n // (so we don't have to update the DOM for each item)\n const itemListFragment = this.renderItems(activeItems);\n\n // Clear list\n this.itemList.innerHTML = '';\n\n // If we have items to add\n if (itemListFragment.childNodes) {\n // Update list\n this.itemList.appendChild(itemListFragment);\n }\n }\n }\n\n this.prevState = this.currentState;\n }\n }\n\n /**\n * Select item (a selected item can be deleted)\n * @param {Element} item Element to select\n * @return {Object} Class instance\n * @public\n */\n highlightItem(item, runEvent = true) {\n if (!item) return;\n const id = item.id;\n const groupId = item.groupId;\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n this.store.dispatch(highlightItem(id, true));\n\n if (runEvent) {\n if(group && group.value) {\n triggerEvent(this.passedElement, 'highlightItem', {\n id,\n value: item.value,\n label: item.label,\n groupValue: group.value\n });\n } else {\n triggerEvent(this.passedElement, 'highlightItem', {\n id,\n value: item.value,\n label: item.label,\n });\n }\n }\n\n return this;\n }\n\n /**\n * Deselect item\n * @param {Element} item Element to de-select\n * @return {Object} Class instance\n * @public\n */\n unhighlightItem(item) {\n if (!item) return;\n const id = item.id;\n const groupId = item.groupId;\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n this.store.dispatch(highlightItem(id, false));\n\n if(group && group.value) {\n triggerEvent(this.passedElement, 'unhighlightItem', {\n id,\n value: item.value,\n label: item.label,\n groupValue: group.value\n });\n } else {\n triggerEvent(this.passedElement, 'unhighlightItem', {\n id,\n value: item.value,\n label: item.label,\n });\n }\n\n return this;\n }\n\n /**\n * Highlight items within store\n * @return {Object} Class instance\n * @public\n */\n highlightAll() {\n const items = this.store.getItems();\n items.forEach((item) => {\n this.highlightItem(item);\n });\n\n return this;\n }\n\n /**\n * Deselect items within store\n * @return {Object} Class instance\n * @public\n */\n unhighlightAll() {\n const items = this.store.getItems();\n items.forEach((item) => {\n this.unhighlightItem(item);\n });\n\n return this;\n }\n\n /**\n * Remove an item from the store by its value\n * @param {String} value Value to search for\n * @return {Object} Class instance\n * @public\n */\n removeItemsByValue(value) {\n if (!value || !isType('String', value)) {\n console.error('removeItemsByValue: No value was passed to be removed');\n return;\n }\n\n const items = this.store.getItemsFilteredByActive();\n\n items.forEach((item) => {\n if (item.value === value) {\n this._removeItem(item);\n }\n });\n\n return this;\n }\n\n /**\n * Remove all items from store array\n * @note Removed items are soft deleted\n * @param {Number} excludedId Optionally exclude item by ID\n * @return {Object} Class instance\n * @public\n */\n removeActiveItems(excludedId) {\n const items = this.store.getItemsFilteredByActive();\n\n items.forEach((item) => {\n if (item.active && excludedId !== item.id) {\n this._removeItem(item);\n }\n });\n\n return this;\n }\n\n /**\n * Remove all selected items from store\n * @note Removed items are soft deleted\n * @return {Object} Class instance\n * @public\n */\n removeHighlightedItems(runEvent = false) {\n const items = this.store.getItemsFilteredByActive();\n\n items.forEach((item) => {\n if (item.highlighted && item.active) {\n this._removeItem(item);\n // If this action was performed by the user\n // trigger the event\n if (runEvent) {\n this._triggerChange(item.value);\n }\n }\n });\n\n return this;\n }\n\n /**\n * Show dropdown to user by adding active state class\n * @return {Object} Class instance\n * @public\n */\n showDropdown(focusInput = false) {\n const body = document.body;\n const html = document.documentElement;\n const winHeight = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n this.containerOuter.classList.add(this.config.classNames.openState);\n this.containerOuter.setAttribute('aria-expanded', 'true');\n this.dropdown.classList.add(this.config.classNames.activeState);\n\n const dimensions = this.dropdown.getBoundingClientRect();\n const dropdownPos = Math.ceil(dimensions.top + window.scrollY + dimensions.height);\n\n // If flip is enabled and the dropdown bottom position is greater than the window height flip the dropdown.\n let shouldFlip = false;\n if (this.config.position === 'auto') {\n shouldFlip = dropdownPos >= winHeight;\n } else if (this.config.position === 'top') {\n shouldFlip = true;\n }\n\n if (shouldFlip) {\n this.containerOuter.classList.add(this.config.classNames.flippedState);\n } else {\n this.containerOuter.classList.remove(this.config.classNames.flippedState);\n }\n\n // Optionally focus the input if we have a search input\n if (focusInput && this.canSearch && document.activeElement !== this.input) {\n this.input.focus();\n }\n\n triggerEvent(this.passedElement, 'showDropdown', {});\n\n return this;\n }\n\n /**\n * Hide dropdown from user\n * @return {Object} Class instance\n * @public\n */\n hideDropdown(blurInput = false) {\n // A dropdown flips if it does not have space within the page\n const isFlipped = this.containerOuter.classList.contains(this.config.classNames.flippedState);\n\n this.containerOuter.classList.remove(this.config.classNames.openState);\n this.containerOuter.setAttribute('aria-expanded', 'false');\n this.dropdown.classList.remove(this.config.classNames.activeState);\n\n if (isFlipped) {\n this.containerOuter.classList.remove(this.config.classNames.flippedState);\n }\n\n // Optionally blur the input if we have a search input\n if (blurInput && this.canSearch && document.activeElement === this.input) {\n this.input.blur();\n }\n\n triggerEvent(this.passedElement, 'hideDropdown', {});\n\n return this;\n }\n\n /**\n * Determine whether to hide or show dropdown based on its current state\n * @return {Object} Class instance\n * @public\n */\n toggleDropdown() {\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n if (hasActiveDropdown) {\n this.hideDropdown();\n } else {\n this.showDropdown(true);\n }\n\n return this;\n }\n\n /**\n * Get value(s) of input (i.e. inputted items (text) or selected choices (select))\n * @param {Boolean} valueOnly Get only values of selected items, otherwise return selected items\n * @return {Array/String} selected value (select-one) or array of selected items (inputs & select-multiple)\n * @public\n */\n getValue(valueOnly = false) {\n const items = this.store.getItemsFilteredByActive();\n const selectedItems = [];\n\n items.forEach((item) => {\n if (this.isTextElement) {\n selectedItems.push(valueOnly ? item.value : item);\n } else if (item.active) {\n selectedItems.push(valueOnly ? item.value : item);\n }\n });\n\n if (this.passedElement.type === 'select-one') {\n return selectedItems[0];\n }\n\n return selectedItems;\n }\n\n /**\n * Set value of input. If the input is a select box, a choice will be created and selected otherwise\n * an item will created directly.\n * @param {Array} args Array of value objects or value strings\n * @return {Object} Class instance\n * @public\n */\n setValue(args) {\n if (this.initialised === true) {\n // Convert args to an iterable array\n const values = [...args],\n passedElementType = this.passedElement.type,\n handleValue = (item) => {\n const itemType = getType(item);\n if (itemType === 'Object') {\n if (!item.value) return;\n // If we are dealing with a select input, we need to create an option first\n // that is then selected. For text inputs we can just add items normally.\n if (passedElementType !== 'text') {\n this._addChoice(true, false, item.value, item.label, -1);\n } else {\n this._addItem(item.value, item.label, item.id);\n }\n } else if (itemType === 'String') {\n if (passedElementType !== 'text') {\n this._addChoice(true, false, item, item, -1);\n } else {\n this._addItem(item);\n }\n }\n };\n\n if (values.length > 1) {\n values.forEach((value) => {\n handleValue(value);\n });\n } else {\n handleValue(values[0]);\n }\n }\n return this;\n }\n\n /**\n * Select value of select box via the value of an existing choice\n * @param {Array/String} value An array of strings of a single string\n * @return {Object} Class instance\n * @public\n */\n setValueByChoice(value) {\n if (this.passedElement.type !== 'text') {\n const choices = this.store.getChoices();\n // If only one value has been passed, convert to array\n const choiceValue = isType('Array', value) ? value : [value];\n\n // Loop through each value and\n choiceValue.forEach((val) => {\n const foundChoice = choices.find((choice) => {\n // Check 'value' property exists and the choice isn't already selected\n return choice.value === val;\n });\n\n if (foundChoice) {\n if (!foundChoice.selected) {\n this._addItem(foundChoice.value, foundChoice.label, foundChoice.id, foundChoice.groupId);\n } else {\n console.warn('Attempting to select choice already selected');\n }\n } else {\n console.warn('Attempting to select choice that does not exist');\n }\n });\n }\n return this;\n }\n\n /**\n * Direct populate choices\n * @param {Array} choices - Choices to insert\n * @param {String} value - Name of 'value' property\n * @param {String} label - Name of 'label' property\n * @param {Boolean} replaceChoices Whether existing choices should be removed\n * @return {Object} Class instance\n * @public\n */\n setChoices(choices, value, label, replaceChoices = false) {\n if (this.initialised === true) {\n if (this.isSelectElement) {\n if (!isType('Array', choices) || !value) return;\n // Clear choices if needed\n if(replaceChoices) {\n this._clearChoices();\n }\n // Add choices if passed\n if (choices && choices.length) {\n this.containerOuter.classList.remove(this.config.classNames.loadingState);\n choices.forEach((result, index) => {\n const isSelected = result.selected ? result.selected : false;\n const isDisabled = result.disabled ? result.disabled : false;\n if (result.choices) {\n this._addGroup(result, (result.id || null), value, label);\n } else {\n this._addChoice(isSelected, isDisabled, result[value], result[label]);\n }\n });\n }\n }\n }\n return this;\n }\n\n /**\n * Clear items,choices and groups\n * @note Hard delete\n * @return {Object} Class instance\n * @public\n */\n clearStore() {\n this.store.dispatch(clearAll());\n return this;\n }\n\n /**\n * Set value of input to blank\n * @return {Object} Class instance\n * @public\n */\n clearInput() {\n if (this.input.value) this.input.value = '';\n if (this.passedElement.type !== 'select-one') {\n this._setInputWidth();\n }\n if (this.passedElement.type !== 'text' && this.config.search) {\n this.isSearching = false;\n this.store.dispatch(activateChoices(true));\n }\n return this;\n }\n\n /**\n * Enable interaction with Choices\n * @return {Object} Class instance\n */\n enable() {\n this.passedElement.disabled = false;\n const isDisabled = this.containerOuter.classList.contains(this.config.classNames.disabledState);\n if (this.initialised && isDisabled) {\n this._addEventListeners();\n this.passedElement.removeAttribute('disabled');\n this.input.removeAttribute('disabled');\n this.containerOuter.classList.remove(this.config.classNames.disabledState);\n this.containerOuter.removeAttribute('aria-disabled');\n }\n return this;\n }\n\n /**\n * Disable interaction with Choices\n * @return {Object} Class instance\n * @public\n */\n disable() {\n this.passedElement.disabled = true;\n const isEnabled = !this.containerOuter.classList.contains(this.config.classNames.disabledState);\n if (this.initialised && isEnabled) {\n this._removeEventListeners();\n this.passedElement.setAttribute('disabled', '');\n this.input.setAttribute('disabled', '');\n this.containerOuter.classList.add(this.config.classNames.disabledState);\n this.containerOuter.setAttribute('aria-disabled', 'true');\n }\n return this;\n }\n\n /**\n * Populate options via ajax callback\n * @param {Function} fn Passed\n * @return {Object} Class instance\n * @public\n */\n ajax(fn) {\n if (this.initialised === true) {\n if (this.isSelectElement) {\n // Show loading text\n this._handleLoadingState(true);\n // Run callback\n fn(this._ajaxCallback());\n }\n }\n return this;\n }\n\n /*===== End of Public functions ======*/\n\n /*=============================================\n = Private functions =\n =============================================*/\n\n /**\n * Call change callback\n * @param {String} value - last added/deleted/selected value\n * @return\n * @private\n */\n _triggerChange(value) {\n if (!value) return;\n\n triggerEvent(this.passedElement, 'change', {\n value\n });\n }\n\n /**\n * Process enter/click of an item button\n * @param {Array} activeItems The currently active items\n * @param {Element} element Button being interacted with\n * @return\n * @private\n */\n _handleButtonAction(activeItems, element) {\n if (!activeItems || !element) return;\n\n // If we are clicking on a button\n if (this.config.removeItems && this.config.removeItemButton) {\n const itemId = element.parentNode.getAttribute('data-id');\n const itemToRemove = activeItems.find((item) => item.id === parseInt(itemId, 10));\n\n // Remove item associated with button\n this._removeItem(itemToRemove);\n this._triggerChange(itemToRemove.value);\n\n if (this.passedElement.type === 'select-one') {\n const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') :\n false;\n if (placeholder) {\n const placeholderItem = this._getTemplate('placeholder', placeholder);\n this.itemList.appendChild(placeholderItem);\n }\n }\n }\n }\n\n /**\n * Process click of an item\n * @param {Array} activeItems The currently active items\n * @param {Element} element Item being interacted with\n * @param {Boolean} hasShiftKey Whether the user has the shift key active\n * @return\n * @private\n */\n _handleItemAction(activeItems, element, hasShiftKey = false) {\n if (!activeItems || !element) return;\n\n // If we are clicking on an item\n if (this.config.removeItems && this.passedElement.type !== 'select-one') {\n const passedId = element.getAttribute('data-id');\n\n // We only want to select one item with a click\n // so we deselect any items that aren't the target\n // unless shift is being pressed\n activeItems.forEach((item) => {\n if (item.id === parseInt(passedId, 10) && !item.highlighted) {\n this.highlightItem(item);\n } else if (!hasShiftKey) {\n if (item.highlighted) {\n this.unhighlightItem(item);\n }\n }\n });\n\n // Focus input as without focus, a user cannot do anything with a\n // highlighted item\n if (document.activeElement !== this.input) this.input.focus();\n }\n }\n\n /**\n * Process click of a choice\n * @param {Array} activeItems The currently active items\n * @param {Element} element Choice being interacted with\n * @return {[type]} [description]\n */\n _handleChoiceAction(activeItems, element) {\n if (!activeItems || !element) return;\n\n // If we are clicking on an option\n const id = element.getAttribute('data-id');\n const choice = this.store.getChoiceById(id);\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n\n if (choice && !choice.selected && !choice.disabled) {\n const canAddItem = this._canAddItem(activeItems, choice.value);\n\n if (canAddItem.response) {\n this._addItem(choice.value, choice.label, choice.id, choice.groupId);\n this._triggerChange(choice.value);\n }\n }\n\n this.clearInput(this.passedElement);\n\n // We wont to close the dropdown if we are dealing with a single select box\n if (hasActiveDropdown && this.passedElement.type === 'select-one') {\n this.hideDropdown();\n this.containerOuter.focus();\n }\n }\n\n /**\n * Process back space event\n * @param {Array} activeItems items\n * @return\n * @private\n */\n _handleBackspace(activeItems) {\n if (this.config.removeItems && activeItems) {\n const lastItem = activeItems[activeItems.length - 1];\n const hasHighlightedItems = activeItems.some((item) => item.highlighted === true);\n\n // If editing the last item is allowed and there are not other selected items,\n // we can edit the item value. Otherwise if we can remove items, remove all selected items\n if (this.config.editItems && !hasHighlightedItems && lastItem) {\n this.input.value = lastItem.value;\n this._setInputWidth();\n this._removeItem(lastItem);\n this._triggerChange(lastItem.value);\n } else {\n if (!hasHighlightedItems) {\n this.highlightItem(lastItem, false);\n }\n this.removeHighlightedItems(true);\n }\n }\n }\n\n /**\n * Validates whether an item can be added by a user\n * @param {Array} activeItems The currently active items\n * @param {String} value Value of item to add\n * @return {Object} Response: Whether user can add item\n * Notice: Notice show in dropdown\n */\n _canAddItem(activeItems, value) {\n let canAddItem = true;\n let notice = isType('Function', this.config.addItemText) ? this.config.addItemText(value) : this.config.addItemText;\n\n if (this.passedElement.type === 'select-multiple' || this.passedElement.type === 'text') {\n if (this.config.maxItemCount > 0 && this.config.maxItemCount <= this.itemList.children.length) {\n // If there is a max entry limit and we have reached that limit\n // don't update\n canAddItem = false;\n notice = isType('Function', this.config.maxItemText) ? this.config.maxItemText(this.config.maxItemCount) : this.config.maxItemText;\n }\n }\n\n if (this.passedElement.type === 'text' && this.config.addItems) {\n const isUnique = !activeItems.some((item) => item.value === value.trim());\n\n // If a user has supplied a regular expression filter\n if (this.config.regexFilter) {\n // Determine whether we can update based on whether\n // our regular expression passes\n canAddItem = this._regexFilter(value);\n }\n\n // If no duplicates are allowed, and the value already exists\n // in the array\n if (this.config.duplicateItems === false && !isUnique) {\n canAddItem = false;\n notice = isType('Function', this.config.uniqueItemText) ? this.config.uniqueItemText(value) : this.config.uniqueItemText;\n }\n }\n\n return {\n response: canAddItem,\n notice,\n };\n }\n\n /**\n * Apply or remove a loading state to the component.\n * @param {Boolean} isLoading default value set to 'true'.\n * @return\n * @private\n */\n _handleLoadingState(isLoading = true) {\n let placeholderItem = this.itemList.querySelector(`.${this.config.classNames.placeholder}`);\n if(isLoading) {\n this.containerOuter.classList.add(this.config.classNames.loadingState);\n this.containerOuter.setAttribute('aria-busy', 'true');\n if (this.passedElement.type === 'select-one') {\n if (!placeholderItem) {\n placeholderItem = this._getTemplate('placeholder', this.config.loadingText);\n this.itemList.appendChild(placeholderItem);\n } else {\n placeholderItem.innerHTML = this.config.loadingText;\n }\n } else {\n this.input.placeholder = this.config.loadingText;\n }\n } else {\n // Remove loading states/text\n this.containerOuter.classList.remove(this.config.classNames.loadingState);\n const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : false;\n if (this.passedElement.type === 'select-one') {\n placeholderItem.innerHTML = placeholder || '';\n } else {\n this.input.placeholder = placeholder || '';\n }\n }\n }\n\n /**\n * Retrieve the callback used to populate component's choices in an async way.\n * @returns {Function} The callback as a function.\n * @private\n */\n _ajaxCallback() {\n return (results, value, label) => {\n if (!results || !value) return;\n\n const parsedResults = isType('Object', results) ? [results] : results;\n\n if (parsedResults && isType('Array', parsedResults) && parsedResults.length) {\n // Remove loading states/text\n this._handleLoadingState(false);\n // Add each result as a choice\n parsedResults.forEach((result, index) => {\n const isSelected = result.selected ? result.selected : false;\n const isDisabled = result.disabled ? result.disabled : false;\n if (result.choices) {\n this._addGroup(result, (result.id || null), value, label);\n } else {\n this._addChoice(isSelected, isDisabled, result[value], result[label]);\n }\n });\n } else {\n // No results, remove loading state\n this._handleLoadingState(false);\n }\n\n this.containerOuter.removeAttribute('aria-busy');\n };\n }\n\n /**\n * Filter choices based on search value\n * @param {String} value Value to filter by\n * @return\n * @private\n */\n _searchChoices(value) {\n const newValue = isType('String', value) ? value.trim() : value;\n const currentValue = isType('String', this.currentValue) ? this.currentValue.trim() : this.currentValue;\n\n // If new value matches the desired length and is not the same as the current value with a space\n if (newValue.length >= 1 && newValue !== `${currentValue} `) {\n const haystack = this.store.getChoicesFilteredBySelectable();\n const needle = newValue;\n const keys = isType('Array', this.config.sortFields) ? this.config.sortFields : [this.config.sortFields];\n const options = Object.assign(this.config.fuseOptions, { keys });\n const fuse = new Fuse(haystack, options);\n const results = fuse.search(needle);\n\n this.currentValue = newValue;\n this.highlightPosition = 0;\n this.isSearching = true;\n this.store.dispatch(filterChoices(results));\n }\n }\n\n /**\n * Determine the action when a user is searching\n * @param {String} value Value entered by user\n * @return\n * @private\n */\n _handleSearch(value) {\n if (!value) return;\n const choices = this.store.getChoices();\n const hasUnactiveChoices = choices.some((option) => option.active !== true);\n\n // Run callback if it is a function\n if (this.input === document.activeElement) {\n // Check that we have a value to search and the input was an alphanumeric character\n if (value && value.length > this.config.searchFloor) {\n // Filter available choices\n this._searchChoices(value);\n // Trigger search event\n triggerEvent(this.passedElement, 'search', {\n value,\n });\n } else if (hasUnactiveChoices) {\n // Otherwise reset choices to active\n this.isSearching = false;\n this.store.dispatch(activateChoices(true));\n }\n }\n }\n\n /**\n * Trigger event listeners\n * @return\n * @private\n */\n _addEventListeners() {\n document.addEventListener('keyup', this._onKeyUp);\n document.addEventListener('keydown', this._onKeyDown);\n document.addEventListener('click', this._onClick);\n document.addEventListener('touchmove', this._onTouchMove);\n document.addEventListener('touchend', this._onTouchEnd);\n document.addEventListener('mousedown', this._onMouseDown);\n document.addEventListener('mouseover', this._onMouseOver);\n\n if (this.passedElement.type && this.passedElement.type === 'select-one') {\n this.containerOuter.addEventListener('focus', this._onFocus);\n this.containerOuter.addEventListener('blur', this._onBlur);\n }\n\n this.input.addEventListener('input', this._onInput);\n this.input.addEventListener('paste', this._onPaste);\n this.input.addEventListener('focus', this._onFocus);\n this.input.addEventListener('blur', this._onBlur);\n }\n\n /**\n * Remove event listeners\n * @return\n * @private\n */\n _removeEventListeners() {\n document.removeEventListener('keyup', this._onKeyUp);\n document.removeEventListener('keydown', this._onKeyDown);\n document.removeEventListener('click', this._onClick);\n document.removeEventListener('touchmove', this._onTouchMove);\n document.removeEventListener('touchend', this._onTouchEnd);\n document.removeEventListener('mousedown', this._onMouseDown);\n document.removeEventListener('mouseover', this._onMouseOver);\n\n if (this.passedElement.type && this.passedElement.type === 'select-one') {\n this.containerOuter.removeEventListener('focus', this._onFocus);\n this.containerOuter.removeEventListener('blur', this._onBlur);\n }\n\n this.input.removeEventListener('input', this._onInput);\n this.input.removeEventListener('paste', this._onPaste);\n this.input.removeEventListener('focus', this._onFocus);\n this.input.removeEventListener('blur', this._onBlur);\n }\n\n /**\n * Set the correct input width based on placeholder\n * value or input value\n * @return\n */\n _setInputWidth() {\n if (this.config.placeholder && (this.config.placeholderValue || this.passedElement.getAttribute('placeholder'))) {\n // If there is a placeholder, we only want to set the width of the input when it is a greater\n // length than 75% of the placeholder. This stops the input jumping around.\n const placeholder = this.config.placeholder ? this.config.placeholderValue ||\n this.passedElement.getAttribute('placeholder') : false;\n if (this.input.value && this.input.value.length >= (placeholder.length / 1.25)) {\n this.input.style.width = getWidthOfInput(this.input);\n }\n } else {\n // If there is no placeholder, resize input to contents\n this.input.style.width = getWidthOfInput(this.input);\n }\n }\n\n /**\n * Key down event\n * @param {Object} e Event\n * @return\n */\n _onKeyDown(e) {\n if (e.target !== this.input && !this.containerOuter.contains(e.target)) return;\n\n const target = e.target;\n const passedElementType = this.passedElement.type;\n const activeItems = this.store.getItemsFilteredByActive();\n const hasFocusedInput = this.input === document.activeElement;\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const hasItems = this.itemList && this.itemList.children;\n const keyString = String.fromCharCode(e.keyCode);\n\n const backKey = 46;\n const deleteKey = 8;\n const enterKey = 13;\n const aKey = 65;\n const escapeKey = 27;\n const upKey = 38;\n const downKey = 40;\n const pageUpKey = 33;\n const pageDownKey = 34;\n const ctrlDownKey = e.ctrlKey || e.metaKey;\n\n // If a user is typing and the dropdown is not active\n if (passedElementType !== 'text' && /[a-zA-Z0-9-_ ]/.test(keyString) && !hasActiveDropdown) {\n this.showDropdown(true);\n }\n\n this.canSearch = this.config.search;\n\n const onAKey = () => {\n // If CTRL + A or CMD + A have been pressed and there are items to select\n if (ctrlDownKey && hasItems) {\n this.canSearch = false;\n if (this.config.removeItems && !this.input.value && this.input === document.activeElement) {\n // Highlight items\n this.highlightAll(this.itemList.children);\n }\n }\n };\n\n const onEnterKey = () => {\n // If enter key is pressed and the input has a value\n if (passedElementType === 'text' && target.value) {\n const value = this.input.value;\n const canAddItem = this._canAddItem(activeItems, value);\n\n // All is good, add\n if (canAddItem.response) {\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n this._addItem(value);\n this._triggerChange(value);\n this.clearInput(this.passedElement);\n }\n }\n\n if (target.hasAttribute('data-button')) {\n this._handleButtonAction(activeItems, target);\n e.preventDefault();\n }\n\n if (hasActiveDropdown) {\n e.preventDefault();\n const highlighted = this.dropdown.querySelector(`.${this.config.classNames.highlightedState}`);\n\n // If we have a highlighted choice\n if (highlighted) {\n this._handleChoiceAction(activeItems, highlighted);\n }\n\n } else if (passedElementType === 'select-one') {\n // Open single select dropdown if it's not active\n if (!hasActiveDropdown) {\n this.showDropdown(true);\n e.preventDefault();\n }\n }\n };\n\n const onEscapeKey = () => {\n if (hasActiveDropdown) {\n this.toggleDropdown();\n }\n };\n\n const onDirectionKey = () => {\n // If up or down key is pressed, traverse through options\n if (hasActiveDropdown || passedElementType === 'select-one') {\n // Show dropdown if focus\n if (!hasActiveDropdown) {\n this.showDropdown(true);\n }\n\n this.canSearch = false;\n\n const directionInt = e.keyCode === downKey || e.keyCode === pageDownKey ? 1 : -1;\n const skipKey = e.metaKey || e.keyCode === pageDownKey || e.keyCode === pageUpKey;\n\n let nextEl;\n if (skipKey) {\n if (directionInt > 0) {\n nextEl = Array.from(this.dropdown.querySelectorAll('[data-choice-selectable]')).pop();\n } else {\n nextEl = this.dropdown.querySelector('[data-choice-selectable]');\n }\n } else {\n const currentEl = this.dropdown.querySelector(`.${this.config.classNames.highlightedState}`);\n if (currentEl) {\n nextEl = getAdjacentEl(currentEl, '[data-choice-selectable]', directionInt);\n } else {\n nextEl = this.dropdown.querySelector('[data-choice-selectable]');\n }\n }\n\n if (nextEl) {\n // We prevent default to stop the cursor moving\n // when pressing the arrow\n if (!isScrolledIntoView(nextEl, this.choiceList, directionInt)) {\n this._scrollToChoice(nextEl, directionInt);\n }\n this._highlightChoice(nextEl);\n }\n\n // Prevent default to maintain cursor position whilst\n // traversing dropdown options\n e.preventDefault();\n }\n };\n\n const onDeleteKey = () => {\n // If backspace or delete key is pressed and the input has no value\n if (hasFocusedInput && !e.target.value && passedElementType !== 'select-one') {\n this._handleBackspace(activeItems);\n e.preventDefault();\n }\n };\n\n // Map keys to key actions\n const keyDownActions = {\n [aKey]: onAKey,\n [enterKey]: onEnterKey,\n [escapeKey]: onEscapeKey,\n [upKey]: onDirectionKey,\n [pageUpKey]: onDirectionKey,\n [downKey]: onDirectionKey,\n [pageDownKey]: onDirectionKey,\n [deleteKey]: onDeleteKey,\n [backKey]: onDeleteKey,\n };\n\n // If keycode has a function, run it\n if (keyDownActions[e.keyCode]) {\n keyDownActions[e.keyCode]();\n }\n }\n\n /**\n * Key up event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onKeyUp(e) {\n if (e.target !== this.input) return;\n\n // We are typing into a text input and have a value, we want to show a dropdown\n // notice. Otherwise hide the dropdown\n if (this.isTextElement) {\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const value = this.input.value;\n\n if (value) {\n const activeItems = this.store.getItemsFilteredByActive();\n const canAddItem = this._canAddItem(activeItems, value);\n\n if (canAddItem.notice) {\n const dropdownItem = this._getTemplate('notice', canAddItem.notice);\n this.dropdown.innerHTML = dropdownItem.outerHTML;\n }\n\n if (canAddItem.response === true) {\n if (!hasActiveDropdown) {\n this.showDropdown();\n }\n } else if (!canAddItem.notice && hasActiveDropdown) {\n this.hideDropdown();\n }\n } else if (hasActiveDropdown) {\n this.hideDropdown();\n }\n } else {\n const backKey = 46;\n const deleteKey = 8;\n\n // If user has removed value...\n if ((e.keyCode === backKey || e.keyCode === deleteKey) && !e.target.value) {\n // ...and it is a multiple select input, activate choices (if searching)\n if (this.passedElement.type !== 'text' && this.isSearching) {\n this.isSearching = false;\n this.store.dispatch(activateChoices(true));\n }\n } else if (this.canSearch) {\n this._handleSearch(this.input.value);\n }\n }\n }\n\n /**\n * Input event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onInput() {\n if (this.passedElement.type !== 'select-one') {\n this._setInputWidth();\n }\n }\n\n /**\n * Touch move event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onTouchMove() {\n if (this.wasTap === true) {\n this.wasTap = false;\n }\n }\n\n /**\n * Touch end event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onTouchEnd(e) {\n const target = e.target || e.touches[0].target;\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n\n // If a user tapped within our container...\n if (this.wasTap === true && this.containerOuter.contains(target)) {\n // ...and we aren't dealing with a single select box, show dropdown/focus input\n if ((target === this.containerOuter || target === this.containerInner) && this.passedElement.type !== 'select-one') {\n if (this.isTextElement) {\n // If text element, we only want to focus the input (if it isn't already)\n if (document.activeElement !== this.input) {\n this.input.focus();\n }\n } else {\n if (!hasActiveDropdown) {\n // If a select box, we want to show the dropdown\n this.showDropdown(true);\n }\n }\n }\n // Prevents focus event firing\n e.stopPropagation();\n }\n\n this.wasTap = true;\n }\n\n /**\n * Mouse down event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onMouseDown(e) {\n let target = e.target;\n if (this.containerOuter.contains(target) && target !== this.input) {\n const activeItems = this.store.getItemsFilteredByActive();\n const hasShiftKey = e.shiftKey;\n let foundTarget;\n\n if (foundTarget = findAncestorByAttr(target, 'data-item')) {\n this._handleItemAction(activeItems, foundTarget, hasShiftKey);\n } else if (foundTarget = findAncestorByAttr(target, 'data-choice')) {\n this._handleChoiceAction(activeItems, foundTarget);\n }\n\n e.preventDefault();\n }\n }\n\n /**\n * Click event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onClick(e) {\n const target = e.target;\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const activeItems = this.store.getItemsFilteredByActive();\n\n // If target is something that concerns us\n if (this.containerOuter.contains(target)) {\n // Handle button delete\n if (target.hasAttribute('data-button')) {\n this._handleButtonAction(activeItems, target);\n }\n\n if (!hasActiveDropdown) {\n if (this.isTextElement) {\n if (document.activeElement !== this.input) {\n this.input.focus();\n }\n } else {\n if (this.canSearch) {\n this.showDropdown(true);\n } else {\n this.showDropdown();\n this.containerOuter.focus();\n }\n }\n } else if (this.passedElement.type === 'select-one' && target !== this.input && !this.dropdown.contains(target)) {\n this.hideDropdown(true);\n }\n } else {\n const hasHighlightedItems = activeItems.some((item) => item.highlighted === true);\n\n // De-select any highlighted items\n if (hasHighlightedItems) {\n this.unhighlightAll();\n }\n\n // Remove focus state\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n\n // Close all other dropdowns\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n }\n }\n\n /**\n * Mouse over (hover) event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onMouseOver(e) {\n // If the dropdown is either the target or one of its children is the target\n if (e.target === this.dropdown || this.dropdown.contains(e.target)) {\n if (e.target.hasAttribute('data-choice')) this._highlightChoice(e.target);\n }\n }\n\n /**\n * Paste event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onPaste(e) {\n // Disable pasting into the input if option has been set\n if (e.target === this.input && !this.config.paste) {\n e.preventDefault();\n }\n }\n\n /**\n * Focus event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onFocus(e) {\n const target = e.target;\n // If target is something that concerns us\n if (this.containerOuter.contains(target)) {\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const focusActions = {\n text: () => {\n if (target === this.input) {\n this.containerOuter.classList.add(this.config.classNames.focusState);\n }\n },\n 'select-one': () => {\n this.containerOuter.classList.add(this.config.classNames.focusState);\n if (target === this.input) {\n // Show dropdown if it isn't already showing\n if (!hasActiveDropdown) {\n this.showDropdown();\n }\n }\n },\n 'select-multiple': () => {\n if (target === this.input) {\n // If element is a select box, the focussed element is the container and the dropdown\n // isn't already open, focus and show dropdown\n this.containerOuter.classList.add(this.config.classNames.focusState);\n\n if (!hasActiveDropdown) {\n this.showDropdown(true);\n }\n }\n },\n };\n\n focusActions[this.passedElement.type]();\n }\n }\n\n /**\n * Blur event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onBlur(e) {\n const target = e.target;\n // If target is something that concerns us\n if (this.containerOuter.contains(target)) {\n const activeItems = this.store.getItemsFilteredByActive();\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const hasHighlightedItems = activeItems.some((item) => item.highlighted === true);\n const blurActions = {\n text: () => {\n if (target === this.input) {\n // Remove the focus state\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n // De-select any highlighted items\n if (hasHighlightedItems) {\n this.unhighlightAll();\n }\n // Hide dropdown if it is showing\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n }\n },\n 'select-one': () => {\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n if (target === this.containerOuter) {\n // Hide dropdown if it is showing\n if (hasActiveDropdown && !this.canSearch) {\n this.hideDropdown();\n }\n }\n\n if (target === this.input) {\n // Hide dropdown if it is showing\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n }\n },\n 'select-multiple': () => {\n if (target === this.input) {\n // Remove the focus state\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n // De-select any highlighted items\n if (hasHighlightedItems) {\n this.unhighlightAll();\n }\n }\n },\n };\n\n blurActions[this.passedElement.type]();\n }\n }\n\n /**\n * Tests value against a regular expression\n * @param {string} value Value to test\n * @return {Boolean} Whether test passed/failed\n * @private\n */\n _regexFilter(value) {\n if (!value) return;\n const regex = this.config.regexFilter;\n const expression = new RegExp(regex.source, 'i');\n return expression.test(value);\n }\n\n /**\n * Scroll to an option element\n * @param {HTMLElement} option Option to scroll to\n * @param {Number} direction Whether option is above or below\n * @return\n * @private\n */\n _scrollToChoice(choice, direction) {\n if (!choice) return;\n\n const dropdownHeight = this.choiceList.offsetHeight;\n const choiceHeight = choice.offsetHeight;\n // Distance from bottom of element to top of parent\n const choicePos = choice.offsetTop + choiceHeight;\n // Scroll position of dropdown\n const containerScrollPos = this.choiceList.scrollTop + dropdownHeight;\n // Difference between the choice and scroll position\n const endPoint = direction > 0 ? ((this.choiceList.scrollTop + choicePos) - containerScrollPos) : choice.offsetTop;\n\n const animateScroll = () => {\n const strength = 4;\n const choiceListScrollTop = this.choiceList.scrollTop;\n let continueAnimation = false;\n let easing;\n let distance;\n\n if (direction > 0) {\n easing = (endPoint - choiceListScrollTop) / strength;\n distance = easing > 1 ? easing : 1;\n\n this.choiceList.scrollTop = choiceListScrollTop + distance;\n if (choiceListScrollTop < endPoint) {\n continueAnimation = true;\n }\n } else {\n easing = (choiceListScrollTop - endPoint) / strength;\n distance = easing > 1 ? easing : 1;\n\n this.choiceList.scrollTop = choiceListScrollTop - distance;\n if (choiceListScrollTop > endPoint) {\n continueAnimation = true;\n }\n }\n\n if (continueAnimation) {\n requestAnimationFrame((time) => {\n animateScroll(time, endPoint, direction);\n });\n }\n };\n\n requestAnimationFrame((time) => {\n animateScroll(time, endPoint, direction);\n });\n }\n\n /**\n * Highlight choice\n * @param {HTMLElement} el Element to highlight\n * @return\n * @private\n */\n _highlightChoice(el) {\n // Highlight first element in dropdown\n const choices = Array.from(this.dropdown.querySelectorAll('[data-choice-selectable]'));\n\n if (choices && choices.length) {\n const highlightedChoices = Array.from(this.dropdown.querySelectorAll(`.${this.config.classNames.highlightedState}`));\n\n // Remove any highlighted choices\n highlightedChoices.forEach((choice) => {\n choice.classList.remove(this.config.classNames.highlightedState);\n choice.setAttribute('aria-selected', 'false');\n });\n\n if (el) {\n // Highlight given option\n el.classList.add(this.config.classNames.highlightedState);\n this.highlightPosition = choices.indexOf(el);\n } else {\n // Highlight choice based on last known highlight location\n let choice;\n\n if (choices.length > this.highlightPosition) {\n // If we have an option to highlight\n choice = choices[this.highlightPosition];\n } else {\n // Otherwise highlight the option before\n choice = choices[choices.length - 1];\n }\n\n if (!choice) choice = choices[0];\n choice.classList.add(this.config.classNames.highlightedState);\n choice.setAttribute('aria-selected', 'true');\n }\n }\n }\n\n /**\n * Add item to store with correct value\n * @param {String} value Value to add to store\n * @param {String} label Label to add to store\n * @return {Object} Class instance\n * @public\n */\n _addItem(value, label, choiceId = -1, groupId = -1) {\n let passedValue = isType('String', value) ? value.trim() : value;\n const items = this.store.getItems();\n const passedLabel = label || passedValue;\n const passedOptionId = parseInt(choiceId, 10) || -1;\n\n // Get group if group ID passed\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n // Generate unique id\n const id = items ? items.length + 1 : 1;\n\n // If a prepended value has been passed, prepend it\n if (this.config.prependValue) {\n passedValue = this.config.prependValue + passedValue.toString();\n }\n\n // If an appended value has been passed, append it\n if (this.config.appendValue) {\n passedValue += this.config.appendValue.toString();\n }\n\n this.store.dispatch(addItem(passedValue, passedLabel, id, passedOptionId, groupId));\n\n if (this.passedElement.type === 'select-one') {\n this.removeActiveItems(id);\n }\n\n // Trigger change event\n if(group && group.value) {\n triggerEvent(this.passedElement, 'addItem', {\n id,\n value: passedValue,\n label: passedLabel,\n groupValue: group.value,\n });\n } else {\n triggerEvent(this.passedElement, 'addItem', {\n id,\n value: passedValue,\n label: passedLabel,\n });\n }\n\n return this;\n }\n\n /**\n * Remove item from store\n * @param {Object} item Item to remove\n * @param {Function} callback Callback to trigger\n * @return {Object} Class instance\n * @public\n */\n _removeItem(item) {\n if (!item || !isType('Object', item)) {\n console.error('removeItem: No item object was passed to be removed');\n return;\n }\n\n const id = item.id;\n const value = item.value;\n const label = item.label;\n const choiceId = item.choiceId;\n const groupId = item.groupId;\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n this.store.dispatch(removeItem(id, choiceId));\n\n if(group && group.value) {\n triggerEvent(this.passedElement, 'removeItem', {\n id,\n value,\n label,\n groupValue: group.value,\n });\n } else {\n triggerEvent(this.passedElement, 'removeItem', {\n id,\n value,\n label,\n });\n }\n\n return this;\n }\n\n /**\n * Add choice to dropdown\n * @param {Boolean} isSelected Whether choice is selected\n * @param {Boolean} isDisabled Whether choice is disabled\n * @param {String} value Value of choice\n * @param {String} Label Label of choice\n * @param {Number} groupId ID of group choice is within. Negative number indicates no group\n * @return\n * @private\n */\n _addChoice(isSelected, isDisabled, value, label, groupId = -1) {\n if (typeof value === 'undefined' || value === null) return;\n\n // Generate unique id\n const choices = this.store.getChoices();\n const choiceLabel = label || value;\n const choiceId = choices ? choices.length + 1 : 1;\n\n this.store.dispatch(addChoice(value, choiceLabel, choiceId, groupId, isDisabled));\n\n if (isSelected) {\n this._addItem(value, choiceLabel, choiceId);\n }\n }\n\n /**\n * Clear all choices added to the store.\n * @return\n * @private\n */\n _clearChoices() {\n this.store.dispatch(clearChoices());\n }\n\n /**\n * Add group to dropdown\n * @param {Object} group Group to add\n * @param {Number} id Group ID\n * @param {String} [valueKey] name of the value property on the object\n * @param {String} [labelKey] name of the label property on the object\n * @return\n * @private\n */\n _addGroup(group, id, valueKey = 'value', labelKey = 'label') {\n const groupChoices = isType('Object', group) ? group.choices : Array.from(group.getElementsByTagName('OPTION'));\n const groupId = id ? id : Math.floor(new Date().valueOf() * Math.random());\n const isDisabled = group.disabled ? group.disabled : false;\n\n if (groupChoices) {\n this.store.dispatch(addGroup(group.label, groupId, true, isDisabled));\n\n groupChoices.forEach((option) => {\n const isOptDisabled = (option.disabled || (option.parentNode && option.parentNode.disabled)) || false;\n const isOptSelected = option.selected ? option.selected : false;\n let label;\n\n if (isType('Object', option)) {\n label = option[labelKey] || option[valueKey];\n } else {\n label = option.innerHTML;\n }\n\n this._addChoice(isOptSelected, isOptDisabled, option[valueKey], label, groupId);\n });\n } else {\n this.store.dispatch(addGroup(group.label, group.id, false, group.disabled));\n }\n }\n\n /**\n * Get template from name\n * @param {String} template Name of template to get\n * @param {...} args Data to pass to template\n * @return {HTMLElement} Template\n * @private\n */\n _getTemplate(template, ...args) {\n if (!template) return;\n const templates = this.config.templates;\n return templates[template](...args);\n }\n\n /**\n * Create HTML element based on type and arguments\n * @return\n * @private\n */\n _createTemplates() {\n const classNames = this.config.classNames;\n const templates = {\n containerOuter: (direction) => {\n return strToEl(`\n
\n `);\n },\n containerInner: () => {\n return strToEl(`\n
\n `);\n },\n itemList: () => {\n return strToEl(`\n
\n `);\n },\n placeholder: (value) => {\n return strToEl(`\n
${value}
\n `);\n },\n item: (data) => {\n if (this.config.removeItemButton) {\n return strToEl(`\n
\n ${data.label}\n
\n `);\n }\n return strToEl(`\n
\n ${data.label}\n
\n `);\n },\n choiceList: () => {\n return strToEl(`\n
\n `);\n },\n choiceGroup: (data) => {\n return strToEl(`\n
\n
${data.value}
\n
\n `);\n },\n choice: (data) => {\n return strToEl(`\n
0 ? 'role=\"treeitem\"' : 'role=\"option\"'}>\n ${data.label}\n
\n `);\n },\n input: () => {\n return strToEl(`\n \n `);\n },\n dropdown: () => {\n return strToEl(`\n
\n `);\n },\n notice: (label) => {\n return strToEl(`\n
${label}
\n `);\n },\n option: (data) => {\n return strToEl(`\n \n `);\n },\n };\n\n // User's custom templates\n const callbackTemplate = this.config.callbackOnCreateTemplates;\n let userTemplates = {};\n if (callbackTemplate && isType('Function', callbackTemplate)) {\n userTemplates = callbackTemplate.call(this, strToEl);\n }\n\n this.config.templates = extend(templates, userTemplates);\n }\n\n /**\n * Create DOM structure around passed select element\n * @return\n * @private\n */\n _createInput() {\n const direction = this.passedElement.getAttribute('dir') || 'ltr';\n const containerOuter = this._getTemplate('containerOuter', direction);\n const containerInner = this._getTemplate('containerInner');\n const itemList = this._getTemplate('itemList');\n const choiceList = this._getTemplate('choiceList');\n const input = this._getTemplate('input');\n const dropdown = this._getTemplate('dropdown');\n const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : false;\n\n this.containerOuter = containerOuter;\n this.containerInner = containerInner;\n this.input = input;\n this.choiceList = choiceList;\n this.itemList = itemList;\n this.dropdown = dropdown;\n\n // Hide passed input\n this.passedElement.classList.add(this.config.classNames.input, this.config.classNames.hiddenState);\n this.passedElement.tabIndex = '-1';\n this.passedElement.setAttribute('style', 'display:none;');\n this.passedElement.setAttribute('aria-hidden', 'true');\n this.passedElement.setAttribute('data-choice', 'active');\n\n // Wrap input in container preserving DOM ordering\n wrap(this.passedElement, containerInner);\n\n // Wrapper inner container with outer container\n wrap(containerInner, containerOuter);\n\n // If placeholder has been enabled and we have a value\n if (placeholder) {\n input.placeholder = placeholder;\n if (this.passedElement.type !== 'select-one') {\n input.style.width = getWidthOfInput(input);\n }\n }\n\n if (!this.config.addItems) this.disable();\n\n containerOuter.appendChild(containerInner);\n containerOuter.appendChild(dropdown);\n containerInner.appendChild(itemList);\n\n if (this.passedElement.type !== 'text') {\n dropdown.appendChild(choiceList);\n }\n\n if (this.passedElement.type === 'select-multiple' || this.passedElement.type === 'text') {\n containerInner.appendChild(input);\n } else if (this.canSearch) {\n dropdown.insertBefore(input, dropdown.firstChild);\n }\n\n if (this.passedElement.type === 'select-multiple' || this.passedElement.type === 'select-one') {\n const passedGroups = Array.from(this.passedElement.getElementsByTagName('OPTGROUP'));\n\n this.highlightPosition = 0;\n this.isSearching = false;\n\n if (passedGroups && passedGroups.length) {\n passedGroups.forEach((group) => {\n this._addGroup(group, (group.id || null));\n });\n } else {\n const passedOptions = Array.from(this.passedElement.options);\n const filter = this.config.sortFilter;\n const allChoices = this.presetChoices;\n\n // Create array of options from option elements\n passedOptions.forEach((o) => {\n allChoices.push({\n value: o.value,\n label: o.innerHTML,\n selected: o.selected,\n disabled: o.disabled || o.parentNode.disabled,\n });\n });\n\n // If sorting is enabled or the user is searching, filter choices\n if (this.config.shouldSort) {\n allChoices.sort(filter);\n }\n\n // Determine whether there is a selected choice\n const hasSelectedChoice = allChoices.some((choice) => {\n return choice.selected === true;\n });\n\n // Add each choice\n allChoices.forEach((choice, index) => {\n const isDisabled = choice.disabled ? choice.disabled : false;\n const isSelected = choice.selected ? choice.selected : false;\n // Pre-select first choice if it's a single select\n if (this.passedElement.type === 'select-one') {\n if (hasSelectedChoice || (!hasSelectedChoice && index > 0)) {\n // If there is a selected choice already or the choice is not\n // the first in the array, add each choice normally\n this._addChoice(isSelected, isDisabled, choice.value, choice.label);\n } else {\n // Otherwise pre-select the first choice in the array\n this._addChoice(true, false, choice.value, choice.label);\n }\n } else {\n this._addChoice(isSelected, isDisabled, choice.value, choice.label);\n }\n });\n }\n } else if (this.isTextElement) {\n // Add any preset values seperated by delimiter\n this.presetItems.forEach((item) => {\n const itemType = getType(item);\n if (itemType === 'Object') {\n if (!item.value) return;\n this._addItem(item.value, item.label, item.id);\n } else if (itemType === 'String') {\n this._addItem(item);\n }\n });\n }\n }\n\n /*===== End of Private functions ======*/\n}\n\nmodule.exports = Choices;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/choices.js","/**\n * @license\n * Fuse - Lightweight fuzzy-search\n *\n * Copyright (c) 2012-2016 Kirollos Risk .\n * All Rights Reserved. Apache Software License 2.0\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n;(function (global) {\n 'use strict'\n\n /** @type {function(...*)} */\n function log () {\n console.log.apply(console, arguments)\n }\n\n var defaultOptions = {\n // The name of the identifier property. If specified, the returned result will be a list\n // of the items' dentifiers, otherwise it will be a list of the items.\n id: null,\n\n // Indicates whether comparisons should be case sensitive.\n\n caseSensitive: false,\n\n // An array of values that should be included from the searcher's output. When this array\n // contains elements, each result in the list will be of the form `{ item: ..., include1: ..., include2: ... }`.\n // Values you can include are `score`, `matchedLocations`\n include: [],\n\n // Whether to sort the result list, by score\n shouldSort: true,\n\n // The search function to use\n // Note that the default search function ([[Function]]) must conform to the following API:\n //\n // @param pattern The pattern string to search\n // @param options The search option\n // [[Function]].constructor = function(pattern, options)\n //\n // @param text: the string to search in for the pattern\n // @return Object in the form of:\n // - isMatch: boolean\n // - score: Int\n // [[Function]].prototype.search = function(text)\n searchFn: BitapSearcher,\n\n // Default sort function\n sortFn: function (a, b) {\n return a.score - b.score\n },\n\n // The get function to use when fetching an object's properties.\n // The default will search nested paths *ie foo.bar.baz*\n getFn: deepValue,\n\n // List of properties that will be searched. This also supports nested properties.\n keys: [],\n\n // Will print to the console. Useful for debugging.\n verbose: false,\n\n // When true, the search algorithm will search individual words **and** the full string,\n // computing the final score as a function of both. Note that when `tokenize` is `true`,\n // the `threshold`, `distance`, and `location` are inconsequential for individual tokens.\n tokenize: false,\n\n // When true, the result set will only include records that match all tokens. Will only work\n // if `tokenize` is also true.\n matchAllTokens: false,\n\n // Regex used to separate words when searching. Only applicable when `tokenize` is `true`.\n tokenSeparator: / +/g,\n\n // Minimum number of characters that must be matched before a result is considered a match\n minMatchCharLength: 1,\n\n // When true, the algorithm continues searching to the end of the input even if a perfect\n // match is found before the end of the same input.\n findAllMatches: false\n }\n\n /**\n * @constructor\n * @param {!Array} list\n * @param {!Object} options\n */\n function Fuse (list, options) {\n var key\n\n this.list = list\n this.options = options = options || {}\n\n for (key in defaultOptions) {\n if (!defaultOptions.hasOwnProperty(key)) {\n continue;\n }\n // Add boolean type options\n if (typeof defaultOptions[key] === 'boolean') {\n this.options[key] = key in options ? options[key] : defaultOptions[key];\n // Add all other options\n } else {\n this.options[key] = options[key] || defaultOptions[key]\n }\n }\n }\n\n Fuse.VERSION = '2.6.2'\n\n /**\n * Sets a new list for Fuse to match against.\n * @param {!Array} list\n * @return {!Array} The newly set list\n * @public\n */\n Fuse.prototype.set = function (list) {\n this.list = list\n return list\n }\n\n Fuse.prototype.search = function (pattern) {\n if (this.options.verbose) log('\\nSearch term:', pattern, '\\n')\n\n this.pattern = pattern\n this.results = []\n this.resultMap = {}\n this._keyMap = null\n\n this._prepareSearchers()\n this._startSearch()\n this._computeScore()\n this._sort()\n\n var output = this._format()\n return output\n }\n\n Fuse.prototype._prepareSearchers = function () {\n var options = this.options\n var pattern = this.pattern\n var searchFn = options.searchFn\n var tokens = pattern.split(options.tokenSeparator)\n var i = 0\n var len = tokens.length\n\n if (this.options.tokenize) {\n this.tokenSearchers = []\n for (; i < len; i++) {\n this.tokenSearchers.push(new searchFn(tokens[i], options))\n }\n }\n this.fullSeacher = new searchFn(pattern, options)\n }\n\n Fuse.prototype._startSearch = function () {\n var options = this.options\n var getFn = options.getFn\n var list = this.list\n var listLen = list.length\n var keys = this.options.keys\n var keysLen = keys.length\n var key\n var weight\n var item = null\n var i\n var j\n\n // Check the first item in the list, if it's a string, then we assume\n // that every item in the list is also a string, and thus it's a flattened array.\n if (typeof list[0] === 'string') {\n // Iterate over every item\n for (i = 0; i < listLen; i++) {\n this._analyze('', list[i], i, i)\n }\n } else {\n this._keyMap = {}\n // Otherwise, the first item is an Object (hopefully), and thus the searching\n // is done on the values of the keys of each item.\n // Iterate over every item\n for (i = 0; i < listLen; i++) {\n item = list[i]\n // Iterate over every key\n for (j = 0; j < keysLen; j++) {\n key = keys[j]\n if (typeof key !== 'string') {\n weight = (1 - key.weight) || 1\n this._keyMap[key.name] = {\n weight: weight\n }\n if (key.weight <= 0 || key.weight > 1) {\n throw new Error('Key weight has to be > 0 and <= 1')\n }\n key = key.name\n } else {\n this._keyMap[key] = {\n weight: 1\n }\n }\n this._analyze(key, getFn(item, key, []), item, i)\n }\n }\n }\n }\n\n Fuse.prototype._analyze = function (key, text, entity, index) {\n var options = this.options\n var words\n var scores\n var exists = false\n var existingResult\n var averageScore\n var finalScore\n var scoresLen\n var mainSearchResult\n var tokenSearcher\n var termScores\n var word\n var tokenSearchResult\n var hasMatchInText\n var checkTextMatches\n var i\n var j\n\n // Check if the text can be searched\n if (text === undefined || text === null) {\n return\n }\n\n scores = []\n\n var numTextMatches = 0\n\n if (typeof text === 'string') {\n words = text.split(options.tokenSeparator)\n\n if (options.verbose) log('---------\\nKey:', key)\n\n if (this.options.tokenize) {\n for (i = 0; i < this.tokenSearchers.length; i++) {\n tokenSearcher = this.tokenSearchers[i]\n\n if (options.verbose) log('Pattern:', tokenSearcher.pattern)\n\n termScores = []\n hasMatchInText = false\n\n for (j = 0; j < words.length; j++) {\n word = words[j]\n tokenSearchResult = tokenSearcher.search(word)\n var obj = {}\n if (tokenSearchResult.isMatch) {\n obj[word] = tokenSearchResult.score\n exists = true\n hasMatchInText = true\n scores.push(tokenSearchResult.score)\n } else {\n obj[word] = 1\n if (!this.options.matchAllTokens) {\n scores.push(1)\n }\n }\n termScores.push(obj)\n }\n\n if (hasMatchInText) {\n numTextMatches++\n }\n\n if (options.verbose) log('Token scores:', termScores)\n }\n\n averageScore = scores[0]\n scoresLen = scores.length\n for (i = 1; i < scoresLen; i++) {\n averageScore += scores[i]\n }\n averageScore = averageScore / scoresLen\n\n if (options.verbose) log('Token score average:', averageScore)\n }\n\n mainSearchResult = this.fullSeacher.search(text)\n if (options.verbose) log('Full text score:', mainSearchResult.score)\n\n finalScore = mainSearchResult.score\n if (averageScore !== undefined) {\n finalScore = (finalScore + averageScore) / 2\n }\n\n if (options.verbose) log('Score average:', finalScore)\n\n checkTextMatches = (this.options.tokenize && this.options.matchAllTokens) ? numTextMatches >= this.tokenSearchers.length : true\n\n if (options.verbose) log('Check Matches', checkTextMatches)\n\n // If a match is found, add the item to , including its score\n if ((exists || mainSearchResult.isMatch) && checkTextMatches) {\n // Check if the item already exists in our results\n existingResult = this.resultMap[index]\n\n if (existingResult) {\n // Use the lowest score\n // existingResult.score, bitapResult.score\n existingResult.output.push({\n key: key,\n score: finalScore,\n matchedIndices: mainSearchResult.matchedIndices\n })\n } else {\n // Add it to the raw result list\n this.resultMap[index] = {\n item: entity,\n output: [{\n key: key,\n score: finalScore,\n matchedIndices: mainSearchResult.matchedIndices\n }]\n }\n\n this.results.push(this.resultMap[index])\n }\n }\n } else if (isArray(text)) {\n for (i = 0; i < text.length; i++) {\n this._analyze(key, text[i], entity, index)\n }\n }\n }\n\n Fuse.prototype._computeScore = function () {\n var i\n var j\n var keyMap = this._keyMap\n var totalScore\n var output\n var scoreLen\n var score\n var weight\n var results = this.results\n var bestScore\n var nScore\n\n if (this.options.verbose) log('\\n\\nComputing score:\\n')\n\n for (i = 0; i < results.length; i++) {\n totalScore = 0\n output = results[i].output\n scoreLen = output.length\n\n bestScore = 1\n\n for (j = 0; j < scoreLen; j++) {\n score = output[j].score\n weight = keyMap ? keyMap[output[j].key].weight : 1\n\n nScore = score * weight\n\n if (weight !== 1) {\n bestScore = Math.min(bestScore, nScore)\n } else {\n totalScore += nScore\n output[j].nScore = nScore\n }\n }\n\n if (bestScore === 1) {\n results[i].score = totalScore / scoreLen\n } else {\n results[i].score = bestScore\n }\n\n if (this.options.verbose) log(results[i])\n }\n }\n\n Fuse.prototype._sort = function () {\n var options = this.options\n if (options.shouldSort) {\n if (options.verbose) log('\\n\\nSorting....')\n this.results.sort(options.sortFn)\n }\n }\n\n Fuse.prototype._format = function () {\n var options = this.options\n var getFn = options.getFn\n var finalOutput = []\n var item\n var i\n var len\n var results = this.results\n var replaceValue\n var getItemAtIndex\n var include = options.include\n\n if (options.verbose) log('\\n\\nOutput:\\n\\n', results)\n\n // Helper function, here for speed-up, which replaces the item with its value,\n // if the options specifies it,\n replaceValue = options.id ? function (index) {\n results[index].item = getFn(results[index].item, options.id, [])[0]\n } : function () {}\n\n getItemAtIndex = function (index) {\n var record = results[index]\n var data\n var j\n var output\n var _item\n var _result\n\n // If `include` has values, put the item in the result\n if (include.length > 0) {\n data = {\n item: record.item\n }\n if (include.indexOf('matches') !== -1) {\n output = record.output\n data.matches = []\n for (j = 0; j < output.length; j++) {\n _item = output[j]\n _result = {\n indices: _item.matchedIndices\n }\n if (_item.key) {\n _result.key = _item.key\n }\n data.matches.push(_result)\n }\n }\n\n if (include.indexOf('score') !== -1) {\n data.score = results[index].score\n }\n\n } else {\n data = record.item\n }\n\n return data\n }\n\n // From the results, push into a new array only the item identifier (if specified)\n // of the entire item. This is because we don't want to return the ,\n // since it contains other metadata\n for (i = 0, len = results.length; i < len; i++) {\n replaceValue(i)\n item = getItemAtIndex(i)\n finalOutput.push(item)\n }\n\n return finalOutput\n }\n\n // Helpers\n\n function deepValue (obj, path, list) {\n var firstSegment\n var remaining\n var dotIndex\n var value\n var i\n var len\n\n if (!path) {\n // If there's no path left, we've gotten to the object we care about.\n list.push(obj)\n } else {\n dotIndex = path.indexOf('.')\n\n if (dotIndex !== -1) {\n firstSegment = path.slice(0, dotIndex)\n remaining = path.slice(dotIndex + 1)\n } else {\n firstSegment = path\n }\n\n value = obj[firstSegment]\n if (value !== null && value !== undefined) {\n if (!remaining && (typeof value === 'string' || typeof value === 'number')) {\n list.push(value)\n } else if (isArray(value)) {\n // Search each item in the array.\n for (i = 0, len = value.length; i < len; i++) {\n deepValue(value[i], remaining, list)\n }\n } else if (remaining) {\n // An object. Recurse further.\n deepValue(value, remaining, list)\n }\n }\n }\n\n return list\n }\n\n function isArray (obj) {\n return Object.prototype.toString.call(obj) === '[object Array]'\n }\n\n /**\n * Adapted from \"Diff, Match and Patch\", by Google\n *\n * http://code.google.com/p/google-diff-match-patch/\n *\n * Modified by: Kirollos Risk \n * -----------------------------------------------\n * Details: the algorithm and structure was modified to allow the creation of\n * instances with a method which does the actual\n * bitap search. The (the string that is searched for) is only defined\n * once per instance and thus it eliminates redundant re-creation when searching\n * over a list of strings.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n *\n * @constructor\n */\n function BitapSearcher (pattern, options) {\n options = options || {}\n this.options = options\n this.options.location = options.location || BitapSearcher.defaultOptions.location\n this.options.distance = 'distance' in options ? options.distance : BitapSearcher.defaultOptions.distance\n this.options.threshold = 'threshold' in options ? options.threshold : BitapSearcher.defaultOptions.threshold\n this.options.maxPatternLength = options.maxPatternLength || BitapSearcher.defaultOptions.maxPatternLength\n\n this.pattern = options.caseSensitive ? pattern : pattern.toLowerCase()\n this.patternLen = pattern.length\n\n if (this.patternLen <= this.options.maxPatternLength) {\n this.matchmask = 1 << (this.patternLen - 1)\n this.patternAlphabet = this._calculatePatternAlphabet()\n }\n }\n\n BitapSearcher.defaultOptions = {\n // Approximately where in the text is the pattern expected to be found?\n location: 0,\n\n // Determines how close the match must be to the fuzzy location (specified above).\n // An exact letter match which is 'distance' characters away from the fuzzy location\n // would score as a complete mismatch. A distance of '0' requires the match be at\n // the exact location specified, a threshold of '1000' would require a perfect match\n // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.\n distance: 100,\n\n // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match\n // (of both letters and location), a threshold of '1.0' would match anything.\n threshold: 0.6,\n\n // Machine word size\n maxPatternLength: 32\n }\n\n /**\n * Initialize the alphabet for the Bitap algorithm.\n * @return {Object} Hash of character locations.\n * @private\n */\n BitapSearcher.prototype._calculatePatternAlphabet = function () {\n var mask = {},\n i = 0\n\n for (i = 0; i < this.patternLen; i++) {\n mask[this.pattern.charAt(i)] = 0\n }\n\n for (i = 0; i < this.patternLen; i++) {\n mask[this.pattern.charAt(i)] |= 1 << (this.pattern.length - i - 1)\n }\n\n return mask\n }\n\n /**\n * Compute and return the score for a match with `e` errors and `x` location.\n * @param {number} errors Number of errors in match.\n * @param {number} location Location of match.\n * @return {number} Overall score for match (0.0 = good, 1.0 = bad).\n * @private\n */\n BitapSearcher.prototype._bitapScore = function (errors, location) {\n var accuracy = errors / this.patternLen,\n proximity = Math.abs(this.options.location - location)\n\n if (!this.options.distance) {\n // Dodge divide by zero error.\n return proximity ? 1.0 : accuracy\n }\n return accuracy + (proximity / this.options.distance)\n }\n\n /**\n * Compute and return the result of the search\n * @param {string} text The text to search in\n * @return {{isMatch: boolean, score: number}} Literal containing:\n * isMatch - Whether the text is a match or not\n * score - Overall score for the match\n * @public\n */\n BitapSearcher.prototype.search = function (text) {\n var options = this.options\n var i\n var j\n var textLen\n var findAllMatches\n var location\n var threshold\n var bestLoc\n var binMin\n var binMid\n var binMax\n var start, finish\n var bitArr\n var lastBitArr\n var charMatch\n var score\n var locations\n var matches\n var isMatched\n var matchMask\n var matchedIndices\n var matchesLen\n var match\n\n text = options.caseSensitive ? text : text.toLowerCase()\n\n if (this.pattern === text) {\n // Exact match\n return {\n isMatch: true,\n score: 0,\n matchedIndices: [[0, text.length - 1]]\n }\n }\n\n // When pattern length is greater than the machine word length, just do a a regex comparison\n if (this.patternLen > options.maxPatternLength) {\n matches = text.match(new RegExp(this.pattern.replace(options.tokenSeparator, '|')))\n isMatched = !!matches\n\n if (isMatched) {\n matchedIndices = []\n for (i = 0, matchesLen = matches.length; i < matchesLen; i++) {\n match = matches[i]\n matchedIndices.push([text.indexOf(match), match.length - 1])\n }\n }\n\n return {\n isMatch: isMatched,\n // TODO: revisit this score\n score: isMatched ? 0.5 : 1,\n matchedIndices: matchedIndices\n }\n }\n\n findAllMatches = options.findAllMatches\n\n location = options.location\n // Set starting location at beginning text and initialize the alphabet.\n textLen = text.length\n // Highest score beyond which we give up.\n threshold = options.threshold\n // Is there a nearby exact match? (speedup)\n bestLoc = text.indexOf(this.pattern, location)\n\n // a mask of the matches\n matchMask = []\n for (i = 0; i < textLen; i++) {\n matchMask[i] = 0\n }\n\n if (bestLoc != -1) {\n threshold = Math.min(this._bitapScore(0, bestLoc), threshold)\n // What about in the other direction? (speed up)\n bestLoc = text.lastIndexOf(this.pattern, location + this.patternLen)\n\n if (bestLoc != -1) {\n threshold = Math.min(this._bitapScore(0, bestLoc), threshold)\n }\n }\n\n bestLoc = -1\n score = 1\n locations = []\n binMax = this.patternLen + textLen\n\n for (i = 0; i < this.patternLen; i++) {\n // Scan for the best match; each iteration allows for one more error.\n // Run a binary search to determine how far from the match location we can stray\n // at this error level.\n binMin = 0\n binMid = binMax\n while (binMin < binMid) {\n if (this._bitapScore(i, location + binMid) <= threshold) {\n binMin = binMid\n } else {\n binMax = binMid\n }\n binMid = Math.floor((binMax - binMin) / 2 + binMin)\n }\n\n // Use the result from this iteration as the maximum for the next.\n binMax = binMid\n start = Math.max(1, location - binMid + 1)\n if (findAllMatches) {\n finish = textLen;\n } else {\n finish = Math.min(location + binMid, textLen) + this.patternLen\n }\n\n // Initialize the bit array\n bitArr = Array(finish + 2)\n\n bitArr[finish + 1] = (1 << i) - 1\n\n for (j = finish; j >= start; j--) {\n charMatch = this.patternAlphabet[text.charAt(j - 1)]\n\n if (charMatch) {\n matchMask[j - 1] = 1\n }\n\n if (i === 0) {\n // First pass: exact match.\n bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch\n } else {\n // Subsequent passes: fuzzy match.\n bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch | (((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1) | lastBitArr[j + 1]\n }\n if (bitArr[j] & this.matchmask) {\n score = this._bitapScore(i, j - 1)\n\n // This match will almost certainly be better than any existing match.\n // But check anyway.\n if (score <= threshold) {\n // Indeed it is\n threshold = score\n bestLoc = j - 1\n locations.push(bestLoc)\n\n if (bestLoc > location) {\n // When passing loc, don't exceed our current distance from loc.\n start = Math.max(1, 2 * location - bestLoc)\n } else {\n // Already passed loc, downhill from here on in.\n break\n }\n }\n }\n }\n\n // No hope for a (better) match at greater error levels.\n if (this._bitapScore(i + 1, location) > threshold) {\n break\n }\n lastBitArr = bitArr\n }\n\n matchedIndices = this._getMatchedIndices(matchMask)\n\n // Count exact matches (those with a score of 0) to be \"almost\" exact\n return {\n isMatch: bestLoc >= 0,\n score: score === 0 ? 0.001 : score,\n matchedIndices: matchedIndices\n }\n }\n\n BitapSearcher.prototype._getMatchedIndices = function (matchMask) {\n var matchedIndices = []\n var start = -1\n var end = -1\n var i = 0\n var match\n var len = matchMask.length\n for (; i < len; i++) {\n match = matchMask[i]\n if (match && start === -1) {\n start = i\n } else if (!match && start !== -1) {\n end = i - 1\n if ((end - start) + 1 >= this.options.minMatchCharLength) {\n matchedIndices.push([start, end])\n }\n start = -1\n }\n }\n if (matchMask[i - 1]) {\n if ((i-1 - start) + 1 >= this.options.minMatchCharLength) {\n matchedIndices.push([start, i - 1])\n }\n }\n return matchedIndices\n }\n\n // Export to Common JS Loader\n if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = Fuse\n } else if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(function () {\n return Fuse\n })\n } else {\n // Browser globals (root is window)\n global.Fuse = Fuse\n }\n\n})(this);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/fuse.js/src/fuse.js\n// module id = 2\n// module chunks = 0","import { createStore } from 'redux';\nimport rootReducer from './../reducers/index.js';\n\nexport default class Store {\n constructor() {\n this.store = createStore(\n rootReducer\n , window.devToolsExtension ? window.devToolsExtension() : undefined\n );\n }\n\n /**\n * Get store object (wrapping Redux method)\n * @return {Object} State\n */\n getState() {\n return this.store.getState();\n }\n\n /**\n * Dispatch event to store (wrapped Redux method)\n * @param {Function} action Action function to trigger\n * @return\n */\n dispatch(action) {\n this.store.dispatch(action);\n }\n\n /**\n * Subscribe store to function call (wrapped Redux method)\n * @param {Function} onChange Function to trigger when state changes\n * @return\n */\n subscribe(onChange) {\n this.store.subscribe(onChange);\n }\n\n /**\n * Get items from store\n * @return {Array} Item objects\n */\n getItems() {\n const state = this.store.getState();\n return state.items;\n }\n\n /**\n * Get active items from store\n * @return {Array} Item objects\n */\n getItemsFilteredByActive() {\n const items = this.getItems();\n const values = items.filter((item) => {\n return item.active === true;\n }, []);\n\n return values;\n }\n\n /**\n * Get items from store reduced to just their values\n * @return {Array} Item objects\n */\n getItemsReducedToValues(items = this.getItems()) {\n const values = items.reduce((prev, current) => {\n prev.push(current.value);\n return prev;\n }, []);\n\n return values;\n }\n\n /**\n * Get choices from store\n * @return {Array} Option objects\n */\n getChoices() {\n const state = this.store.getState();\n return state.choices;\n }\n\n /**\n * Get active choices from store\n * @return {Array} Option objects\n */\n getChoicesFilteredByActive() {\n const choices = this.getChoices();\n const values = choices.filter((choice) => {\n return choice.active === true;\n }, []);\n\n return values;\n }\n\n /**\n * Get selectable choices from store\n * @return {Array} Option objects\n */\n getChoicesFilteredBySelectable() {\n const choices = this.getChoices();\n const values = choices.filter((choice) => {\n return choice.disabled !== true;\n }, []);\n\n return values;\n }\n\n /**\n * Get single choice by it's ID\n * @return {Object} Found choice\n */\n getChoiceById(id) {\n if (id) {\n const choices = this.getChoicesFilteredByActive();\n const foundChoice = choices.find((choice) => choice.id === parseInt(id, 10));\n return foundChoice;\n }\n return false;\n }\n\n /**\n * Get groups from store\n * @return {Array} Group objects\n */\n getGroups() {\n const state = this.store.getState();\n return state.groups;\n }\n\n /**\n * Get active groups from store\n * @return {Array} Group objects\n */\n getGroupsFilteredByActive() {\n const groups = this.getGroups();\n const choices = this.getChoices();\n\n const values = groups.filter((group) => {\n const isActive = group.active === true && group.disabled === false;\n const hasActiveOptions = choices.some((choice) => {\n return choice.active === true && choice.disabled === false;\n });\n return isActive && hasActiveOptions;\n }, []);\n\n return values;\n }\n\n /**\n * Get group by group id\n * @param {Number} id Group ID\n * @return {Object} Group data\n */\n getGroupById(id) {\n const groups = this.getGroups();\n const foundGroup = groups.find((group) => {\n return group.id === id;\n });\n\n return foundGroup;\n }\n}\n\nmodule.exports = Store;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/store/index.js","'use strict';\n\nexports.__esModule = true;\nexports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined;\n\nvar _createStore = require('./createStore');\n\nvar _createStore2 = _interopRequireDefault(_createStore);\n\nvar _combineReducers = require('./combineReducers');\n\nvar _combineReducers2 = _interopRequireDefault(_combineReducers);\n\nvar _bindActionCreators = require('./bindActionCreators');\n\nvar _bindActionCreators2 = _interopRequireDefault(_bindActionCreators);\n\nvar _applyMiddleware = require('./applyMiddleware');\n\nvar _applyMiddleware2 = _interopRequireDefault(_applyMiddleware);\n\nvar _compose = require('./compose');\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nvar _warning = require('./utils/warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/*\n* This is a dummy function to check if the function name has been altered by minification.\n* If the function has been minified and NODE_ENV !== 'production', warn the user.\n*/\nfunction isCrushed() {}\n\nif (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {\n (0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \\'production\\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');\n}\n\nexports.createStore = _createStore2['default'];\nexports.combineReducers = _combineReducers2['default'];\nexports.bindActionCreators = _bindActionCreators2['default'];\nexports.applyMiddleware = _applyMiddleware2['default'];\nexports.compose = _compose2['default'];\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/index.js\n// module id = 4\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports.ActionTypes = undefined;\nexports['default'] = createStore;\n\nvar _isPlainObject = require('lodash/isPlainObject');\n\nvar _isPlainObject2 = _interopRequireDefault(_isPlainObject);\n\nvar _symbolObservable = require('symbol-observable');\n\nvar _symbolObservable2 = _interopRequireDefault(_symbolObservable);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar ActionTypes = exports.ActionTypes = {\n INIT: '@@redux/INIT'\n};\n\n/**\n * Creates a Redux store that holds the state tree.\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} enhancer The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error('Expected the enhancer to be a function.');\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error('Expected the reducer to be a function.');\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n function getState() {\n return currentState;\n }\n\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Expected listener to be a function.');\n }\n\n var isSubscribed = true;\n\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n isSubscribed = false;\n\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n };\n }\n\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n function dispatch(action) {\n if (!(0, _isPlainObject2['default'])(action)) {\n throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error('Actions may not have an undefined \"type\" property. ' + 'Have you misspelled a constant?');\n }\n\n if (isDispatching) {\n throw new Error('Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n for (var i = 0; i < listeners.length; i++) {\n listeners[i]();\n }\n\n return action;\n }\n\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error('Expected the nextReducer to be a function.');\n }\n\n currentReducer = nextReducer;\n dispatch({ type: ActionTypes.INIT });\n }\n\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/zenparsing/es-observable\n */\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object') {\n throw new TypeError('Expected the observer to be an object.');\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return { unsubscribe: unsubscribe };\n }\n }, _ref[_symbolObservable2['default']] = function () {\n return this;\n }, _ref;\n }\n\n // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n dispatch({ type: ActionTypes.INIT });\n\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[_symbolObservable2['default']] = observable, _ref2;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/createStore.js\n// module id = 5\n// module chunks = 0","var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/isPlainObject.js\n// module id = 6\n// module chunks = 0","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_baseGetTag.js\n// module id = 7\n// module chunks = 0","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_Symbol.js\n// module id = 8\n// module chunks = 0","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_root.js\n// module id = 9\n// module chunks = 0","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_freeGlobal.js\n// module id = 10\n// module chunks = 0","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_getRawTag.js\n// module id = 11\n// module chunks = 0","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_objectToString.js\n// module id = 12\n// module chunks = 0","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_getPrototype.js\n// module id = 13\n// module chunks = 0","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_overArg.js\n// module id = 14\n// module chunks = 0","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/isObjectLike.js\n// module id = 15\n// module chunks = 0","module.exports = require('./lib/index');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/index.js\n// module id = 16\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _ponyfill = require('./ponyfill');\n\nvar _ponyfill2 = _interopRequireDefault(_ponyfill);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar root; /* global window */\n\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = (0, _ponyfill2['default'])(root);\nexports['default'] = result;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/lib/index.js\n// module id = 17\n// module chunks = 0","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/module.js\n// module id = 18\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports['default'] = symbolObservablePonyfill;\nfunction symbolObservablePonyfill(root) {\n\tvar result;\n\tvar _Symbol = root.Symbol;\n\n\tif (typeof _Symbol === 'function') {\n\t\tif (_Symbol.observable) {\n\t\t\tresult = _Symbol.observable;\n\t\t} else {\n\t\t\tresult = _Symbol('observable');\n\t\t\t_Symbol.observable = result;\n\t\t}\n\t} else {\n\t\tresult = '@@observable';\n\t}\n\n\treturn result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/lib/ponyfill.js\n// module id = 19\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = combineReducers;\n\nvar _createStore = require('./createStore');\n\nvar _isPlainObject = require('lodash/isPlainObject');\n\nvar _isPlainObject2 = _interopRequireDefault(_isPlainObject);\n\nvar _warning = require('./utils/warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction getUndefinedStateErrorMessage(key, action) {\n var actionType = action && action.type;\n var actionName = actionType && '\"' + actionType.toString() + '\"' || 'an action';\n\n return 'Given action ' + actionName + ', reducer \"' + key + '\" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.';\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === _createStore.ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!(0, _isPlainObject2['default'])(inputState)) {\n return 'The ' + argumentName + ' has unexpected type of \"' + {}.toString.call(inputState).match(/\\s([a-z|A-Z]+)/)[1] + '\". Expected argument to be an object with the following ' + ('keys: \"' + reducerKeys.join('\", \"') + '\"');\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n\n if (unexpectedKeys.length > 0) {\n return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('\"' + unexpectedKeys.join('\", \"') + '\" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('\"' + reducerKeys.join('\", \"') + '\". Unexpected keys will be ignored.');\n }\n}\n\nfunction assertReducerSanity(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT });\n\n if (typeof initialState === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');\n }\n\n var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');\n if (typeof reducer(undefined, { type: type }) === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined when probed with a random type. ' + ('Don\\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in \"redux/*\" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');\n }\n });\n}\n\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n (0, _warning2['default'])('No reducer provided for key \"' + key + '\"');\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n var finalReducerKeys = Object.keys(finalReducers);\n\n if (process.env.NODE_ENV !== 'production') {\n var unexpectedKeyCache = {};\n }\n\n var sanityError;\n try {\n assertReducerSanity(finalReducers);\n } catch (e) {\n sanityError = e;\n }\n\n return function combination() {\n var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n var action = arguments[1];\n\n if (sanityError) {\n throw sanityError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n if (warningMessage) {\n (0, _warning2['default'])(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n for (var i = 0; i < finalReducerKeys.length; i++) {\n var key = finalReducerKeys[i];\n var reducer = finalReducers[key];\n var previousStateForKey = state[key];\n var nextStateForKey = reducer(previousStateForKey, action);\n if (typeof nextStateForKey === 'undefined') {\n var errorMessage = getUndefinedStateErrorMessage(key, action);\n throw new Error(errorMessage);\n }\n nextState[key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n return hasChanged ? nextState : state;\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/combineReducers.js\n// module id = 20\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = warning;\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n /* eslint-disable no-empty */\n } catch (e) {}\n /* eslint-enable no-empty */\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/utils/warning.js\n// module id = 21\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = bindActionCreators;\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(undefined, arguments));\n };\n}\n\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass a single function as the first argument,\n * and get a function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?');\n }\n\n var keys = Object.keys(actionCreators);\n var boundActionCreators = {};\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var actionCreator = actionCreators[key];\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n return boundActionCreators;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/bindActionCreators.js\n// module id = 22\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports['default'] = applyMiddleware;\n\nvar _compose = require('./compose');\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function (reducer, preloadedState, enhancer) {\n var store = createStore(reducer, preloadedState, enhancer);\n var _dispatch = store.dispatch;\n var chain = [];\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch(action) {\n return _dispatch(action);\n }\n };\n chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);\n\n return _extends({}, store, {\n dispatch: _dispatch\n });\n };\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/applyMiddleware.js\n// module id = 23\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\nexports[\"default\"] = compose;\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\n\nfunction compose() {\n for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n var last = funcs[funcs.length - 1];\n var rest = funcs.slice(0, -1);\n return function () {\n return rest.reduceRight(function (composed, f) {\n return f(composed);\n }, last.apply(undefined, arguments));\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/compose.js\n// module id = 24\n// module chunks = 0","import { combineReducers } from 'redux';\nimport items from './items';\nimport groups from './groups';\nimport choices from './choices';\n\nconst appReducer = combineReducers({\n items,\n groups,\n choices,\n});\n\nconst rootReducer = (passedState, action) => {\n let state = passedState;\n // If we are clearing all items, groups and options we reassign\n // state and then pass that state to our proper reducer. This isn't\n // mutating our actual state\n // See: http://stackoverflow.com/a/35641992\n if (action.type === 'CLEAR_ALL') {\n state = undefined;\n }\n\n return appReducer(state, action);\n};\n\nexport default rootReducer;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/index.js","const items = (state = [], action) => {\n switch (action.type) {\n case 'ADD_ITEM': {\n // Add object to items array\n const newState = [...state, {\n id: action.id,\n choiceId: action.choiceId,\n groupId: action.groupId,\n value: action.value,\n label: action.label,\n active: true,\n highlighted: false,\n }];\n\n return newState.map((item) => {\n if (item.highlighted) {\n item.highlighted = false;\n }\n return item;\n });\n }\n\n case 'REMOVE_ITEM': {\n // Set item to inactive\n return state.map((item) => {\n if (item.id === action.id) {\n item.active = false;\n }\n return item;\n });\n }\n\n case 'HIGHLIGHT_ITEM': {\n return state.map((item) => {\n if (item.id === action.id) {\n item.highlighted = action.highlighted;\n }\n return item;\n });\n }\n\n default: {\n return state;\n }\n }\n};\n\nexport default items;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/items.js","const groups = (state = [], action) => {\n switch (action.type) {\n case 'ADD_GROUP': {\n return [...state, {\n id: action.id,\n value: action.value,\n active: action.active,\n disabled: action.disabled,\n }];\n }\n\n case 'CLEAR_CHOICES': {\n return state.groups = [];\n }\n\n default: {\n return state;\n }\n }\n};\n\nexport default groups;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/groups.js","const choices = (state = [], action) => {\n switch (action.type) {\n case 'ADD_CHOICE': {\n /*\n A disabled choice appears in the choice dropdown but cannot be selected\n A selected choice has been added to the passed input's value (added as an item)\n An active choice appears within the choice dropdown\n */\n return [...state, {\n id: action.id,\n groupId: action.groupId,\n value: action.value,\n label: action.label,\n disabled: action.disabled,\n selected: false,\n active: true,\n score: 9999,\n }];\n }\n\n case 'ADD_ITEM': {\n let newState = state;\n\n // If all choices need to be activated\n if (action.activateOptions) {\n newState = state.map((choice) => {\n choice.active = action.active;\n return choice;\n });\n }\n // When an item is added and it has an associated choice,\n // we want to disable it so it can't be chosen again\n if (action.choiceId > -1) {\n newState = state.map((choice) => {\n if (choice.id === parseInt(action.choiceId, 10)) {\n choice.selected = true;\n }\n return choice;\n });\n }\n\n return newState;\n }\n\n case 'REMOVE_ITEM': {\n // When an item is removed and it has an associated choice,\n // we want to re-enable it so it can be chosen again\n if (action.choiceId > -1) {\n return state.map((choice) => {\n if (choice.id === parseInt(action.choiceId, 10)) {\n choice.selected = false;\n }\n return choice;\n });\n }\n\n return state;\n }\n\n case 'FILTER_CHOICES': {\n const filteredResults = action.results;\n const filteredState = state.map((choice) => {\n // Set active state based on whether choice is\n // within filtered results\n\n choice.active = filteredResults.some((result) => {\n if (result.item.id === choice.id) {\n choice.score = result.score;\n return true;\n }\n return false;\n });\n\n return choice;\n });\n\n return filteredState;\n }\n\n case 'ACTIVATE_CHOICES': {\n return state.map((choice) => {\n choice.active = action.active;\n return choice;\n });\n }\n\n case 'CLEAR_CHOICES': {\n return state.choices = [];\n }\n\n default: {\n return state;\n }\n }\n};\n\nexport default choices;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/choices.js","export const addItem = (value, label, id, choiceId, groupId) => {\n return {\n type: 'ADD_ITEM',\n value,\n label,\n id,\n choiceId,\n groupId,\n };\n};\n\nexport const removeItem = (id, choiceId) => {\n return {\n type: 'REMOVE_ITEM',\n id,\n choiceId,\n };\n};\n\nexport const highlightItem = (id, highlighted) => {\n return {\n type: 'HIGHLIGHT_ITEM',\n id,\n highlighted,\n };\n};\n\nexport const addChoice = (value, label, id, groupId, disabled) => {\n return {\n type: 'ADD_CHOICE',\n value,\n label,\n id,\n groupId,\n disabled,\n };\n};\n\nexport const filterChoices = (results) => {\n return {\n type: 'FILTER_CHOICES',\n results,\n };\n};\n\nexport const activateChoices = (active = true) => {\n return {\n type: 'ACTIVATE_CHOICES',\n active,\n };\n};\n\nexport const clearChoices = () => {\n return {\n type: 'CLEAR_CHOICES',\n };\n};\n\nexport const addGroup = (value, id, active, disabled) => {\n return {\n type: 'ADD_GROUP',\n value,\n id,\n active,\n disabled,\n };\n};\n\nexport const clearAll = () => {\n return {\n type: 'CLEAR_ALL',\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/actions/index.js","/* eslint-disable */\n/**\n * Capitalises the first letter of each word in a string\n * @param {String} str String to capitalise\n * @return {String} Capitalised string\n */\nexport const capitalise = function(str) {\n return str.replace(/\\w\\S*/g, function(txt) {\n return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();\n });\n};\n\n/**\n * Tests the type of an object\n * @param {String} type Type to test object against\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const getType = function(obj) {\n return Object.prototype.toString.call(obj).slice(8, -1);\n};\n\n/**\n * Tests the type of an object\n * @param {String} type Type to test object against\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const isType = function(type, obj) {\n var clas = getType(obj);\n return obj !== undefined && obj !== null && clas === type;\n};\n\n/**\n * Tests to see if a passed object is a node\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const isNode = (o) => {\n return (\n typeof Node === \"object\" ? o instanceof Node :\n o && typeof o === \"object\" && typeof o.nodeType === \"number\" && typeof o.nodeName === \"string\"\n );\n};\n\n/**\n * Tests to see if a passed object is an element\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const isElement = (o) => {\n return (\n typeof HTMLElement === \"object\" ? o instanceof HTMLElement : //DOM2\n o && typeof o === \"object\" && o !== null && o.nodeType === 1 && typeof o.nodeName === \"string\"\n );\n};\n\n/**\n * Merges unspecified amount of objects into new object\n * @private\n * @return {Object} Merged object of arguments\n */\nexport const extend = function() {\n let extended = {};\n let length = arguments.length;\n\n /**\n * Merge one object into another\n * @param {Object} obj Object to merge into extended object\n */\n let merge = function(obj) {\n for (let prop in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n // If deep merge and property is an object, merge properties\n if (isType('Object', obj[prop])) {\n extended[prop] = extend(true, extended[prop], obj[prop]);\n } else {\n extended[prop] = obj[prop];\n }\n }\n }\n };\n\n // Loop through each passed argument\n for (let i = 0; i < length; i++) {\n // store argument at position i\n let obj = arguments[i];\n\n // If we are in fact dealing with an object, merge it.\n if (isType('Object', obj)) {\n merge(obj);\n }\n }\n\n return extended;\n};\n\n/**\n * CSS transition end event listener\n * @return\n */\nexport const whichTransitionEvent = function() {\n var t,\n el = document.createElement(\"fakeelement\");\n\n var transitions = {\n \"transition\": \"transitionend\",\n \"OTransition\": \"oTransitionEnd\",\n \"MozTransition\": \"transitionend\",\n \"WebkitTransition\": \"webkitTransitionEnd\"\n }\n\n for (t in transitions) {\n if (el.style[t] !== undefined) {\n return transitions[t];\n }\n }\n};\n\n/**\n * CSS animation end event listener\n * @return\n */\nexport const whichAnimationEvent = function() {\n var t,\n el = document.createElement('fakeelement');\n\n var animations = {\n 'animation': 'animationend',\n 'OAnimation': 'oAnimationEnd',\n 'MozAnimation': 'animationend',\n 'WebkitAnimation': 'webkitAnimationEnd'\n };\n\n for (t in animations) {\n if (el.style[t] !== undefined) {\n return animations[t];\n }\n }\n};\n\n/**\n * Get the ancestors of each element in the current set of matched elements,\n * up to but not including the element matched by the selector\n * @param {NodeElement} elem Element to begin search from\n * @param {NodeElement} parent Parent to find\n * @param {String} selector Class to find\n * @return {Array} Array of parent elements\n */\nexport const getParentsUntil = function(elem, parent, selector) {\n var parents = [];\n // Get matches\n for (; elem && elem !== document; elem = elem.parentNode) {\n\n // Check if parent has been reached\n if (parent) {\n\n var parentType = parent.charAt(0);\n\n // If parent is a class\n if (parentType === '.') {\n if (elem.classList.contains(parent.substr(1))) {\n break;\n }\n }\n\n // If parent is an ID\n if (parentType === '#') {\n if (elem.id === parent.substr(1)) {\n break;\n }\n }\n\n // If parent is a data attribute\n if (parentType === '[') {\n if (elem.hasAttribute(parent.substr(1, parent.length - 1))) {\n break;\n }\n }\n\n // If parent is a tag\n if (elem.tagName.toLowerCase() === parent) {\n break;\n }\n\n }\n if (selector) {\n var selectorType = selector.charAt(0);\n\n // If selector is a class\n if (selectorType === '.') {\n if (elem.classList.contains(selector.substr(1))) {\n parents.push(elem);\n }\n }\n\n // If selector is an ID\n if (selectorType === '#') {\n if (elem.id === selector.substr(1)) {\n parents.push(elem);\n }\n }\n\n // If selector is a data attribute\n if (selectorType === '[') {\n if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {\n parents.push(elem);\n }\n }\n\n // If selector is a tag\n if (elem.tagName.toLowerCase() === selector) {\n parents.push(elem);\n }\n\n } else {\n parents.push(elem);\n }\n }\n\n // Return parents if any exist\n if (parents.length === 0) {\n return null;\n } else {\n return parents;\n }\n};\n\nexport const wrap = function(element, wrapper) {\n wrapper = wrapper || document.createElement('div');\n if (element.nextSibling) {\n element.parentNode.insertBefore(wrapper, element.nextSibling);\n } else {\n element.parentNode.appendChild(wrapper);\n }\n return wrapper.appendChild(element);\n};\n\nexport const getSiblings = function(elem) {\n var siblings = [];\n var sibling = elem.parentNode.firstChild;\n for (; sibling; sibling = sibling.nextSibling) {\n if (sibling.nodeType === 1 && sibling !== elem) {\n siblings.push(sibling);\n }\n }\n return siblings;\n};\n\n/**\n * Find ancestor in DOM tree\n * @param {NodeElement} el Element to start search from\n * @param {[type]} cls Class of parent\n * @return {NodeElement} Found parent element\n */\nexport const findAncestor = function(el, cls) {\n while ((el = el.parentElement) && !el.classList.contains(cls));\n return el;\n};\n\n/**\n * Find ancestor in DOM tree by attribute name\n * @param {NodeElement} el Element to start search from\n * @param {string} attr Attribute name of parent\n * @return {?NodeElement} Found parent element or null\n */\nexport const findAncestorByAttr = function(el, attr) {\n let target = el;\n\n while (target) {\n if (target.hasAttribute(attr)) {\n return target;\n }\n\n target = target.parentElement;\n }\n\n return null;\n};\n\n/**\n * Debounce an event handler.\n * @param {Function} func Function to run after wait\n * @param {Number} wait The delay before the function is executed\n * @param {Boolean} immediate If passed, trigger the function on the leading edge, instead of the trailing.\n * @return {Function} A function will be called after it stops being called for a given delay\n */\nexport const debounce = function(func, wait, immediate) {\n var timeout;\n return function() {\n var context = this,\n args = arguments;\n var later = function() {\n timeout = null;\n if (!immediate) func.apply(context, args);\n };\n var callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) func.apply(context, args);\n };\n};\n\n/**\n * Get an element's distance from the top of the page\n * @private\n * @param {NodeElement} el Element to test for\n * @return {Number} Elements Distance from top of page\n */\nexport const getElemDistance = function(el) {\n var location = 0;\n if (el.offsetParent) {\n do {\n location += el.offsetTop;\n el = el.offsetParent;\n } while (el);\n }\n return location >= 0 ? location : 0;\n};\n\n/**\n * Determine element height multiplied by any offsets\n * @private\n * @param {HTMLElement} el Element to test for\n * @return {Number} Height of element\n */\nexport const getElementOffset = function(el, offset) {\n var elOffset = offset;\n if (elOffset > 1) elOffset = 1;\n if (elOffset > 0) elOffset = 0;\n\n return Math.max(el.offsetHeight * elOffset);\n};\n\n/**\n * Get the next or previous element from a given start point\n * @param {HTMLElement} startEl Element to start position from\n * @param {String} className The class we will look through\n * @param {Number} direction Positive next element, negative previous element\n * @return {[HTMLElement} Found element\n */\nexport const getAdjacentEl = (startEl, className, direction = 1) => {\n if (!startEl || !className) return;\n\n const parent = startEl.parentNode.parentNode;\n const children = Array.from(parent.querySelectorAll(className));\n\n const startPos = children.indexOf(startEl);\n const operatorDirection = direction > 0 ? 1 : -1;\n\n return children[startPos + operatorDirection];\n};\n\n/**\n * Get scroll position based on top/bottom position\n * @private\n * @return {String} Position of scroll\n */\nexport const getScrollPosition = function(position) {\n if (position === 'bottom') {\n // Scroll position from the bottom of the viewport\n return Math.max((window.scrollY || window.pageYOffset) + (window.innerHeight || document.documentElement.clientHeight));\n } else {\n // Scroll position from the top of the viewport\n return (window.scrollY || window.pageYOffset);\n }\n};\n\n/**\n * Determine whether an element is within the viewport\n * @param {HTMLElement} el Element to test\n * @return {String} Position of scroll\n * @return {Boolean}\n */\nexport const isInView = function(el, position, offset) {\n // If the user has scrolled further than the distance from the element to the top of its parent\n return this.getScrollPosition(position) > (this.getElemDistance(el) + this.getElementOffset(el, offset)) ? true : false;\n};\n\n/**\n * Determine whether an element is within\n * @param {HTMLElement} el Element to test\n * @param {HTMLElement} parent Scrolling parent\n * @param {Number} direction Whether element is visible from above or below\n * @return {Boolean}\n */\nexport const isScrolledIntoView = (el, parent, direction = 1) => {\n if (!el) return;\n\n let isVisible;\n\n if (direction > 0) {\n // In view from bottom\n isVisible = (parent.scrollTop + parent.offsetHeight) >= (el.offsetTop + el.offsetHeight);\n } else {\n // In view from top\n isVisible = el.offsetTop >= parent.scrollTop;\n }\n\n return isVisible;\n};\n\n/**\n * Remove html tags from a string\n * @param {String} Initial string/html\n * @return {String} Sanitised string\n */\nexport const stripHTML = function(html) {\n let el = document.createElement(\"DIV\");\n el.innerHTML = html;\n return el.textContent || el.innerText || \"\";\n};\n\n/**\n * Adds animation to an element and removes it upon animation completion\n * @param {Element} el Element to add animation to\n * @param {String} animation Animation class to add to element\n * @return\n */\nexport const addAnimation = (el, animation) => {\n let animationEvent = whichAnimationEvent();\n\n let removeAnimation = () => {\n el.classList.remove(animation);\n el.removeEventListener(animationEvent, removeAnimation, false);\n };\n\n el.classList.add(animation);\n el.addEventListener(animationEvent, removeAnimation, false);\n};\n\n\n/**\n * Get a random number between a range\n * @param {Number} min Minimum range\n * @param {Number} max Maximum range\n * @return {Number} Random number\n */\nexport const getRandomNumber = function(min, max) {\n return Math.floor(Math.random() * (max - min) + min);\n};\n\n/**\n * Turn a string into a node\n * @param {String} String to convert\n * @return {HTMLElement} Converted node element\n */\nexport const strToEl = (function() {\n var tmpEl = document.createElement('div');\n return function(str) {\n var r;\n tmpEl.innerHTML = str;\n r = tmpEl.children[0];\n\n while (tmpEl.firstChild) {\n tmpEl.removeChild(tmpEl.firstChild);\n }\n\n return r;\n };\n}());\n\n/**\n * Sets the width of a passed input based on its value\n * @return {Number} Width of input\n */\nexport const getWidthOfInput = (input) => {\n const value = input.value || input.placeholder;\n let width = input.offsetWidth;\n\n if (value) {\n const testEl = strToEl(`${ value }`);\n testEl.style.position = 'absolute';\n testEl.style.padding = '0';\n testEl.style.top = '-9999px';\n testEl.style.left = '-9999px';\n testEl.style.width = 'auto';\n testEl.style.whiteSpace = 'pre';\n\n document.body.appendChild(testEl);\n\n if (value && testEl.offsetWidth !== input.offsetWidth) {\n width = testEl.offsetWidth + 4;\n }\n\n document.body.removeChild(testEl);\n }\n\n return `${width}px`;\n};\n\n/**\n * Sorting function for current and previous string\n * @param {String} a Current value\n * @param {String} b Next value\n * @return {Number} -1 for after previous,\n * 1 for before,\n * 0 for same location\n */\nexport const sortByAlpha = (a, b) => {\n const labelA = (a.label || a.value).toLowerCase();\n const labelB = (b.label || b.value).toLowerCase();\n\n if (labelA < labelB) return -1;\n if (labelA > labelB) return 1;\n return 0;\n};\n\n/**\n * Sort by numeric score\n * @param {Object} a Current value\n * @param {Object} b Next value\n * @return {Number} -1 for after previous,\n * 1 for before,\n * 0 for same location\n */\nexport const sortByScore = (a, b) => {\n return a.score - b.score;\n};\n\n/**\n * Trigger native event\n * @param {NodeElement} element Element to trigger event on\n * @param {String} type Type of event to trigger\n * @param {Object} customArgs Data to pass with event\n * @return {Object} Triggered event\n */\nexport const triggerEvent = (element, type, customArgs = null) => {\n const event = new CustomEvent(type, {\n detail: customArgs,\n bubbles: true,\n cancelable: true\n });\n\n return element.dispatchEvent(event);\n};\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/lib/utils.js","/* eslint-disable */\n(function () {\n // Production steps of ECMA-262, Edition 6, 22.1.2.1\n // Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from\n if (!Array.from) {\n Array.from = (function() {\n var toStr = Object.prototype.toString;\n\n var isCallable = function(fn) {\n return typeof fn === 'function' || toStr.call(fn) === '[object Function]';\n };\n\n var toInteger = function(value) {\n var number = Number(value);\n if (isNaN(number)) {\n return 0;\n }\n if (number === 0 || !isFinite(number)) {\n return number;\n }\n return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));\n };\n\n var maxSafeInteger = Math.pow(2, 53) - 1;\n\n var toLength = function(value) {\n var len = toInteger(value);\n return Math.min(Math.max(len, 0), maxSafeInteger);\n };\n\n // The length property of the from method is 1.\n return function from(arrayLike /*, mapFn, thisArg */ ) {\n // 1. Let C be the this value.\n var C = this;\n\n // 2. Let items be ToObject(arrayLike).\n var items = Object(arrayLike);\n\n // 3. ReturnIfAbrupt(items).\n if (arrayLike == null) {\n throw new TypeError(\"Array.from requires an array-like object - not null or undefined\");\n }\n\n // 4. If mapfn is undefined, then let mapping be false.\n var mapFn = arguments.length > 1 ? arguments[1] : void undefined;\n var T;\n if (typeof mapFn !== 'undefined') {\n // 5. else\n // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.\n if (!isCallable(mapFn)) {\n throw new TypeError('Array.from: when provided, the second argument must be a function');\n }\n\n // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.\n if (arguments.length > 2) {\n T = arguments[2];\n }\n }\n\n // 10. Let lenValue be Get(items, \"length\").\n // 11. Let len be ToLength(lenValue).\n var len = toLength(items.length);\n\n // 13. If IsConstructor(C) is true, then\n // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.\n // 14. a. Else, Let A be ArrayCreate(len).\n var A = isCallable(C) ? Object(new C(len)) : new Array(len);\n\n // 16. Let k be 0.\n var k = 0;\n // 17. Repeat, while k < len… (also steps a - h)\n var kValue;\n while (k < len) {\n kValue = items[k];\n if (mapFn) {\n A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);\n } else {\n A[k] = kValue;\n }\n k += 1;\n }\n // 18. Let putStatus be Put(A, \"length\", len, true).\n A.length = len;\n // 20. Return A.\n return A;\n };\n }());\n }\n\n // Reference: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find\n if (!Array.prototype.find) {\n Array.prototype.find = function(predicate) {\n 'use strict';\n if (this == null) {\n throw new TypeError('Array.prototype.find called on null or undefined');\n }\n if (typeof predicate !== 'function') {\n throw new TypeError('predicate must be a function');\n }\n var list = Object(this);\n var length = list.length >>> 0;\n var thisArg = arguments[1];\n var value;\n\n for (var i = 0; i < length; i++) {\n value = list[i];\n if (predicate.call(thisArg, value, i, list)) {\n return value;\n }\n }\n return undefined;\n };\n }\n\n function CustomEvent (event, params) {\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n var evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n }\n\n CustomEvent.prototype = window.Event.prototype;\n\n window.CustomEvent = CustomEvent;\n})();\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/lib/polyfills.js"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACtCA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAWA;AACA;AAeA;AACA;;;;;;;;;AAEA;;;AAGA;AACA;AAAA;AACA;AADA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAxBA;AA0BA;AACA;AADA;AAGA;AACA;AAhEA;AACA;AAkEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AAQA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AASA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AAQA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAzBA;AACA;AA2BA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA3CA;AACA;AA6CA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AAUA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AASA;AAAA;AACA;AADA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AAHA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAKA;AACA;AAKA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AAzEA;AACA;AA2EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAEA;;;;;;AC9uEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACxzBA;AACA;AAAA;AACA;;;;;;;AACA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AACA;;;;;;;;AAIA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AA7JA;AACA;AACA;AA8JA;;;;;;ACnKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5BA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AACA;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACvBA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AA1CA;AA4CA;AACA;;;;;;;;;;;;;;;AC9CA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAhBA;AAkBA;AACA;;;;;;;;;;;;;;;ACpBA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AA3FA;AA6FA;AACA;;;;;;;;;;;;AC/FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AACA;AACA;AACA;AACA;AADA;AAGA;;;;;;;;;;;;;;ACxEA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AAIA;AACA;AACA;;;;;AAKA;AACA;AAEA;AAEA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAHA;AACA;AAKA;;;;;;;;;ACthBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;","sourceRoot":""} \ No newline at end of file +{"version":3,"file":"choices.js","sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap e130c7337988713df4f7","webpack:///assets/scripts/src/choices.js","webpack:///./~/fuse.js/src/fuse.js","webpack:///assets/scripts/src/store/index.js","webpack:///./~/redux/lib/index.js","webpack:///./~/redux/lib/createStore.js","webpack:///./~/lodash/isPlainObject.js","webpack:///./~/lodash/_baseGetTag.js","webpack:///./~/lodash/_Symbol.js","webpack:///./~/lodash/_root.js","webpack:///./~/lodash/_freeGlobal.js","webpack:///./~/lodash/_getRawTag.js","webpack:///./~/lodash/_objectToString.js","webpack:///./~/lodash/_getPrototype.js","webpack:///./~/lodash/_overArg.js","webpack:///./~/lodash/isObjectLike.js","webpack:///./~/symbol-observable/index.js","webpack:///./~/symbol-observable/lib/index.js","webpack:///(webpack)/buildin/module.js","webpack:///./~/symbol-observable/lib/ponyfill.js","webpack:///./~/redux/lib/combineReducers.js","webpack:///./~/redux/lib/utils/warning.js","webpack:///./~/redux/lib/bindActionCreators.js","webpack:///./~/redux/lib/applyMiddleware.js","webpack:///./~/redux/lib/compose.js","webpack:///assets/scripts/src/reducers/index.js","webpack:///assets/scripts/src/reducers/items.js","webpack:///assets/scripts/src/reducers/groups.js","webpack:///assets/scripts/src/reducers/choices.js","webpack:///assets/scripts/src/actions/index.js","webpack:///assets/scripts/src/lib/utils.js","webpack:///assets/scripts/src/lib/polyfills.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"Choices\"] = factory();\n\telse\n\t\troot[\"Choices\"] = factory();\n})(this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/assets/scripts/dist/\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap e130c7337988713df4f7","import Fuse from 'fuse.js';\nimport Store from './store/index.js';\nimport {\n addItem,\n removeItem,\n highlightItem,\n addChoice,\n filterChoices,\n activateChoices,\n addGroup,\n clearAll,\n clearChoices,\n}\nfrom './actions/index';\nimport {\n isScrolledIntoView,\n getAdjacentEl,\n wrap,\n getType,\n isType,\n isElement,\n strToEl,\n extend,\n getWidthOfInput,\n sortByAlpha,\n sortByScore,\n triggerEvent,\n findAncestorByAttrName\n}\nfrom './lib/utils.js';\nimport './lib/polyfills.js';\n\n\n/**\n * Choices\n */\nclass Choices {\n constructor(element = '[data-choice]', userConfig = {}) {\n // If there are multiple elements, create a new instance\n // for each element besides the first one (as that already has an instance)\n if (isType('String', element)) {\n const elements = document.querySelectorAll(element);\n if (elements.length > 1) {\n for (let i = 1; i < elements.length; i++) {\n const el = elements[i];\n new Choices(el, userConfig);\n }\n }\n }\n\n const defaultConfig = {\n items: [],\n choices: [],\n maxItemCount: -1,\n addItems: true,\n removeItems: true,\n removeItemButton: false,\n editItems: false,\n duplicateItems: true,\n delimiter: ',',\n paste: true,\n search: true,\n searchFloor: 1,\n position: 'auto',\n resetScrollPosition: true,\n regexFilter: null,\n shouldSort: true,\n sortFilter: sortByAlpha,\n sortFields: ['label', 'value'],\n placeholder: true,\n placeholderValue: null,\n prependValue: null,\n appendValue: null,\n loadingText: 'Loading...',\n noResultsText: 'No results found',\n noChoicesText: 'No choices to choose from',\n itemSelectText: 'Press to select',\n addItemText: (value) => {\n return `Press Enter to add \"${value}\"`;\n },\n maxItemText: (maxItemCount) => {\n return `Only ${maxItemCount} values can be added.`;\n },\n uniqueItemText: 'Only unique values can be added.',\n classNames: {\n containerOuter: 'choices',\n containerInner: 'choices__inner',\n input: 'choices__input',\n inputCloned: 'choices__input--cloned',\n list: 'choices__list',\n listItems: 'choices__list--multiple',\n listSingle: 'choices__list--single',\n listDropdown: 'choices__list--dropdown',\n item: 'choices__item',\n itemSelectable: 'choices__item--selectable',\n itemDisabled: 'choices__item--disabled',\n itemChoice: 'choices__item--choice',\n placeholder: 'choices__placeholder',\n group: 'choices__group',\n groupHeading: 'choices__heading',\n button: 'choices__button',\n activeState: 'is-active',\n focusState: 'is-focused',\n openState: 'is-open',\n disabledState: 'is-disabled',\n highlightedState: 'is-highlighted',\n hiddenState: 'is-hidden',\n flippedState: 'is-flipped',\n loadingState: 'is-loading',\n },\n fuseOptions: {\n include: 'score',\n },\n callbackOnInit: null,\n callbackOnCreateTemplates: null,\n };\n\n // Merge options with user options\n this.config = extend(defaultConfig, userConfig);\n\n // Create data store\n this.store = new Store(this.render);\n\n // State tracking\n this.initialised = false;\n this.currentState = {};\n this.prevState = {};\n this.currentValue = '';\n\n // Retrieve triggering element (i.e. element with 'data-choice' trigger)\n this.element = element;\n this.passedElement = isType('String', element) ? document.querySelector(element) : element;\n this.isSelectElement = this.passedElement.type === 'select-one' || this.passedElement.type === 'select-multiple';\n this.isTextElement = this.passedElement.type === 'text';\n\n if (!this.passedElement) {\n console.error('Passed element not found');\n return;\n }\n\n this.highlightPosition = 0;\n this.canSearch = this.config.search;\n\n // Assing preset choices from passed object\n this.presetChoices = this.config.choices;\n\n // Assign preset items from passed object first\n this.presetItems = this.config.items;\n\n // Then add any values passed from attribute\n if (this.passedElement.value) {\n this.presetItems = this.presetItems.concat(this.passedElement.value.split(this.config.delimiter));\n }\n\n // Bind methods\n this.init = this.init.bind(this);\n this.render = this.render.bind(this);\n this.destroy = this.destroy.bind(this);\n this.disable = this.disable.bind(this);\n\n // Bind event handlers\n this._onFocus = this._onFocus.bind(this);\n this._onBlur = this._onBlur.bind(this);\n this._onKeyUp = this._onKeyUp.bind(this);\n this._onKeyDown = this._onKeyDown.bind(this);\n this._onClick = this._onClick.bind(this);\n this._onTouchMove = this._onTouchMove.bind(this);\n this._onTouchEnd = this._onTouchEnd.bind(this);\n this._onMouseDown = this._onMouseDown.bind(this);\n this._onMouseOver = this._onMouseOver.bind(this);\n this._onPaste = this._onPaste.bind(this);\n this._onInput = this._onInput.bind(this);\n\n // Monitor touch taps/scrolls\n this.wasTap = true;\n\n // Cutting the mustard\n const cuttingTheMustard = 'classList' in document.documentElement;\n if (!cuttingTheMustard) console.error('Choices: Your browser doesn\\'t support Choices');\n\n // Input type check\n const isValidType = ['select-one', 'select-multiple', 'text'].some(type => type === this.passedElement.type);\n const canInit = isElement(this.passedElement) && isValidType;\n\n if (canInit) {\n // If element has already been initalised with Choices\n if (this.passedElement.getAttribute('data-choice') === 'active') return;\n\n // Let's go\n this.init();\n } else {\n console.error('Incompatible input passed');\n }\n }\n\n /*========================================\n = Public functions =\n ========================================*/\n\n /**\n * Initialise Choices\n * @return\n * @public\n */\n init() {\n if (this.initialised === true) return;\n\n const callback = this.config.callbackOnInit;\n\n // Set initialise flag\n this.initialised = true;\n // Create required elements\n this._createTemplates();\n // Generate input markup\n this._createInput();\n // Subscribe store to render method\n this.store.subscribe(this.render);\n // Render any items\n this.render();\n // Trigger event listeners\n this._addEventListeners();\n\n // Run callback if it is a function\n if (callback) {\n if (isType('Function', callback)) {\n callback.call(this);\n }\n }\n }\n\n /**\n * Destroy Choices and nullify values\n * @return\n * @public\n */\n destroy() {\n if (this.initialised === false) return;\n\n // Remove all event listeners\n this._removeEventListeners();\n\n // Reinstate passed element\n this.passedElement.classList.remove(this.config.classNames.input, this.config.classNames.hiddenState);\n this.passedElement.removeAttribute('tabindex');\n this.passedElement.removeAttribute('style', 'display:none;');\n this.passedElement.removeAttribute('aria-hidden');\n this.passedElement.removeAttribute('data-choice', 'active');\n\n // Re-assign values - this is weird, I know\n this.passedElement.value = this.passedElement.value;\n\n // Move passed element back to original position\n this.containerOuter.parentNode.insertBefore(this.passedElement, this.containerOuter);\n // Remove added elements\n this.containerOuter.parentNode.removeChild(this.containerOuter);\n\n // Clear data store\n this.clearStore();\n\n // Nullify instance-specific data\n this.config.templates = null;\n\n // Uninitialise\n this.initialised = false;\n }\n\n /**\n * Render group choices into a DOM fragment and append to choice list\n * @param {Array} groups Groups to add to list\n * @param {Array} choices Choices to add to groups\n * @param {DocumentFragment} fragment Fragment to add groups and options to (optional)\n * @return {DocumentFragment} Populated options fragment\n * @private\n */\n renderGroups(groups, choices, fragment) {\n const groupFragment = fragment || document.createDocumentFragment();\n const filter = this.config.sortFilter;\n\n // If sorting is enabled, filter groups\n if (this.config.shouldSort) {\n groups.sort(filter);\n }\n\n groups.forEach((group) => {\n // Grab options that are children of this group\n const groupChoices = choices.filter((choice) => {\n if (this.passedElement.type === 'select-one') {\n return choice.groupId === group.id;\n }\n return choice.groupId === group.id && !choice.selected;\n });\n\n if (groupChoices.length >= 1) {\n const dropdownGroup = this._getTemplate('choiceGroup', group);\n groupFragment.appendChild(dropdownGroup);\n this.renderChoices(groupChoices, groupFragment);\n }\n });\n\n return groupFragment;\n }\n\n /**\n * Render choices into a DOM fragment and append to choice list\n * @param {Array} choices Choices to add to list\n * @param {DocumentFragment} fragment Fragment to add choices to (optional)\n * @return {DocumentFragment} Populated choices fragment\n * @private\n */\n renderChoices(choices, fragment) {\n // Create a fragment to store our list items (so we don't have to update the DOM for each item)\n const choicesFragment = fragment || document.createDocumentFragment();\n const filter = this.isSearching ? sortByScore : this.config.sortFilter;\n\n // If sorting is enabled or the user is searching, filter choices\n if (this.config.shouldSort || this.isSearching) {\n choices.sort(filter);\n }\n\n choices.forEach((choice) => {\n const dropdownItem = this._getTemplate('choice', choice);\n const shouldRender = this.passedElement.type === 'select-one' || !choice.selected;\n if (shouldRender) {\n choicesFragment.appendChild(dropdownItem);\n }\n });\n\n return choicesFragment;\n }\n\n /**\n * Render items into a DOM fragment and append to items list\n * @param {Array} items Items to add to list\n * @param {DocumentFragment} fragment Fragrment to add items to (optional)\n * @return\n * @private\n */\n renderItems(items, fragment) {\n // Create fragment to add elements to\n const itemListFragment = fragment || document.createDocumentFragment();\n // Simplify store data to just values\n const itemsFiltered = this.store.getItemsReducedToValues(items);\n\n if (this.isTextElement) {\n // Assign hidden input array of values\n this.passedElement.setAttribute('value', itemsFiltered.join(this.config.delimiter));\n } else {\n const selectedOptionsFragment = document.createDocumentFragment();\n\n // Add each list item to list\n items.forEach((item) => {\n // Create a standard select option\n const option = this._getTemplate('option', item);\n // Append it to fragment\n selectedOptionsFragment.appendChild(option);\n });\n\n // Update selected choices\n this.passedElement.innerHTML = '';\n this.passedElement.appendChild(selectedOptionsFragment);\n }\n\n // Add each list item to list\n items.forEach((item) => {\n // Create new list element\n const listItem = this._getTemplate('item', item);\n // Append it to list\n itemListFragment.appendChild(listItem);\n });\n\n return itemListFragment;\n }\n\n /**\n * Render DOM with values\n * @return\n * @private\n */\n render() {\n this.currentState = this.store.getState();\n\n // Only render if our state has actually changed\n if (this.currentState !== this.prevState) {\n // Choices\n if (this.currentState.choices !== this.prevState.choices ||\n this.currentState.groups !== this.prevState.groups) {\n if (this.passedElement.type === 'select-multiple' ||\n this.passedElement.type === 'select-one') {\n // Get active groups/choices\n const activeGroups = this.store.getGroupsFilteredByActive();\n const activeChoices = this.store.getChoicesFilteredByActive();\n\n let choiceListFragment = document.createDocumentFragment();\n\n // Clear choices\n this.choiceList.innerHTML = '';\n\n // Scroll back to top of choices list\n if(this.config.resetScrollPosition){\n this.choiceList.scrollTop = 0;\n }\n\n // If we have grouped options\n if (activeGroups.length >= 1 && this.isSearching !== true) {\n choiceListFragment = this.renderGroups(activeGroups, activeChoices, choiceListFragment);\n } else if (activeChoices.length >= 1) {\n choiceListFragment = this.renderChoices(activeChoices, choiceListFragment);\n }\n\n if (choiceListFragment.childNodes && choiceListFragment.childNodes.length > 0) {\n // If we actually have anything to add to our dropdown\n // append it and highlight the first choice\n this.choiceList.appendChild(choiceListFragment);\n this._highlightChoice();\n } else {\n // Otherwise show a notice\n let dropdownItem;\n let notice;\n\n if (this.isSearching) {\n notice = isType('Function', this.config.noResultsText) ? this.config.noResultsText() : this.config.noResultsText;\n dropdownItem = this._getTemplate('notice', notice);\n } else {\n notice = isType('Function', this.config.noChoicesText) ? this.config.noChoicesText() : this.config.noChoicesText;\n dropdownItem = this._getTemplate('notice', notice);\n }\n\n this.choiceList.appendChild(dropdownItem);\n }\n }\n }\n\n // Items\n if (this.currentState.items !== this.prevState.items) {\n const activeItems = this.store.getItemsFilteredByActive();\n if (activeItems) {\n // Create a fragment to store our list items\n // (so we don't have to update the DOM for each item)\n const itemListFragment = this.renderItems(activeItems);\n\n // Clear list\n this.itemList.innerHTML = '';\n\n // If we have items to add\n if (itemListFragment.childNodes) {\n // Update list\n this.itemList.appendChild(itemListFragment);\n }\n }\n }\n\n this.prevState = this.currentState;\n }\n }\n\n /**\n * Select item (a selected item can be deleted)\n * @param {Element} item Element to select\n * @return {Object} Class instance\n * @public\n */\n highlightItem(item, runEvent = true) {\n if (!item) return;\n const id = item.id;\n const groupId = item.groupId;\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n this.store.dispatch(highlightItem(id, true));\n\n if (runEvent) {\n if(group && group.value) {\n triggerEvent(this.passedElement, 'highlightItem', {\n id,\n value: item.value,\n label: item.label,\n groupValue: group.value\n });\n } else {\n triggerEvent(this.passedElement, 'highlightItem', {\n id,\n value: item.value,\n label: item.label,\n });\n }\n }\n\n return this;\n }\n\n /**\n * Deselect item\n * @param {Element} item Element to de-select\n * @return {Object} Class instance\n * @public\n */\n unhighlightItem(item) {\n if (!item) return;\n const id = item.id;\n const groupId = item.groupId;\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n this.store.dispatch(highlightItem(id, false));\n\n if(group && group.value) {\n triggerEvent(this.passedElement, 'unhighlightItem', {\n id,\n value: item.value,\n label: item.label,\n groupValue: group.value\n });\n } else {\n triggerEvent(this.passedElement, 'unhighlightItem', {\n id,\n value: item.value,\n label: item.label,\n });\n }\n\n return this;\n }\n\n /**\n * Highlight items within store\n * @return {Object} Class instance\n * @public\n */\n highlightAll() {\n const items = this.store.getItems();\n items.forEach((item) => {\n this.highlightItem(item);\n });\n\n return this;\n }\n\n /**\n * Deselect items within store\n * @return {Object} Class instance\n * @public\n */\n unhighlightAll() {\n const items = this.store.getItems();\n items.forEach((item) => {\n this.unhighlightItem(item);\n });\n\n return this;\n }\n\n /**\n * Remove an item from the store by its value\n * @param {String} value Value to search for\n * @return {Object} Class instance\n * @public\n */\n removeItemsByValue(value) {\n if (!value || !isType('String', value)) {\n console.error('removeItemsByValue: No value was passed to be removed');\n return;\n }\n\n const items = this.store.getItemsFilteredByActive();\n\n items.forEach((item) => {\n if (item.value === value) {\n this._removeItem(item);\n }\n });\n\n return this;\n }\n\n /**\n * Remove all items from store array\n * @note Removed items are soft deleted\n * @param {Number} excludedId Optionally exclude item by ID\n * @return {Object} Class instance\n * @public\n */\n removeActiveItems(excludedId) {\n const items = this.store.getItemsFilteredByActive();\n\n items.forEach((item) => {\n if (item.active && excludedId !== item.id) {\n this._removeItem(item);\n }\n });\n\n return this;\n }\n\n /**\n * Remove all selected items from store\n * @note Removed items are soft deleted\n * @return {Object} Class instance\n * @public\n */\n removeHighlightedItems(runEvent = false) {\n const items = this.store.getItemsFilteredByActive();\n\n items.forEach((item) => {\n if (item.highlighted && item.active) {\n this._removeItem(item);\n // If this action was performed by the user\n // trigger the event\n if (runEvent) {\n this._triggerChange(item.value);\n }\n }\n });\n\n return this;\n }\n\n /**\n * Show dropdown to user by adding active state class\n * @return {Object} Class instance\n * @public\n */\n showDropdown(focusInput = false) {\n const body = document.body;\n const html = document.documentElement;\n const winHeight = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n this.containerOuter.classList.add(this.config.classNames.openState);\n this.containerOuter.setAttribute('aria-expanded', 'true');\n this.dropdown.classList.add(this.config.classNames.activeState);\n this.dropdown.setAttribute('aria-expanded', 'true');\n\n const dimensions = this.dropdown.getBoundingClientRect();\n const dropdownPos = Math.ceil(dimensions.top + window.scrollY + dimensions.height);\n\n // If flip is enabled and the dropdown bottom position is greater than the window height flip the dropdown.\n let shouldFlip = false;\n if (this.config.position === 'auto') {\n shouldFlip = dropdownPos >= winHeight;\n } else if (this.config.position === 'top') {\n shouldFlip = true;\n }\n\n if (shouldFlip) {\n this.containerOuter.classList.add(this.config.classNames.flippedState);\n } else {\n this.containerOuter.classList.remove(this.config.classNames.flippedState);\n }\n\n // Optionally focus the input if we have a search input\n if (focusInput && this.canSearch && document.activeElement !== this.input) {\n this.input.focus();\n }\n\n triggerEvent(this.passedElement, 'showDropdown', {});\n\n return this;\n }\n\n /**\n * Hide dropdown from user\n * @return {Object} Class instance\n * @public\n */\n hideDropdown(blurInput = false) {\n // A dropdown flips if it does not have space within the page\n const isFlipped = this.containerOuter.classList.contains(this.config.classNames.flippedState);\n\n this.containerOuter.classList.remove(this.config.classNames.openState);\n this.containerOuter.setAttribute('aria-expanded', 'false');\n this.dropdown.classList.remove(this.config.classNames.activeState);\n this.dropdown.setAttribute('aria-expanded', 'false');\n\n if (isFlipped) {\n this.containerOuter.classList.remove(this.config.classNames.flippedState);\n }\n\n // Optionally blur the input if we have a search input\n if (blurInput && this.canSearch && document.activeElement === this.input) {\n this.input.blur();\n }\n\n triggerEvent(this.passedElement, 'hideDropdown', {});\n\n return this;\n }\n\n /**\n * Determine whether to hide or show dropdown based on its current state\n * @return {Object} Class instance\n * @public\n */\n toggleDropdown() {\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n if (hasActiveDropdown) {\n this.hideDropdown();\n } else {\n this.showDropdown(true);\n }\n\n return this;\n }\n\n /**\n * Get value(s) of input (i.e. inputted items (text) or selected choices (select))\n * @param {Boolean} valueOnly Get only values of selected items, otherwise return selected items\n * @return {Array/String} selected value (select-one) or array of selected items (inputs & select-multiple)\n * @public\n */\n getValue(valueOnly = false) {\n const items = this.store.getItemsFilteredByActive();\n const selectedItems = [];\n\n items.forEach((item) => {\n if (this.isTextElement) {\n selectedItems.push(valueOnly ? item.value : item);\n } else if (item.active) {\n selectedItems.push(valueOnly ? item.value : item);\n }\n });\n\n if (this.passedElement.type === 'select-one') {\n return selectedItems[0];\n }\n\n return selectedItems;\n }\n\n /**\n * Set value of input. If the input is a select box, a choice will be created and selected otherwise\n * an item will created directly.\n * @param {Array} args Array of value objects or value strings\n * @return {Object} Class instance\n * @public\n */\n setValue(args) {\n if (this.initialised === true) {\n // Convert args to an iterable array\n const values = [...args],\n passedElementType = this.passedElement.type,\n handleValue = (item) => {\n const itemType = getType(item);\n if (itemType === 'Object') {\n if (!item.value) return;\n // If we are dealing with a select input, we need to create an option first\n // that is then selected. For text inputs we can just add items normally.\n if (passedElementType !== 'text') {\n this._addChoice(true, false, item.value, item.label, -1);\n } else {\n this._addItem(item.value, item.label, item.id);\n }\n } else if (itemType === 'String') {\n if (passedElementType !== 'text') {\n this._addChoice(true, false, item, item, -1);\n } else {\n this._addItem(item);\n }\n }\n };\n\n if (values.length > 1) {\n values.forEach((value) => {\n handleValue(value);\n });\n } else {\n handleValue(values[0]);\n }\n }\n return this;\n }\n\n /**\n * Select value of select box via the value of an existing choice\n * @param {Array/String} value An array of strings of a single string\n * @return {Object} Class instance\n * @public\n */\n setValueByChoice(value) {\n if (this.passedElement.type !== 'text') {\n const choices = this.store.getChoices();\n // If only one value has been passed, convert to array\n const choiceValue = isType('Array', value) ? value : [value];\n\n // Loop through each value and\n choiceValue.forEach((val) => {\n const foundChoice = choices.find((choice) => {\n // Check 'value' property exists and the choice isn't already selected\n return choice.value === val;\n });\n\n if (foundChoice) {\n if (!foundChoice.selected) {\n this._addItem(foundChoice.value, foundChoice.label, foundChoice.id, foundChoice.groupId);\n } else {\n console.warn('Attempting to select choice already selected');\n }\n } else {\n console.warn('Attempting to select choice that does not exist');\n }\n });\n }\n return this;\n }\n\n /**\n * Direct populate choices\n * @param {Array} choices - Choices to insert\n * @param {String} value - Name of 'value' property\n * @param {String} label - Name of 'label' property\n * @param {Boolean} replaceChoices Whether existing choices should be removed\n * @return {Object} Class instance\n * @public\n */\n setChoices(choices, value, label, replaceChoices = false) {\n if (this.initialised === true) {\n if (this.isSelectElement) {\n if (!isType('Array', choices) || !value) return;\n // Clear choices if needed\n if(replaceChoices) {\n this._clearChoices();\n }\n // Add choices if passed\n if (choices && choices.length) {\n this.containerOuter.classList.remove(this.config.classNames.loadingState);\n choices.forEach((result, index) => {\n const isSelected = result.selected ? result.selected : false;\n const isDisabled = result.disabled ? result.disabled : false;\n if (result.choices) {\n this._addGroup(result, (result.id || null), value, label);\n } else {\n this._addChoice(isSelected, isDisabled, result[value], result[label]);\n }\n });\n }\n }\n }\n return this;\n }\n\n /**\n * Clear items,choices and groups\n * @note Hard delete\n * @return {Object} Class instance\n * @public\n */\n clearStore() {\n this.store.dispatch(clearAll());\n return this;\n }\n\n /**\n * Set value of input to blank\n * @return {Object} Class instance\n * @public\n */\n clearInput() {\n if (this.input.value) this.input.value = '';\n if (this.passedElement.type !== 'select-one') {\n this._setInputWidth();\n }\n if (this.passedElement.type !== 'text' && this.config.search) {\n this.isSearching = false;\n this.store.dispatch(activateChoices(true));\n }\n return this;\n }\n\n /**\n * Enable interaction with Choices\n * @return {Object} Class instance\n */\n enable() {\n this.passedElement.disabled = false;\n const isDisabled = this.containerOuter.classList.contains(this.config.classNames.disabledState);\n if (this.initialised && isDisabled) {\n this._addEventListeners();\n this.passedElement.removeAttribute('disabled');\n this.input.removeAttribute('disabled');\n this.containerOuter.classList.remove(this.config.classNames.disabledState);\n this.containerOuter.removeAttribute('aria-disabled');\n }\n return this;\n }\n\n /**\n * Disable interaction with Choices\n * @return {Object} Class instance\n * @public\n */\n disable() {\n this.passedElement.disabled = true;\n const isEnabled = !this.containerOuter.classList.contains(this.config.classNames.disabledState);\n if (this.initialised && isEnabled) {\n this._removeEventListeners();\n this.passedElement.setAttribute('disabled', '');\n this.input.setAttribute('disabled', '');\n this.containerOuter.classList.add(this.config.classNames.disabledState);\n this.containerOuter.setAttribute('aria-disabled', 'true');\n }\n return this;\n }\n\n /**\n * Populate options via ajax callback\n * @param {Function} fn Passed\n * @return {Object} Class instance\n * @public\n */\n ajax(fn) {\n if (this.initialised === true) {\n if (this.isSelectElement) {\n // Show loading text\n this._handleLoadingState(true);\n // Run callback\n fn(this._ajaxCallback());\n }\n }\n return this;\n }\n\n /*===== End of Public functions ======*/\n\n /*=============================================\n = Private functions =\n =============================================*/\n\n /**\n * Call change callback\n * @param {String} value - last added/deleted/selected value\n * @return\n * @private\n */\n _triggerChange(value) {\n if (!value) return;\n\n triggerEvent(this.passedElement, 'change', {\n value\n });\n }\n\n /**\n * Process enter/click of an item button\n * @param {Array} activeItems The currently active items\n * @param {Element} element Button being interacted with\n * @return\n * @private\n */\n _handleButtonAction(activeItems, element) {\n if (!activeItems || !element) return;\n\n // If we are clicking on a button\n if (this.config.removeItems && this.config.removeItemButton) {\n const itemId = element.parentNode.getAttribute('data-id');\n const itemToRemove = activeItems.find((item) => item.id === parseInt(itemId, 10));\n\n // Remove item associated with button\n this._removeItem(itemToRemove);\n this._triggerChange(itemToRemove.value);\n\n if (this.passedElement.type === 'select-one') {\n const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') :\n false;\n if (placeholder) {\n const placeholderItem = this._getTemplate('placeholder', placeholder);\n this.itemList.appendChild(placeholderItem);\n }\n }\n }\n }\n\n /**\n * Process click of an item\n * @param {Array} activeItems The currently active items\n * @param {Element} element Item being interacted with\n * @param {Boolean} hasShiftKey Whether the user has the shift key active\n * @return\n * @private\n */\n _handleItemAction(activeItems, element, hasShiftKey = false) {\n if (!activeItems || !element) return;\n\n // If we are clicking on an item\n if (this.config.removeItems && this.passedElement.type !== 'select-one') {\n const passedId = element.getAttribute('data-id');\n\n // We only want to select one item with a click\n // so we deselect any items that aren't the target\n // unless shift is being pressed\n activeItems.forEach((item) => {\n if (item.id === parseInt(passedId, 10) && !item.highlighted) {\n this.highlightItem(item);\n } else if (!hasShiftKey) {\n if (item.highlighted) {\n this.unhighlightItem(item);\n }\n }\n });\n\n // Focus input as without focus, a user cannot do anything with a\n // highlighted item\n if (document.activeElement !== this.input) this.input.focus();\n }\n }\n\n /**\n * Process click of a choice\n * @param {Array} activeItems The currently active items\n * @param {Element} element Choice being interacted with\n * @return {[type]} [description]\n */\n _handleChoiceAction(activeItems, element) {\n if (!activeItems || !element) return;\n\n // If we are clicking on an option\n const id = element.getAttribute('data-id');\n const choice = this.store.getChoiceById(id);\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n\n triggerEvent(this.passedElement, 'choice', {\n choice,\n });\n\n if (choice && !choice.selected && !choice.disabled) {\n const canAddItem = this._canAddItem(activeItems, choice.value);\n\n if (canAddItem.response) {\n this._addItem(choice.value, choice.label, choice.id, choice.groupId);\n this._triggerChange(choice.value);\n }\n }\n\n this.clearInput(this.passedElement);\n\n // We wont to close the dropdown if we are dealing with a single select box\n if (hasActiveDropdown && this.passedElement.type === 'select-one') {\n this.hideDropdown();\n this.containerOuter.focus();\n }\n }\n\n /**\n * Process back space event\n * @param {Array} activeItems items\n * @return\n * @private\n */\n _handleBackspace(activeItems) {\n if (this.config.removeItems && activeItems) {\n const lastItem = activeItems[activeItems.length - 1];\n const hasHighlightedItems = activeItems.some((item) => item.highlighted === true);\n\n // If editing the last item is allowed and there are not other selected items,\n // we can edit the item value. Otherwise if we can remove items, remove all selected items\n if (this.config.editItems && !hasHighlightedItems && lastItem) {\n this.input.value = lastItem.value;\n this._setInputWidth();\n this._removeItem(lastItem);\n this._triggerChange(lastItem.value);\n } else {\n if (!hasHighlightedItems) {\n this.highlightItem(lastItem, false);\n }\n this.removeHighlightedItems(true);\n }\n }\n }\n\n /**\n * Validates whether an item can be added by a user\n * @param {Array} activeItems The currently active items\n * @param {String} value Value of item to add\n * @return {Object} Response: Whether user can add item\n * Notice: Notice show in dropdown\n */\n _canAddItem(activeItems, value) {\n let canAddItem = true;\n let notice = isType('Function', this.config.addItemText) ? this.config.addItemText(value) : this.config.addItemText;\n\n if (this.passedElement.type === 'select-multiple' || this.passedElement.type === 'text') {\n if (this.config.maxItemCount > 0 && this.config.maxItemCount <= this.itemList.children.length) {\n // If there is a max entry limit and we have reached that limit\n // don't update\n canAddItem = false;\n notice = isType('Function', this.config.maxItemText) ? this.config.maxItemText(this.config.maxItemCount) : this.config.maxItemText;\n }\n }\n\n if (this.passedElement.type === 'text' && this.config.addItems) {\n const isUnique = !activeItems.some((item) => item.value === value.trim());\n\n // If a user has supplied a regular expression filter\n if (this.config.regexFilter) {\n // Determine whether we can update based on whether\n // our regular expression passes\n canAddItem = this._regexFilter(value);\n }\n\n // If no duplicates are allowed, and the value already exists\n // in the array\n if (this.config.duplicateItems === false && !isUnique) {\n canAddItem = false;\n notice = isType('Function', this.config.uniqueItemText) ? this.config.uniqueItemText(value) : this.config.uniqueItemText;\n }\n }\n\n return {\n response: canAddItem,\n notice,\n };\n }\n\n /**\n * Apply or remove a loading state to the component.\n * @param {Boolean} isLoading default value set to 'true'.\n * @return\n * @private\n */\n _handleLoadingState(isLoading = true) {\n let placeholderItem = this.itemList.querySelector(`.${this.config.classNames.placeholder}`);\n if(isLoading) {\n this.containerOuter.classList.add(this.config.classNames.loadingState);\n this.containerOuter.setAttribute('aria-busy', 'true');\n if (this.passedElement.type === 'select-one') {\n if (!placeholderItem) {\n placeholderItem = this._getTemplate('placeholder', this.config.loadingText);\n this.itemList.appendChild(placeholderItem);\n } else {\n placeholderItem.innerHTML = this.config.loadingText;\n }\n } else {\n this.input.placeholder = this.config.loadingText;\n }\n } else {\n // Remove loading states/text\n this.containerOuter.classList.remove(this.config.classNames.loadingState);\n const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : false;\n if (this.passedElement.type === 'select-one') {\n placeholderItem.innerHTML = placeholder || '';\n } else {\n this.input.placeholder = placeholder || '';\n }\n }\n }\n\n /**\n * Retrieve the callback used to populate component's choices in an async way.\n * @returns {Function} The callback as a function.\n * @private\n */\n _ajaxCallback() {\n return (results, value, label) => {\n if (!results || !value) return;\n\n const parsedResults = isType('Object', results) ? [results] : results;\n\n if (parsedResults && isType('Array', parsedResults) && parsedResults.length) {\n // Remove loading states/text\n this._handleLoadingState(false);\n // Add each result as a choice\n parsedResults.forEach((result, index) => {\n const isSelected = result.selected ? result.selected : false;\n const isDisabled = result.disabled ? result.disabled : false;\n if (result.choices) {\n this._addGroup(result, (result.id || null), value, label);\n } else {\n this._addChoice(isSelected, isDisabled, result[value], result[label]);\n }\n });\n } else {\n // No results, remove loading state\n this._handleLoadingState(false);\n }\n\n this.containerOuter.removeAttribute('aria-busy');\n };\n }\n\n /**\n * Filter choices based on search value\n * @param {String} value Value to filter by\n * @return\n * @private\n */\n _searchChoices(value) {\n const newValue = isType('String', value) ? value.trim() : value;\n const currentValue = isType('String', this.currentValue) ? this.currentValue.trim() : this.currentValue;\n\n // If new value matches the desired length and is not the same as the current value with a space\n if (newValue.length >= 1 && newValue !== `${currentValue} `) {\n const haystack = this.store.getChoicesFilteredBySelectable();\n const needle = newValue;\n const keys = isType('Array', this.config.sortFields) ? this.config.sortFields : [this.config.sortFields];\n const options = Object.assign(this.config.fuseOptions, { keys });\n const fuse = new Fuse(haystack, options);\n const results = fuse.search(needle);\n\n this.currentValue = newValue;\n this.highlightPosition = 0;\n this.isSearching = true;\n this.store.dispatch(filterChoices(results));\n }\n }\n\n /**\n * Determine the action when a user is searching\n * @param {String} value Value entered by user\n * @return\n * @private\n */\n _handleSearch(value) {\n if (!value) return;\n const choices = this.store.getChoices();\n const hasUnactiveChoices = choices.some((option) => option.active !== true);\n\n // Run callback if it is a function\n if (this.input === document.activeElement) {\n // Check that we have a value to search and the input was an alphanumeric character\n if (value && value.length > this.config.searchFloor) {\n // Filter available choices\n this._searchChoices(value);\n // Trigger search event\n triggerEvent(this.passedElement, 'search', {\n value,\n });\n } else if (hasUnactiveChoices) {\n // Otherwise reset choices to active\n this.isSearching = false;\n this.store.dispatch(activateChoices(true));\n }\n }\n }\n\n /**\n * Trigger event listeners\n * @return\n * @private\n */\n _addEventListeners() {\n document.addEventListener('keyup', this._onKeyUp);\n document.addEventListener('keydown', this._onKeyDown);\n document.addEventListener('click', this._onClick);\n document.addEventListener('touchmove', this._onTouchMove);\n document.addEventListener('touchend', this._onTouchEnd);\n document.addEventListener('mousedown', this._onMouseDown);\n document.addEventListener('mouseover', this._onMouseOver);\n\n if (this.passedElement.type && this.passedElement.type === 'select-one') {\n this.containerOuter.addEventListener('focus', this._onFocus);\n this.containerOuter.addEventListener('blur', this._onBlur);\n }\n\n this.input.addEventListener('input', this._onInput);\n this.input.addEventListener('paste', this._onPaste);\n this.input.addEventListener('focus', this._onFocus);\n this.input.addEventListener('blur', this._onBlur);\n }\n\n /**\n * Remove event listeners\n * @return\n * @private\n */\n _removeEventListeners() {\n document.removeEventListener('keyup', this._onKeyUp);\n document.removeEventListener('keydown', this._onKeyDown);\n document.removeEventListener('click', this._onClick);\n document.removeEventListener('touchmove', this._onTouchMove);\n document.removeEventListener('touchend', this._onTouchEnd);\n document.removeEventListener('mousedown', this._onMouseDown);\n document.removeEventListener('mouseover', this._onMouseOver);\n\n if (this.passedElement.type && this.passedElement.type === 'select-one') {\n this.containerOuter.removeEventListener('focus', this._onFocus);\n this.containerOuter.removeEventListener('blur', this._onBlur);\n }\n\n this.input.removeEventListener('input', this._onInput);\n this.input.removeEventListener('paste', this._onPaste);\n this.input.removeEventListener('focus', this._onFocus);\n this.input.removeEventListener('blur', this._onBlur);\n }\n\n /**\n * Set the correct input width based on placeholder\n * value or input value\n * @return\n */\n _setInputWidth() {\n if (this.config.placeholder && (this.config.placeholderValue || this.passedElement.getAttribute('placeholder'))) {\n // If there is a placeholder, we only want to set the width of the input when it is a greater\n // length than 75% of the placeholder. This stops the input jumping around.\n const placeholder = this.config.placeholder ? this.config.placeholderValue ||\n this.passedElement.getAttribute('placeholder') : false;\n if (this.input.value && this.input.value.length >= (placeholder.length / 1.25)) {\n this.input.style.width = getWidthOfInput(this.input);\n }\n } else {\n // If there is no placeholder, resize input to contents\n this.input.style.width = getWidthOfInput(this.input);\n }\n }\n\n /**\n * Key down event\n * @param {Object} e Event\n * @return\n */\n _onKeyDown(e) {\n if (e.target !== this.input && !this.containerOuter.contains(e.target)) return;\n\n const target = e.target;\n const passedElementType = this.passedElement.type;\n const activeItems = this.store.getItemsFilteredByActive();\n const hasFocusedInput = this.input === document.activeElement;\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const hasItems = this.itemList && this.itemList.children;\n const keyString = String.fromCharCode(e.keyCode);\n\n const backKey = 46;\n const deleteKey = 8;\n const enterKey = 13;\n const aKey = 65;\n const escapeKey = 27;\n const upKey = 38;\n const downKey = 40;\n const pageUpKey = 33;\n const pageDownKey = 34;\n const ctrlDownKey = e.ctrlKey || e.metaKey;\n\n // If a user is typing and the dropdown is not active\n if (passedElementType !== 'text' && /[a-zA-Z0-9-_ ]/.test(keyString) && !hasActiveDropdown) {\n this.showDropdown(true);\n }\n\n this.canSearch = this.config.search;\n\n const onAKey = () => {\n // If CTRL + A or CMD + A have been pressed and there are items to select\n if (ctrlDownKey && hasItems) {\n this.canSearch = false;\n if (this.config.removeItems && !this.input.value && this.input === document.activeElement) {\n // Highlight items\n this.highlightAll(this.itemList.children);\n }\n }\n };\n\n const onEnterKey = () => {\n // If enter key is pressed and the input has a value\n if (passedElementType === 'text' && target.value) {\n const value = this.input.value;\n const canAddItem = this._canAddItem(activeItems, value);\n\n // All is good, add\n if (canAddItem.response) {\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n this._addItem(value);\n this._triggerChange(value);\n this.clearInput(this.passedElement);\n }\n }\n\n if (target.hasAttribute('data-button')) {\n this._handleButtonAction(activeItems, target);\n e.preventDefault();\n }\n\n if (hasActiveDropdown) {\n e.preventDefault();\n const highlighted = this.dropdown.querySelector(`.${this.config.classNames.highlightedState}`);\n\n // If we have a highlighted choice\n if (highlighted) {\n this._handleChoiceAction(activeItems, highlighted);\n }\n\n } else if (passedElementType === 'select-one') {\n // Open single select dropdown if it's not active\n if (!hasActiveDropdown) {\n this.showDropdown(true);\n e.preventDefault();\n }\n }\n };\n\n const onEscapeKey = () => {\n if (hasActiveDropdown) {\n this.toggleDropdown();\n }\n };\n\n const onDirectionKey = () => {\n // If up or down key is pressed, traverse through options\n if (hasActiveDropdown || passedElementType === 'select-one') {\n // Show dropdown if focus\n if (!hasActiveDropdown) {\n this.showDropdown(true);\n }\n\n this.canSearch = false;\n\n const directionInt = e.keyCode === downKey || e.keyCode === pageDownKey ? 1 : -1;\n const skipKey = e.metaKey || e.keyCode === pageDownKey || e.keyCode === pageUpKey;\n\n let nextEl;\n if (skipKey) {\n if (directionInt > 0) {\n nextEl = Array.from(this.dropdown.querySelectorAll('[data-choice-selectable]')).pop();\n } else {\n nextEl = this.dropdown.querySelector('[data-choice-selectable]');\n }\n } else {\n const currentEl = this.dropdown.querySelector(`.${this.config.classNames.highlightedState}`);\n if (currentEl) {\n nextEl = getAdjacentEl(currentEl, '[data-choice-selectable]', directionInt);\n } else {\n nextEl = this.dropdown.querySelector('[data-choice-selectable]');\n }\n }\n\n if (nextEl) {\n // We prevent default to stop the cursor moving\n // when pressing the arrow\n if (!isScrolledIntoView(nextEl, this.choiceList, directionInt)) {\n this._scrollToChoice(nextEl, directionInt);\n }\n this._highlightChoice(nextEl);\n }\n\n // Prevent default to maintain cursor position whilst\n // traversing dropdown options\n e.preventDefault();\n }\n };\n\n const onDeleteKey = () => {\n // If backspace or delete key is pressed and the input has no value\n if (hasFocusedInput && !e.target.value && passedElementType !== 'select-one') {\n this._handleBackspace(activeItems);\n e.preventDefault();\n }\n };\n\n // Map keys to key actions\n const keyDownActions = {\n [aKey]: onAKey,\n [enterKey]: onEnterKey,\n [escapeKey]: onEscapeKey,\n [upKey]: onDirectionKey,\n [pageUpKey]: onDirectionKey,\n [downKey]: onDirectionKey,\n [pageDownKey]: onDirectionKey,\n [deleteKey]: onDeleteKey,\n [backKey]: onDeleteKey,\n };\n\n // If keycode has a function, run it\n if (keyDownActions[e.keyCode]) {\n keyDownActions[e.keyCode]();\n }\n }\n\n /**\n * Key up event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onKeyUp(e) {\n if (e.target !== this.input) return;\n\n // We are typing into a text input and have a value, we want to show a dropdown\n // notice. Otherwise hide the dropdown\n if (this.isTextElement) {\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const value = this.input.value;\n\n if (value) {\n const activeItems = this.store.getItemsFilteredByActive();\n const canAddItem = this._canAddItem(activeItems, value);\n\n if (canAddItem.notice) {\n const dropdownItem = this._getTemplate('notice', canAddItem.notice);\n this.dropdown.innerHTML = dropdownItem.outerHTML;\n }\n\n if (canAddItem.response === true) {\n if (!hasActiveDropdown) {\n this.showDropdown();\n }\n } else if (!canAddItem.notice && hasActiveDropdown) {\n this.hideDropdown();\n }\n } else if (hasActiveDropdown) {\n this.hideDropdown();\n }\n } else {\n const backKey = 46;\n const deleteKey = 8;\n\n // If user has removed value...\n if ((e.keyCode === backKey || e.keyCode === deleteKey) && !e.target.value) {\n // ...and it is a multiple select input, activate choices (if searching)\n if (this.passedElement.type !== 'text' && this.isSearching) {\n this.isSearching = false;\n this.store.dispatch(activateChoices(true));\n }\n } else if (this.canSearch) {\n this._handleSearch(this.input.value);\n }\n }\n }\n\n /**\n * Input event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onInput() {\n if (this.passedElement.type !== 'select-one') {\n this._setInputWidth();\n }\n }\n\n /**\n * Touch move event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onTouchMove() {\n if (this.wasTap === true) {\n this.wasTap = false;\n }\n }\n\n /**\n * Touch end event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onTouchEnd(e) {\n const target = e.target || e.touches[0].target;\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n\n // If a user tapped within our container...\n if (this.wasTap === true && this.containerOuter.contains(target)) {\n // ...and we aren't dealing with a single select box, show dropdown/focus input\n if ((target === this.containerOuter || target === this.containerInner) && this.passedElement.type !== 'select-one') {\n if (this.isTextElement) {\n // If text element, we only want to focus the input (if it isn't already)\n if (document.activeElement !== this.input) {\n this.input.focus();\n }\n } else {\n if (!hasActiveDropdown) {\n // If a select box, we want to show the dropdown\n this.showDropdown(true);\n }\n }\n }\n // Prevents focus event firing\n e.stopPropagation();\n }\n\n this.wasTap = true;\n }\n\n /**\n * Mouse down event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onMouseDown(e) {\n const target = e.target;\n if (this.containerOuter.contains(target) && target !== this.input) {\n let foundTarget;\n const activeItems = this.store.getItemsFilteredByActive();\n const hasShiftKey = e.shiftKey;\n\n if(foundTarget = findAncestorByAttrName(target, 'data-button')) {\n this._handleButtonAction(activeItems, foundTarget);\n } else if (foundTarget = findAncestorByAttrName(target, 'data-item')) {\n this._handleItemAction(activeItems, foundTarget, hasShiftKey);\n } else if (foundTarget = findAncestorByAttrName(target, 'data-choice')) {\n this._handleChoiceAction(activeItems, foundTarget);\n }\n\n e.preventDefault();\n }\n }\n\n /**\n * Click event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onClick(e) {\n const target = e.target;\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const activeItems = this.store.getItemsFilteredByActive();\n\n\n // If target is something that concerns us\n if (this.containerOuter.contains(target)) {\n // Handle button delete\n if (target.hasAttribute('data-button')) {\n this._handleButtonAction(activeItems, target);\n }\n\n if (!hasActiveDropdown) {\n if (this.isTextElement) {\n if (document.activeElement !== this.input) {\n this.input.focus();\n }\n } else {\n if (this.canSearch) {\n this.showDropdown(true);\n } else {\n this.showDropdown();\n this.containerOuter.focus();\n }\n }\n } else if (this.passedElement.type === 'select-one' && target !== this.input && !this.dropdown.contains(target)) {\n this.hideDropdown(true);\n }\n } else {\n const hasHighlightedItems = activeItems.some((item) => item.highlighted === true);\n\n // De-select any highlighted items\n if (hasHighlightedItems) {\n this.unhighlightAll();\n }\n\n // Remove focus state\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n\n // Close all other dropdowns\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n }\n }\n\n /**\n * Mouse over (hover) event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onMouseOver(e) {\n // If the dropdown is either the target or one of its children is the target\n if (e.target === this.dropdown || this.dropdown.contains(e.target)) {\n if (e.target.hasAttribute('data-choice')) this._highlightChoice(e.target);\n }\n }\n\n /**\n * Paste event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onPaste(e) {\n // Disable pasting into the input if option has been set\n if (e.target === this.input && !this.config.paste) {\n e.preventDefault();\n }\n }\n\n /**\n * Focus event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onFocus(e) {\n const target = e.target;\n // If target is something that concerns us\n if (this.containerOuter.contains(target)) {\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const focusActions = {\n text: () => {\n if (target === this.input) {\n this.containerOuter.classList.add(this.config.classNames.focusState);\n }\n },\n 'select-one': () => {\n this.containerOuter.classList.add(this.config.classNames.focusState);\n if (target === this.input) {\n // Show dropdown if it isn't already showing\n if (!hasActiveDropdown) {\n this.showDropdown();\n }\n }\n },\n 'select-multiple': () => {\n if (target === this.input) {\n // If element is a select box, the focussed element is the container and the dropdown\n // isn't already open, focus and show dropdown\n this.containerOuter.classList.add(this.config.classNames.focusState);\n\n if (!hasActiveDropdown) {\n this.showDropdown(true);\n }\n }\n },\n };\n\n focusActions[this.passedElement.type]();\n }\n }\n\n /**\n * Blur event\n * @param {Object} e Event\n * @return\n * @private\n */\n _onBlur(e) {\n const target = e.target;\n // If target is something that concerns us\n if (this.containerOuter.contains(target)) {\n const activeItems = this.store.getItemsFilteredByActive();\n const hasActiveDropdown = this.dropdown.classList.contains(this.config.classNames.activeState);\n const hasHighlightedItems = activeItems.some((item) => item.highlighted === true);\n const blurActions = {\n text: () => {\n if (target === this.input) {\n // Remove the focus state\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n // De-select any highlighted items\n if (hasHighlightedItems) {\n this.unhighlightAll();\n }\n // Hide dropdown if it is showing\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n }\n },\n 'select-one': () => {\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n if (target === this.containerOuter) {\n // Hide dropdown if it is showing\n if (hasActiveDropdown && !this.canSearch) {\n this.hideDropdown();\n }\n }\n\n if (target === this.input) {\n // Hide dropdown if it is showing\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n }\n },\n 'select-multiple': () => {\n if (target === this.input) {\n // Remove the focus state\n this.containerOuter.classList.remove(this.config.classNames.focusState);\n if (hasActiveDropdown) {\n this.hideDropdown();\n }\n // De-select any highlighted items\n if (hasHighlightedItems) {\n this.unhighlightAll();\n }\n }\n },\n };\n\n blurActions[this.passedElement.type]();\n }\n }\n\n /**\n * Tests value against a regular expression\n * @param {string} value Value to test\n * @return {Boolean} Whether test passed/failed\n * @private\n */\n _regexFilter(value) {\n if (!value) return;\n const regex = this.config.regexFilter;\n const expression = new RegExp(regex.source, 'i');\n return expression.test(value);\n }\n\n /**\n * Scroll to an option element\n * @param {HTMLElement} option Option to scroll to\n * @param {Number} direction Whether option is above or below\n * @return\n * @private\n */\n _scrollToChoice(choice, direction) {\n if (!choice) return;\n\n const dropdownHeight = this.choiceList.offsetHeight;\n const choiceHeight = choice.offsetHeight;\n // Distance from bottom of element to top of parent\n const choicePos = choice.offsetTop + choiceHeight;\n // Scroll position of dropdown\n const containerScrollPos = this.choiceList.scrollTop + dropdownHeight;\n // Difference between the choice and scroll position\n const endPoint = direction > 0 ? ((this.choiceList.scrollTop + choicePos) - containerScrollPos) : choice.offsetTop;\n\n const animateScroll = () => {\n const strength = 4;\n const choiceListScrollTop = this.choiceList.scrollTop;\n let continueAnimation = false;\n let easing;\n let distance;\n\n if (direction > 0) {\n easing = (endPoint - choiceListScrollTop) / strength;\n distance = easing > 1 ? easing : 1;\n\n this.choiceList.scrollTop = choiceListScrollTop + distance;\n if (choiceListScrollTop < endPoint) {\n continueAnimation = true;\n }\n } else {\n easing = (choiceListScrollTop - endPoint) / strength;\n distance = easing > 1 ? easing : 1;\n\n this.choiceList.scrollTop = choiceListScrollTop - distance;\n if (choiceListScrollTop > endPoint) {\n continueAnimation = true;\n }\n }\n\n if (continueAnimation) {\n requestAnimationFrame((time) => {\n animateScroll(time, endPoint, direction);\n });\n }\n };\n\n requestAnimationFrame((time) => {\n animateScroll(time, endPoint, direction);\n });\n }\n\n /**\n * Highlight choice\n * @param {HTMLElement} el Element to highlight\n * @return\n * @private\n */\n _highlightChoice(el) {\n // Highlight first element in dropdown\n const choices = Array.from(this.dropdown.querySelectorAll('[data-choice-selectable]'));\n\n if (choices && choices.length) {\n const highlightedChoices = Array.from(this.dropdown.querySelectorAll(`.${this.config.classNames.highlightedState}`));\n\n // Remove any highlighted choices\n highlightedChoices.forEach((choice) => {\n choice.classList.remove(this.config.classNames.highlightedState);\n choice.setAttribute('aria-selected', 'false');\n });\n\n if (el) {\n // Highlight given option\n el.classList.add(this.config.classNames.highlightedState);\n this.highlightPosition = choices.indexOf(el);\n } else {\n // Highlight choice based on last known highlight location\n let choice;\n\n if (choices.length > this.highlightPosition) {\n // If we have an option to highlight\n choice = choices[this.highlightPosition];\n } else {\n // Otherwise highlight the option before\n choice = choices[choices.length - 1];\n }\n\n if (!choice) choice = choices[0];\n choice.classList.add(this.config.classNames.highlightedState);\n choice.setAttribute('aria-selected', 'true');\n }\n }\n }\n\n /**\n * Add item to store with correct value\n * @param {String} value Value to add to store\n * @param {String} label Label to add to store\n * @return {Object} Class instance\n * @public\n */\n _addItem(value, label, choiceId = -1, groupId = -1) {\n let passedValue = isType('String', value) ? value.trim() : value;\n const items = this.store.getItems();\n const passedLabel = label || passedValue;\n const passedOptionId = parseInt(choiceId, 10) || -1;\n\n // Get group if group ID passed\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n // Generate unique id\n const id = items ? items.length + 1 : 1;\n\n // If a prepended value has been passed, prepend it\n if (this.config.prependValue) {\n passedValue = this.config.prependValue + passedValue.toString();\n }\n\n // If an appended value has been passed, append it\n if (this.config.appendValue) {\n passedValue += this.config.appendValue.toString();\n }\n\n this.store.dispatch(addItem(passedValue, passedLabel, id, passedOptionId, groupId));\n\n if (this.passedElement.type === 'select-one') {\n this.removeActiveItems(id);\n }\n\n // Trigger change event\n if(group && group.value) {\n triggerEvent(this.passedElement, 'addItem', {\n id,\n value: passedValue,\n label: passedLabel,\n groupValue: group.value,\n });\n } else {\n triggerEvent(this.passedElement, 'addItem', {\n id,\n value: passedValue,\n label: passedLabel,\n });\n }\n\n return this;\n }\n\n /**\n * Remove item from store\n * @param {Object} item Item to remove\n * @param {Function} callback Callback to trigger\n * @return {Object} Class instance\n * @public\n */\n _removeItem(item) {\n if (!item || !isType('Object', item)) {\n console.error('removeItem: No item object was passed to be removed');\n return;\n }\n\n const id = item.id;\n const value = item.value;\n const label = item.label;\n const choiceId = item.choiceId;\n const groupId = item.groupId;\n const group = groupId >= 0 ? this.store.getGroupById(groupId) : null;\n\n this.store.dispatch(removeItem(id, choiceId));\n\n if(group && group.value) {\n triggerEvent(this.passedElement, 'removeItem', {\n id,\n value,\n label,\n groupValue: group.value,\n });\n } else {\n triggerEvent(this.passedElement, 'removeItem', {\n id,\n value,\n label,\n });\n }\n\n return this;\n }\n\n /**\n * Add choice to dropdown\n * @param {Boolean} isSelected Whether choice is selected\n * @param {Boolean} isDisabled Whether choice is disabled\n * @param {String} value Value of choice\n * @param {String} Label Label of choice\n * @param {Number} groupId ID of group choice is within. Negative number indicates no group\n * @return\n * @private\n */\n _addChoice(isSelected, isDisabled, value, label, groupId = -1) {\n if (typeof value === 'undefined' || value === null) return;\n\n // Generate unique id\n const choices = this.store.getChoices();\n const choiceLabel = label || value;\n const choiceId = choices ? choices.length + 1 : 1;\n\n this.store.dispatch(addChoice(value, choiceLabel, choiceId, groupId, isDisabled));\n\n if (isSelected) {\n this._addItem(value, choiceLabel, choiceId);\n }\n }\n\n /**\n * Clear all choices added to the store.\n * @return\n * @private\n */\n _clearChoices() {\n this.store.dispatch(clearChoices());\n }\n\n /**\n * Add group to dropdown\n * @param {Object} group Group to add\n * @param {Number} id Group ID\n * @param {String} [valueKey] name of the value property on the object\n * @param {String} [labelKey] name of the label property on the object\n * @return\n * @private\n */\n _addGroup(group, id, valueKey = 'value', labelKey = 'label') {\n const groupChoices = isType('Object', group) ? group.choices : Array.from(group.getElementsByTagName('OPTION'));\n const groupId = id ? id : Math.floor(new Date().valueOf() * Math.random());\n const isDisabled = group.disabled ? group.disabled : false;\n\n if (groupChoices) {\n this.store.dispatch(addGroup(group.label, groupId, true, isDisabled));\n\n groupChoices.forEach((option) => {\n const isOptDisabled = (option.disabled || (option.parentNode && option.parentNode.disabled)) || false;\n const isOptSelected = option.selected ? option.selected : false;\n let label;\n\n if (isType('Object', option)) {\n label = option[labelKey] || option[valueKey];\n } else {\n label = option.innerHTML;\n }\n\n this._addChoice(isOptSelected, isOptDisabled, option[valueKey], label, groupId);\n });\n } else {\n this.store.dispatch(addGroup(group.label, group.id, false, group.disabled));\n }\n }\n\n /**\n * Get template from name\n * @param {String} template Name of template to get\n * @param {...} args Data to pass to template\n * @return {HTMLElement} Template\n * @private\n */\n _getTemplate(template, ...args) {\n if (!template) return;\n const templates = this.config.templates;\n return templates[template](...args);\n }\n\n /**\n * Create HTML element based on type and arguments\n * @return\n * @private\n */\n _createTemplates() {\n const classNames = this.config.classNames;\n const templates = {\n containerOuter: (direction) => {\n return strToEl(`\n
\n `);\n },\n containerInner: () => {\n return strToEl(`\n
\n `);\n },\n itemList: () => {\n return strToEl(`\n
\n `);\n },\n placeholder: (value) => {\n return strToEl(`\n
${value}
\n `);\n },\n item: (data) => {\n if (this.config.removeItemButton) {\n return strToEl(`\n
\n ${data.label}\n
\n `);\n }\n return strToEl(`\n
\n ${data.label}\n
\n `);\n },\n choiceList: () => {\n return strToEl(`\n
\n `);\n },\n choiceGroup: (data) => {\n return strToEl(`\n
\n
${data.value}
\n
\n `);\n },\n choice: (data) => {\n return strToEl(`\n
0 ? 'role=\"treeitem\"' : 'role=\"option\"'}>\n ${data.label}\n
\n `);\n },\n input: () => {\n return strToEl(`\n \n `);\n },\n dropdown: () => {\n return strToEl(`\n
\n `);\n },\n notice: (label) => {\n return strToEl(`\n
${label}
\n `);\n },\n option: (data) => {\n return strToEl(`\n \n `);\n },\n };\n\n // User's custom templates\n const callbackTemplate = this.config.callbackOnCreateTemplates;\n let userTemplates = {};\n if (callbackTemplate && isType('Function', callbackTemplate)) {\n userTemplates = callbackTemplate.call(this, strToEl);\n }\n\n this.config.templates = extend(templates, userTemplates);\n }\n\n /**\n * Create DOM structure around passed select element\n * @return\n * @private\n */\n _createInput() {\n const direction = this.passedElement.getAttribute('dir') || 'ltr';\n const containerOuter = this._getTemplate('containerOuter', direction);\n const containerInner = this._getTemplate('containerInner');\n const itemList = this._getTemplate('itemList');\n const choiceList = this._getTemplate('choiceList');\n const input = this._getTemplate('input');\n const dropdown = this._getTemplate('dropdown');\n const placeholder = this.config.placeholder ? this.config.placeholderValue || this.passedElement.getAttribute('placeholder') : false;\n\n this.containerOuter = containerOuter;\n this.containerInner = containerInner;\n this.input = input;\n this.choiceList = choiceList;\n this.itemList = itemList;\n this.dropdown = dropdown;\n\n // Hide passed input\n this.passedElement.classList.add(this.config.classNames.input, this.config.classNames.hiddenState);\n this.passedElement.tabIndex = '-1';\n this.passedElement.setAttribute('style', 'display:none;');\n this.passedElement.setAttribute('aria-hidden', 'true');\n this.passedElement.setAttribute('data-choice', 'active');\n\n // Wrap input in container preserving DOM ordering\n wrap(this.passedElement, containerInner);\n\n // Wrapper inner container with outer container\n wrap(containerInner, containerOuter);\n\n // If placeholder has been enabled and we have a value\n if (placeholder) {\n input.placeholder = placeholder;\n if (this.passedElement.type !== 'select-one') {\n input.style.width = getWidthOfInput(input);\n }\n }\n\n if (!this.config.addItems) this.disable();\n\n containerOuter.appendChild(containerInner);\n containerOuter.appendChild(dropdown);\n containerInner.appendChild(itemList);\n\n if (this.passedElement.type !== 'text') {\n dropdown.appendChild(choiceList);\n }\n\n if (this.passedElement.type === 'select-multiple' || this.passedElement.type === 'text') {\n containerInner.appendChild(input);\n } else if (this.canSearch) {\n dropdown.insertBefore(input, dropdown.firstChild);\n }\n\n if (this.passedElement.type === 'select-multiple' || this.passedElement.type === 'select-one') {\n const passedGroups = Array.from(this.passedElement.getElementsByTagName('OPTGROUP'));\n\n this.highlightPosition = 0;\n this.isSearching = false;\n\n if (passedGroups && passedGroups.length) {\n passedGroups.forEach((group) => {\n this._addGroup(group, (group.id || null));\n });\n } else {\n const passedOptions = Array.from(this.passedElement.options);\n const filter = this.config.sortFilter;\n const allChoices = this.presetChoices;\n\n // Create array of options from option elements\n passedOptions.forEach((o) => {\n allChoices.push({\n value: o.value,\n label: o.innerHTML,\n selected: o.selected,\n disabled: o.disabled || o.parentNode.disabled,\n });\n });\n\n // If sorting is enabled or the user is searching, filter choices\n if (this.config.shouldSort) {\n allChoices.sort(filter);\n }\n\n // Determine whether there is a selected choice\n const hasSelectedChoice = allChoices.some((choice) => {\n return choice.selected === true;\n });\n\n // Add each choice\n allChoices.forEach((choice, index) => {\n const isDisabled = choice.disabled ? choice.disabled : false;\n const isSelected = choice.selected ? choice.selected : false;\n // Pre-select first choice if it's a single select\n if (this.passedElement.type === 'select-one') {\n if (hasSelectedChoice || (!hasSelectedChoice && index > 0)) {\n // If there is a selected choice already or the choice is not\n // the first in the array, add each choice normally\n this._addChoice(isSelected, isDisabled, choice.value, choice.label);\n } else {\n // Otherwise pre-select the first choice in the array\n this._addChoice(true, false, choice.value, choice.label);\n }\n } else {\n this._addChoice(isSelected, isDisabled, choice.value, choice.label);\n }\n });\n }\n } else if (this.isTextElement) {\n // Add any preset values seperated by delimiter\n this.presetItems.forEach((item) => {\n const itemType = getType(item);\n if (itemType === 'Object') {\n if (!item.value) return;\n this._addItem(item.value, item.label, item.id);\n } else if (itemType === 'String') {\n this._addItem(item);\n }\n });\n }\n }\n\n /*===== End of Private functions ======*/\n}\n\nmodule.exports = Choices;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/choices.js","/**\n * @license\n * Fuse - Lightweight fuzzy-search\n *\n * Copyright (c) 2012-2016 Kirollos Risk .\n * All Rights Reserved. Apache Software License 2.0\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n;(function (global) {\n 'use strict'\n\n /** @type {function(...*)} */\n function log () {\n console.log.apply(console, arguments)\n }\n\n var defaultOptions = {\n // The name of the identifier property. If specified, the returned result will be a list\n // of the items' dentifiers, otherwise it will be a list of the items.\n id: null,\n\n // Indicates whether comparisons should be case sensitive.\n\n caseSensitive: false,\n\n // An array of values that should be included from the searcher's output. When this array\n // contains elements, each result in the list will be of the form `{ item: ..., include1: ..., include2: ... }`.\n // Values you can include are `score`, `matchedLocations`\n include: [],\n\n // Whether to sort the result list, by score\n shouldSort: true,\n\n // The search function to use\n // Note that the default search function ([[Function]]) must conform to the following API:\n //\n // @param pattern The pattern string to search\n // @param options The search option\n // [[Function]].constructor = function(pattern, options)\n //\n // @param text: the string to search in for the pattern\n // @return Object in the form of:\n // - isMatch: boolean\n // - score: Int\n // [[Function]].prototype.search = function(text)\n searchFn: BitapSearcher,\n\n // Default sort function\n sortFn: function (a, b) {\n return a.score - b.score\n },\n\n // The get function to use when fetching an object's properties.\n // The default will search nested paths *ie foo.bar.baz*\n getFn: deepValue,\n\n // List of properties that will be searched. This also supports nested properties.\n keys: [],\n\n // Will print to the console. Useful for debugging.\n verbose: false,\n\n // When true, the search algorithm will search individual words **and** the full string,\n // computing the final score as a function of both. Note that when `tokenize` is `true`,\n // the `threshold`, `distance`, and `location` are inconsequential for individual tokens.\n tokenize: false,\n\n // When true, the result set will only include records that match all tokens. Will only work\n // if `tokenize` is also true.\n matchAllTokens: false,\n\n // Regex used to separate words when searching. Only applicable when `tokenize` is `true`.\n tokenSeparator: / +/g,\n\n // Minimum number of characters that must be matched before a result is considered a match\n minMatchCharLength: 1,\n\n // When true, the algorithm continues searching to the end of the input even if a perfect\n // match is found before the end of the same input.\n findAllMatches: false\n }\n\n /**\n * @constructor\n * @param {!Array} list\n * @param {!Object} options\n */\n function Fuse (list, options) {\n var i\n var len\n var key\n var keys\n\n this.list = list\n this.options = options = options || {}\n\n for (key in defaultOptions) {\n if (!defaultOptions.hasOwnProperty(key)) {\n continue;\n }\n // Add boolean type options\n if (typeof defaultOptions[key] === 'boolean') {\n this.options[key] = key in options ? options[key] : defaultOptions[key];\n // Add all other options\n } else {\n this.options[key] = options[key] || defaultOptions[key]\n }\n }\n }\n\n Fuse.VERSION = '2.6.0'\n\n /**\n * Sets a new list for Fuse to match against.\n * @param {!Array} list\n * @return {!Array} The newly set list\n * @public\n */\n Fuse.prototype.set = function (list) {\n this.list = list\n return list\n }\n\n Fuse.prototype.search = function (pattern) {\n if (this.options.verbose) log('\\nSearch term:', pattern, '\\n')\n\n this.pattern = pattern\n this.results = []\n this.resultMap = {}\n this._keyMap = null\n\n this._prepareSearchers()\n this._startSearch()\n this._computeScore()\n this._sort()\n\n var output = this._format()\n return output\n }\n\n Fuse.prototype._prepareSearchers = function () {\n var options = this.options\n var pattern = this.pattern\n var searchFn = options.searchFn\n var tokens = pattern.split(options.tokenSeparator)\n var i = 0\n var len = tokens.length\n\n if (this.options.tokenize) {\n this.tokenSearchers = []\n for (; i < len; i++) {\n this.tokenSearchers.push(new searchFn(tokens[i], options))\n }\n }\n this.fullSeacher = new searchFn(pattern, options)\n }\n\n Fuse.prototype._startSearch = function () {\n var options = this.options\n var getFn = options.getFn\n var list = this.list\n var listLen = list.length\n var keys = this.options.keys\n var keysLen = keys.length\n var key\n var weight\n var item = null\n var i\n var j\n\n // Check the first item in the list, if it's a string, then we assume\n // that every item in the list is also a string, and thus it's a flattened array.\n if (typeof list[0] === 'string') {\n // Iterate over every item\n for (i = 0; i < listLen; i++) {\n this._analyze('', list[i], i, i)\n }\n } else {\n this._keyMap = {}\n // Otherwise, the first item is an Object (hopefully), and thus the searching\n // is done on the values of the keys of each item.\n // Iterate over every item\n for (i = 0; i < listLen; i++) {\n item = list[i]\n // Iterate over every key\n for (j = 0; j < keysLen; j++) {\n key = keys[j]\n if (typeof key !== 'string') {\n weight = (1 - key.weight) || 1\n this._keyMap[key.name] = {\n weight: weight\n }\n if (key.weight <= 0 || key.weight > 1) {\n throw new Error('Key weight has to be > 0 and <= 1')\n }\n key = key.name\n } else {\n this._keyMap[key] = {\n weight: 1\n }\n }\n this._analyze(key, getFn(item, key, []), item, i)\n }\n }\n }\n }\n\n Fuse.prototype._analyze = function (key, text, entity, index) {\n var options = this.options\n var words\n var scores\n var exists = false\n var existingResult\n var averageScore\n var finalScore\n var scoresLen\n var mainSearchResult\n var tokenSearcher\n var termScores\n var word\n var tokenSearchResult\n var hasMatchInText\n var checkTextMatches\n var i\n var j\n\n // Check if the text can be searched\n if (text === undefined || text === null) {\n return\n }\n\n scores = []\n\n var numTextMatches = 0\n\n if (typeof text === 'string') {\n words = text.split(options.tokenSeparator)\n\n if (options.verbose) log('---------\\nKey:', key)\n\n if (this.options.tokenize) {\n for (i = 0; i < this.tokenSearchers.length; i++) {\n tokenSearcher = this.tokenSearchers[i]\n\n if (options.verbose) log('Pattern:', tokenSearcher.pattern)\n\n termScores = []\n hasMatchInText = false\n\n for (j = 0; j < words.length; j++) {\n word = words[j]\n tokenSearchResult = tokenSearcher.search(word)\n var obj = {}\n if (tokenSearchResult.isMatch) {\n obj[word] = tokenSearchResult.score\n exists = true\n hasMatchInText = true\n scores.push(tokenSearchResult.score)\n } else {\n obj[word] = 1\n if (!this.options.matchAllTokens) {\n scores.push(1)\n }\n }\n termScores.push(obj)\n }\n\n if (hasMatchInText) {\n numTextMatches++\n }\n\n if (options.verbose) log('Token scores:', termScores)\n }\n\n averageScore = scores[0]\n scoresLen = scores.length\n for (i = 1; i < scoresLen; i++) {\n averageScore += scores[i]\n }\n averageScore = averageScore / scoresLen\n\n if (options.verbose) log('Token score average:', averageScore)\n }\n\n mainSearchResult = this.fullSeacher.search(text)\n if (options.verbose) log('Full text score:', mainSearchResult.score)\n\n finalScore = mainSearchResult.score\n if (averageScore !== undefined) {\n finalScore = (finalScore + averageScore) / 2\n }\n\n if (options.verbose) log('Score average:', finalScore)\n\n checkTextMatches = (this.options.tokenize && this.options.matchAllTokens) ? numTextMatches >= this.tokenSearchers.length : true\n\n if (options.verbose) log('Check Matches', checkTextMatches)\n\n // If a match is found, add the item to , including its score\n if ((exists || mainSearchResult.isMatch) && checkTextMatches) {\n // Check if the item already exists in our results\n existingResult = this.resultMap[index]\n\n if (existingResult) {\n // Use the lowest score\n // existingResult.score, bitapResult.score\n existingResult.output.push({\n key: key,\n score: finalScore,\n matchedIndices: mainSearchResult.matchedIndices\n })\n } else {\n // Add it to the raw result list\n this.resultMap[index] = {\n item: entity,\n output: [{\n key: key,\n score: finalScore,\n matchedIndices: mainSearchResult.matchedIndices\n }]\n }\n\n this.results.push(this.resultMap[index])\n }\n }\n } else if (isArray(text)) {\n for (i = 0; i < text.length; i++) {\n this._analyze(key, text[i], entity, index)\n }\n }\n }\n\n Fuse.prototype._computeScore = function () {\n var i\n var j\n var keyMap = this._keyMap\n var totalScore\n var output\n var scoreLen\n var score\n var weight\n var results = this.results\n var bestScore\n var nScore\n\n if (this.options.verbose) log('\\n\\nComputing score:\\n')\n\n for (i = 0; i < results.length; i++) {\n totalScore = 0\n output = results[i].output\n scoreLen = output.length\n\n bestScore = 1\n\n for (j = 0; j < scoreLen; j++) {\n score = output[j].score\n weight = keyMap ? keyMap[output[j].key].weight : 1\n\n nScore = score * weight\n\n if (weight !== 1) {\n bestScore = Math.min(bestScore, nScore)\n } else {\n totalScore += nScore\n output[j].nScore = nScore\n }\n }\n\n if (bestScore === 1) {\n results[i].score = totalScore / scoreLen\n } else {\n results[i].score = bestScore\n }\n\n if (this.options.verbose) log(results[i])\n }\n }\n\n Fuse.prototype._sort = function () {\n var options = this.options\n if (options.shouldSort) {\n if (options.verbose) log('\\n\\nSorting....')\n this.results.sort(options.sortFn)\n }\n }\n\n Fuse.prototype._format = function () {\n var options = this.options\n var getFn = options.getFn\n var finalOutput = []\n var item\n var i\n var len\n var results = this.results\n var replaceValue\n var getItemAtIndex\n var include = options.include\n\n if (options.verbose) log('\\n\\nOutput:\\n\\n', results)\n\n // Helper function, here for speed-up, which replaces the item with its value,\n // if the options specifies it,\n replaceValue = options.id ? function (index) {\n results[index].item = getFn(results[index].item, options.id, [])[0]\n } : function () {}\n\n getItemAtIndex = function (index) {\n var record = results[index]\n var data\n var j\n var output\n var _item\n var _result\n\n // If `include` has values, put the item in the result\n if (include.length > 0) {\n data = {\n item: record.item\n }\n if (include.indexOf('matches') !== -1) {\n output = record.output\n data.matches = []\n for (j = 0; j < output.length; j++) {\n _item = output[j]\n _result = {\n indices: _item.matchedIndices\n }\n if (_item.key) {\n _result.key = _item.key\n }\n data.matches.push(_result)\n }\n }\n\n if (include.indexOf('score') !== -1) {\n data.score = results[index].score\n }\n\n } else {\n data = record.item\n }\n\n return data\n }\n\n // From the results, push into a new array only the item identifier (if specified)\n // of the entire item. This is because we don't want to return the ,\n // since it contains other metadata\n for (i = 0, len = results.length; i < len; i++) {\n replaceValue(i)\n item = getItemAtIndex(i)\n finalOutput.push(item)\n }\n\n return finalOutput\n }\n\n // Helpers\n\n function deepValue (obj, path, list) {\n var firstSegment\n var remaining\n var dotIndex\n var value\n var i\n var len\n\n if (!path) {\n // If there's no path left, we've gotten to the object we care about.\n list.push(obj)\n } else {\n dotIndex = path.indexOf('.')\n\n if (dotIndex !== -1) {\n firstSegment = path.slice(0, dotIndex)\n remaining = path.slice(dotIndex + 1)\n } else {\n firstSegment = path\n }\n\n value = obj[firstSegment]\n if (value !== null && value !== undefined) {\n if (!remaining && (typeof value === 'string' || typeof value === 'number')) {\n list.push(value)\n } else if (isArray(value)) {\n // Search each item in the array.\n for (i = 0, len = value.length; i < len; i++) {\n deepValue(value[i], remaining, list)\n }\n } else if (remaining) {\n // An object. Recurse further.\n deepValue(value, remaining, list)\n }\n }\n }\n\n return list\n }\n\n function isArray (obj) {\n return Object.prototype.toString.call(obj) === '[object Array]'\n }\n\n /**\n * Adapted from \"Diff, Match and Patch\", by Google\n *\n * http://code.google.com/p/google-diff-match-patch/\n *\n * Modified by: Kirollos Risk \n * -----------------------------------------------\n * Details: the algorithm and structure was modified to allow the creation of\n * instances with a method which does the actual\n * bitap search. The (the string that is searched for) is only defined\n * once per instance and thus it eliminates redundant re-creation when searching\n * over a list of strings.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\")\n * you may not use this file except in compliance with the License.\n *\n * @constructor\n */\n function BitapSearcher (pattern, options) {\n options = options || {}\n this.options = options\n this.options.location = options.location || BitapSearcher.defaultOptions.location\n this.options.distance = 'distance' in options ? options.distance : BitapSearcher.defaultOptions.distance\n this.options.threshold = 'threshold' in options ? options.threshold : BitapSearcher.defaultOptions.threshold\n this.options.maxPatternLength = options.maxPatternLength || BitapSearcher.defaultOptions.maxPatternLength\n\n this.pattern = options.caseSensitive ? pattern : pattern.toLowerCase()\n this.patternLen = pattern.length\n\n if (this.patternLen <= this.options.maxPatternLength) {\n this.matchmask = 1 << (this.patternLen - 1)\n this.patternAlphabet = this._calculatePatternAlphabet()\n }\n }\n\n BitapSearcher.defaultOptions = {\n // Approximately where in the text is the pattern expected to be found?\n location: 0,\n\n // Determines how close the match must be to the fuzzy location (specified above).\n // An exact letter match which is 'distance' characters away from the fuzzy location\n // would score as a complete mismatch. A distance of '0' requires the match be at\n // the exact location specified, a threshold of '1000' would require a perfect match\n // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold.\n distance: 100,\n\n // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match\n // (of both letters and location), a threshold of '1.0' would match anything.\n threshold: 0.6,\n\n // Machine word size\n maxPatternLength: 32\n }\n\n /**\n * Initialize the alphabet for the Bitap algorithm.\n * @return {Object} Hash of character locations.\n * @private\n */\n BitapSearcher.prototype._calculatePatternAlphabet = function () {\n var mask = {},\n i = 0\n\n for (i = 0; i < this.patternLen; i++) {\n mask[this.pattern.charAt(i)] = 0\n }\n\n for (i = 0; i < this.patternLen; i++) {\n mask[this.pattern.charAt(i)] |= 1 << (this.pattern.length - i - 1)\n }\n\n return mask\n }\n\n /**\n * Compute and return the score for a match with `e` errors and `x` location.\n * @param {number} errors Number of errors in match.\n * @param {number} location Location of match.\n * @return {number} Overall score for match (0.0 = good, 1.0 = bad).\n * @private\n */\n BitapSearcher.prototype._bitapScore = function (errors, location) {\n var accuracy = errors / this.patternLen,\n proximity = Math.abs(this.options.location - location)\n\n if (!this.options.distance) {\n // Dodge divide by zero error.\n return proximity ? 1.0 : accuracy\n }\n return accuracy + (proximity / this.options.distance)\n }\n\n /**\n * Compute and return the result of the search\n * @param {string} text The text to search in\n * @return {{isMatch: boolean, score: number}} Literal containing:\n * isMatch - Whether the text is a match or not\n * score - Overall score for the match\n * @public\n */\n BitapSearcher.prototype.search = function (text) {\n var options = this.options\n var i\n var j\n var textLen\n var findAllMatches\n var location\n var threshold\n var bestLoc\n var binMin\n var binMid\n var binMax\n var start, finish\n var bitArr\n var lastBitArr\n var charMatch\n var score\n var locations\n var matches\n var isMatched\n var matchMask\n var matchedIndices\n var matchesLen\n var match\n\n text = options.caseSensitive ? text : text.toLowerCase()\n\n if (this.pattern === text) {\n // Exact match\n return {\n isMatch: true,\n score: 0,\n matchedIndices: [[0, text.length - 1]]\n }\n }\n\n // When pattern length is greater than the machine word length, just do a a regex comparison\n if (this.patternLen > options.maxPatternLength) {\n matches = text.match(new RegExp(this.pattern.replace(options.tokenSeparator, '|')))\n isMatched = !!matches\n\n if (isMatched) {\n matchedIndices = []\n for (i = 0, matchesLen = matches.length; i < matchesLen; i++) {\n match = matches[i]\n matchedIndices.push([text.indexOf(match), match.length - 1])\n }\n }\n\n return {\n isMatch: isMatched,\n // TODO: revisit this score\n score: isMatched ? 0.5 : 1,\n matchedIndices: matchedIndices\n }\n }\n\n findAllMatches = options.findAllMatches\n\n location = options.location\n // Set starting location at beginning text and initialize the alphabet.\n textLen = text.length\n // Highest score beyond which we give up.\n threshold = options.threshold\n // Is there a nearby exact match? (speedup)\n bestLoc = text.indexOf(this.pattern, location)\n\n // a mask of the matches\n matchMask = []\n for (i = 0; i < textLen; i++) {\n matchMask[i] = 0\n }\n\n if (bestLoc != -1) {\n threshold = Math.min(this._bitapScore(0, bestLoc), threshold)\n // What about in the other direction? (speed up)\n bestLoc = text.lastIndexOf(this.pattern, location + this.patternLen)\n\n if (bestLoc != -1) {\n threshold = Math.min(this._bitapScore(0, bestLoc), threshold)\n }\n }\n\n bestLoc = -1\n score = 1\n locations = []\n binMax = this.patternLen + textLen\n\n for (i = 0; i < this.patternLen; i++) {\n // Scan for the best match; each iteration allows for one more error.\n // Run a binary search to determine how far from the match location we can stray\n // at this error level.\n binMin = 0\n binMid = binMax\n while (binMin < binMid) {\n if (this._bitapScore(i, location + binMid) <= threshold) {\n binMin = binMid\n } else {\n binMax = binMid\n }\n binMid = Math.floor((binMax - binMin) / 2 + binMin)\n }\n\n // Use the result from this iteration as the maximum for the next.\n binMax = binMid\n start = Math.max(1, location - binMid + 1)\n if (findAllMatches) {\n finish = textLen;\n } else {\n finish = Math.min(location + binMid, textLen) + this.patternLen\n }\n\n // Initialize the bit array\n bitArr = Array(finish + 2)\n\n bitArr[finish + 1] = (1 << i) - 1\n\n for (j = finish; j >= start; j--) {\n charMatch = this.patternAlphabet[text.charAt(j - 1)]\n\n if (charMatch) {\n matchMask[j - 1] = 1\n }\n\n if (i === 0) {\n // First pass: exact match.\n bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch\n } else {\n // Subsequent passes: fuzzy match.\n bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch | (((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1) | lastBitArr[j + 1]\n }\n if (bitArr[j] & this.matchmask) {\n score = this._bitapScore(i, j - 1)\n\n // This match will almost certainly be better than any existing match.\n // But check anyway.\n if (score <= threshold) {\n // Indeed it is\n threshold = score\n bestLoc = j - 1\n locations.push(bestLoc)\n\n if (bestLoc > location) {\n // When passing loc, don't exceed our current distance from loc.\n start = Math.max(1, 2 * location - bestLoc)\n } else {\n // Already passed loc, downhill from here on in.\n break\n }\n }\n }\n }\n\n // No hope for a (better) match at greater error levels.\n if (this._bitapScore(i + 1, location) > threshold) {\n break\n }\n lastBitArr = bitArr\n }\n\n matchedIndices = this._getMatchedIndices(matchMask)\n\n // Count exact matches (those with a score of 0) to be \"almost\" exact\n return {\n isMatch: bestLoc >= 0,\n score: score === 0 ? 0.001 : score,\n matchedIndices: matchedIndices\n }\n }\n\n BitapSearcher.prototype._getMatchedIndices = function (matchMask) {\n var matchedIndices = []\n var start = -1\n var end = -1\n var i = 0\n var match\n var len = matchMask.length\n for (; i < len; i++) {\n match = matchMask[i]\n if (match && start === -1) {\n start = i\n } else if (!match && start !== -1) {\n end = i - 1\n if ((end - start) + 1 >= this.options.minMatchCharLength) {\n matchedIndices.push([start, end])\n }\n start = -1\n }\n }\n if (matchMask[i - 1]) {\n if ((i-1 - start) + 1 >= this.options.minMatchCharLength) {\n matchedIndices.push([start, i - 1])\n }\n }\n return matchedIndices\n }\n\n // Export to Common JS Loader\n if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = Fuse\n } else if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define(function () {\n return Fuse\n })\n } else {\n // Browser globals (root is window)\n global.Fuse = Fuse\n }\n\n})(this);\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/fuse.js/src/fuse.js\n// module id = 2\n// module chunks = 0","import { createStore } from 'redux';\nimport rootReducer from './../reducers/index.js';\n\nexport default class Store {\n constructor() {\n this.store = createStore(\n rootReducer\n , window.devToolsExtension ? window.devToolsExtension() : undefined\n );\n }\n\n /**\n * Get store object (wrapping Redux method)\n * @return {Object} State\n */\n getState() {\n return this.store.getState();\n }\n\n /**\n * Dispatch event to store (wrapped Redux method)\n * @param {Function} action Action function to trigger\n * @return\n */\n dispatch(action) {\n this.store.dispatch(action);\n }\n\n /**\n * Subscribe store to function call (wrapped Redux method)\n * @param {Function} onChange Function to trigger when state changes\n * @return\n */\n subscribe(onChange) {\n this.store.subscribe(onChange);\n }\n\n /**\n * Get items from store\n * @return {Array} Item objects\n */\n getItems() {\n const state = this.store.getState();\n return state.items;\n }\n\n /**\n * Get active items from store\n * @return {Array} Item objects\n */\n getItemsFilteredByActive() {\n const items = this.getItems();\n const values = items.filter((item) => {\n return item.active === true;\n }, []);\n\n return values;\n }\n\n /**\n * Get items from store reduced to just their values\n * @return {Array} Item objects\n */\n getItemsReducedToValues(items = this.getItems()) {\n const values = items.reduce((prev, current) => {\n prev.push(current.value);\n return prev;\n }, []);\n\n return values;\n }\n\n /**\n * Get choices from store\n * @return {Array} Option objects\n */\n getChoices() {\n const state = this.store.getState();\n return state.choices;\n }\n\n /**\n * Get active choices from store\n * @return {Array} Option objects\n */\n getChoicesFilteredByActive() {\n const choices = this.getChoices();\n const values = choices.filter((choice) => {\n return choice.active === true;\n }, []);\n\n return values;\n }\n\n /**\n * Get selectable choices from store\n * @return {Array} Option objects\n */\n getChoicesFilteredBySelectable() {\n const choices = this.getChoices();\n const values = choices.filter((choice) => {\n return choice.disabled !== true;\n }, []);\n\n return values;\n }\n\n /**\n * Get single choice by it's ID\n * @return {Object} Found choice\n */\n getChoiceById(id) {\n if (id) {\n const choices = this.getChoicesFilteredByActive();\n const foundChoice = choices.find((choice) => choice.id === parseInt(id, 10));\n return foundChoice;\n }\n return false;\n }\n\n /**\n * Get groups from store\n * @return {Array} Group objects\n */\n getGroups() {\n const state = this.store.getState();\n return state.groups;\n }\n\n /**\n * Get active groups from store\n * @return {Array} Group objects\n */\n getGroupsFilteredByActive() {\n const groups = this.getGroups();\n const choices = this.getChoices();\n\n const values = groups.filter((group) => {\n const isActive = group.active === true && group.disabled === false;\n const hasActiveOptions = choices.some((choice) => {\n return choice.active === true && choice.disabled === false;\n });\n return isActive && hasActiveOptions;\n }, []);\n\n return values;\n }\n\n /**\n * Get group by group id\n * @param {Number} id Group ID\n * @return {Object} Group data\n */\n getGroupById(id) {\n const groups = this.getGroups();\n const foundGroup = groups.find((group) => {\n return group.id === id;\n });\n\n return foundGroup;\n }\n}\n\nmodule.exports = Store;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/store/index.js","'use strict';\n\nexports.__esModule = true;\nexports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined;\n\nvar _createStore = require('./createStore');\n\nvar _createStore2 = _interopRequireDefault(_createStore);\n\nvar _combineReducers = require('./combineReducers');\n\nvar _combineReducers2 = _interopRequireDefault(_combineReducers);\n\nvar _bindActionCreators = require('./bindActionCreators');\n\nvar _bindActionCreators2 = _interopRequireDefault(_bindActionCreators);\n\nvar _applyMiddleware = require('./applyMiddleware');\n\nvar _applyMiddleware2 = _interopRequireDefault(_applyMiddleware);\n\nvar _compose = require('./compose');\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nvar _warning = require('./utils/warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/*\n* This is a dummy function to check if the function name has been altered by minification.\n* If the function has been minified and NODE_ENV !== 'production', warn the user.\n*/\nfunction isCrushed() {}\n\nif (process.env.NODE_ENV !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {\n (0, _warning2['default'])('You are currently using minified code outside of NODE_ENV === \\'production\\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');\n}\n\nexports.createStore = _createStore2['default'];\nexports.combineReducers = _combineReducers2['default'];\nexports.bindActionCreators = _bindActionCreators2['default'];\nexports.applyMiddleware = _applyMiddleware2['default'];\nexports.compose = _compose2['default'];\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/index.js\n// module id = 4\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports.ActionTypes = undefined;\nexports['default'] = createStore;\n\nvar _isPlainObject = require('lodash/isPlainObject');\n\nvar _isPlainObject2 = _interopRequireDefault(_isPlainObject);\n\nvar _symbolObservable = require('symbol-observable');\n\nvar _symbolObservable2 = _interopRequireDefault(_symbolObservable);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar ActionTypes = exports.ActionTypes = {\n INIT: '@@redux/INIT'\n};\n\n/**\n * Creates a Redux store that holds the state tree.\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} enhancer The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error('Expected the enhancer to be a function.');\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error('Expected the reducer to be a function.');\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n function getState() {\n return currentState;\n }\n\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error('Expected listener to be a function.');\n }\n\n var isSubscribed = true;\n\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n isSubscribed = false;\n\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n };\n }\n\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n function dispatch(action) {\n if (!(0, _isPlainObject2['default'])(action)) {\n throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error('Actions may not have an undefined \"type\" property. ' + 'Have you misspelled a constant?');\n }\n\n if (isDispatching) {\n throw new Error('Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n for (var i = 0; i < listeners.length; i++) {\n listeners[i]();\n }\n\n return action;\n }\n\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error('Expected the nextReducer to be a function.');\n }\n\n currentReducer = nextReducer;\n dispatch({ type: ActionTypes.INIT });\n }\n\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/zenparsing/es-observable\n */\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object') {\n throw new TypeError('Expected the observer to be an object.');\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return { unsubscribe: unsubscribe };\n }\n }, _ref[_symbolObservable2['default']] = function () {\n return this;\n }, _ref;\n }\n\n // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n dispatch({ type: ActionTypes.INIT });\n\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[_symbolObservable2['default']] = observable, _ref2;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/createStore.js\n// module id = 5\n// module chunks = 0","var baseGetTag = require('./_baseGetTag'),\n getPrototype = require('./_getPrototype'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/** Used to infer the `Object` constructor. */\nvar objectCtorString = funcToString.call(Object);\n\n/**\n * Checks if `value` is a plain object, that is, an object created by the\n * `Object` constructor or one with a `[[Prototype]]` of `null`.\n *\n * @static\n * @memberOf _\n * @since 0.8.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * }\n *\n * _.isPlainObject(new Foo);\n * // => false\n *\n * _.isPlainObject([1, 2, 3]);\n * // => false\n *\n * _.isPlainObject({ 'x': 0, 'y': 0 });\n * // => true\n *\n * _.isPlainObject(Object.create(null));\n * // => true\n */\nfunction isPlainObject(value) {\n if (!isObjectLike(value) || baseGetTag(value) != objectTag) {\n return false;\n }\n var proto = getPrototype(value);\n if (proto === null) {\n return true;\n }\n var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return typeof Ctor == 'function' && Ctor instanceof Ctor &&\n funcToString.call(Ctor) == objectCtorString;\n}\n\nmodule.exports = isPlainObject;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/isPlainObject.js\n// module id = 6\n// module chunks = 0","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_baseGetTag.js\n// module id = 7\n// module chunks = 0","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_Symbol.js\n// module id = 8\n// module chunks = 0","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_root.js\n// module id = 9\n// module chunks = 0","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_freeGlobal.js\n// module id = 10\n// module chunks = 0","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_getRawTag.js\n// module id = 11\n// module chunks = 0","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_objectToString.js\n// module id = 12\n// module chunks = 0","var overArg = require('./_overArg');\n\n/** Built-in value references. */\nvar getPrototype = overArg(Object.getPrototypeOf, Object);\n\nmodule.exports = getPrototype;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_getPrototype.js\n// module id = 13\n// module chunks = 0","/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\nmodule.exports = overArg;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/_overArg.js\n// module id = 14\n// module chunks = 0","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/lodash/isObjectLike.js\n// module id = 15\n// module chunks = 0","module.exports = require('./lib/index');\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/index.js\n// module id = 16\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _ponyfill = require('./ponyfill');\n\nvar _ponyfill2 = _interopRequireDefault(_ponyfill);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nvar root; /* global window */\n\n\nif (typeof self !== 'undefined') {\n root = self;\n} else if (typeof window !== 'undefined') {\n root = window;\n} else if (typeof global !== 'undefined') {\n root = global;\n} else if (typeof module !== 'undefined') {\n root = module;\n} else {\n root = Function('return this')();\n}\n\nvar result = (0, _ponyfill2['default'])(root);\nexports['default'] = result;\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/lib/index.js\n// module id = 17\n// module chunks = 0","module.exports = function(module) {\r\n\tif(!module.webpackPolyfill) {\r\n\t\tmodule.deprecate = function() {};\r\n\t\tmodule.paths = [];\r\n\t\t// module.parent = undefined by default\r\n\t\tmodule.children = [];\r\n\t\tmodule.webpackPolyfill = 1;\r\n\t}\r\n\treturn module;\r\n}\r\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// (webpack)/buildin/module.js\n// module id = 18\n// module chunks = 0","'use strict';\n\nObject.defineProperty(exports, \"__esModule\", {\n\tvalue: true\n});\nexports['default'] = symbolObservablePonyfill;\nfunction symbolObservablePonyfill(root) {\n\tvar result;\n\tvar _Symbol = root.Symbol;\n\n\tif (typeof _Symbol === 'function') {\n\t\tif (_Symbol.observable) {\n\t\t\tresult = _Symbol.observable;\n\t\t} else {\n\t\t\tresult = _Symbol('observable');\n\t\t\t_Symbol.observable = result;\n\t\t}\n\t} else {\n\t\tresult = '@@observable';\n\t}\n\n\treturn result;\n};\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/symbol-observable/lib/ponyfill.js\n// module id = 19\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = combineReducers;\n\nvar _createStore = require('./createStore');\n\nvar _isPlainObject = require('lodash/isPlainObject');\n\nvar _isPlainObject2 = _interopRequireDefault(_isPlainObject);\n\nvar _warning = require('./utils/warning');\n\nvar _warning2 = _interopRequireDefault(_warning);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\nfunction getUndefinedStateErrorMessage(key, action) {\n var actionType = action && action.type;\n var actionName = actionType && '\"' + actionType.toString() + '\"' || 'an action';\n\n return 'Given action ' + actionName + ', reducer \"' + key + '\" returned undefined. ' + 'To ignore an action, you must explicitly return the previous state.';\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === _createStore.ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!(0, _isPlainObject2['default'])(inputState)) {\n return 'The ' + argumentName + ' has unexpected type of \"' + {}.toString.call(inputState).match(/\\s([a-z|A-Z]+)/)[1] + '\". Expected argument to be an object with the following ' + ('keys: \"' + reducerKeys.join('\", \"') + '\"');\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n\n if (unexpectedKeys.length > 0) {\n return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('\"' + unexpectedKeys.join('\", \"') + '\" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('\"' + reducerKeys.join('\", \"') + '\". Unexpected keys will be ignored.');\n }\n}\n\nfunction assertReducerSanity(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT });\n\n if (typeof initialState === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');\n }\n\n var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');\n if (typeof reducer(undefined, { type: type }) === 'undefined') {\n throw new Error('Reducer \"' + key + '\" returned undefined when probed with a random type. ' + ('Don\\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in \"redux/*\" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');\n }\n });\n}\n\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n (0, _warning2['default'])('No reducer provided for key \"' + key + '\"');\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n var finalReducerKeys = Object.keys(finalReducers);\n\n if (process.env.NODE_ENV !== 'production') {\n var unexpectedKeyCache = {};\n }\n\n var sanityError;\n try {\n assertReducerSanity(finalReducers);\n } catch (e) {\n sanityError = e;\n }\n\n return function combination() {\n var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];\n var action = arguments[1];\n\n if (sanityError) {\n throw sanityError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n if (warningMessage) {\n (0, _warning2['default'])(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n for (var i = 0; i < finalReducerKeys.length; i++) {\n var key = finalReducerKeys[i];\n var reducer = finalReducers[key];\n var previousStateForKey = state[key];\n var nextStateForKey = reducer(previousStateForKey, action);\n if (typeof nextStateForKey === 'undefined') {\n var errorMessage = getUndefinedStateErrorMessage(key, action);\n throw new Error(errorMessage);\n }\n nextState[key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n return hasChanged ? nextState : state;\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/combineReducers.js\n// module id = 20\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = warning;\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n /* eslint-disable no-empty */\n } catch (e) {}\n /* eslint-enable no-empty */\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/utils/warning.js\n// module id = 21\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\nexports['default'] = bindActionCreators;\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(undefined, arguments));\n };\n}\n\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass a single function as the first argument,\n * and get a function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write \"import ActionCreators from\" instead of \"import * as ActionCreators from\"?');\n }\n\n var keys = Object.keys(actionCreators);\n var boundActionCreators = {};\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var actionCreator = actionCreators[key];\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n return boundActionCreators;\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/bindActionCreators.js\n// module id = 22\n// module chunks = 0","'use strict';\n\nexports.__esModule = true;\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports['default'] = applyMiddleware;\n\nvar _compose = require('./compose');\n\nvar _compose2 = _interopRequireDefault(_compose);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function (reducer, preloadedState, enhancer) {\n var store = createStore(reducer, preloadedState, enhancer);\n var _dispatch = store.dispatch;\n var chain = [];\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch(action) {\n return _dispatch(action);\n }\n };\n chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = _compose2['default'].apply(undefined, chain)(store.dispatch);\n\n return _extends({}, store, {\n dispatch: _dispatch\n });\n };\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/applyMiddleware.js\n// module id = 23\n// module chunks = 0","\"use strict\";\n\nexports.__esModule = true;\nexports[\"default\"] = compose;\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\n\nfunction compose() {\n for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n var last = funcs[funcs.length - 1];\n var rest = funcs.slice(0, -1);\n return function () {\n return rest.reduceRight(function (composed, f) {\n return f(composed);\n }, last.apply(undefined, arguments));\n };\n}\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./~/redux/lib/compose.js\n// module id = 24\n// module chunks = 0","import { combineReducers } from 'redux';\nimport items from './items';\nimport groups from './groups';\nimport choices from './choices';\n\nconst appReducer = combineReducers({\n items,\n groups,\n choices,\n});\n\nconst rootReducer = (passedState, action) => {\n let state = passedState;\n // If we are clearing all items, groups and options we reassign\n // state and then pass that state to our proper reducer. This isn't\n // mutating our actual state\n // See: http://stackoverflow.com/a/35641992\n if (action.type === 'CLEAR_ALL') {\n state = undefined;\n }\n\n return appReducer(state, action);\n};\n\nexport default rootReducer;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/index.js","const items = (state = [], action) => {\n switch (action.type) {\n case 'ADD_ITEM': {\n // Add object to items array\n const newState = [...state, {\n id: action.id,\n choiceId: action.choiceId,\n groupId: action.groupId,\n value: action.value,\n label: action.label,\n active: true,\n highlighted: false,\n }];\n\n return newState.map((item) => {\n if (item.highlighted) {\n item.highlighted = false;\n }\n return item;\n });\n }\n\n case 'REMOVE_ITEM': {\n // Set item to inactive\n return state.map((item) => {\n if (item.id === action.id) {\n item.active = false;\n }\n return item;\n });\n }\n\n case 'HIGHLIGHT_ITEM': {\n return state.map((item) => {\n if (item.id === action.id) {\n item.highlighted = action.highlighted;\n }\n return item;\n });\n }\n\n default: {\n return state;\n }\n }\n};\n\nexport default items;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/items.js","const groups = (state = [], action) => {\n switch (action.type) {\n case 'ADD_GROUP': {\n return [...state, {\n id: action.id,\n value: action.value,\n active: action.active,\n disabled: action.disabled,\n }];\n }\n\n case 'CLEAR_CHOICES': {\n return state.groups = [];\n }\n\n default: {\n return state;\n }\n }\n};\n\nexport default groups;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/groups.js","const choices = (state = [], action) => {\n switch (action.type) {\n case 'ADD_CHOICE': {\n /*\n A disabled choice appears in the choice dropdown but cannot be selected\n A selected choice has been added to the passed input's value (added as an item)\n An active choice appears within the choice dropdown\n */\n return [...state, {\n id: action.id,\n groupId: action.groupId,\n value: action.value,\n label: action.label,\n disabled: action.disabled,\n selected: false,\n active: true,\n score: 9999,\n }];\n }\n\n case 'ADD_ITEM': {\n let newState = state;\n\n // If all choices need to be activated\n if (action.activateOptions) {\n newState = state.map((choice) => {\n choice.active = action.active;\n return choice;\n });\n }\n // When an item is added and it has an associated choice,\n // we want to disable it so it can't be chosen again\n if (action.choiceId > -1) {\n newState = state.map((choice) => {\n if (choice.id === parseInt(action.choiceId, 10)) {\n choice.selected = true;\n }\n return choice;\n });\n }\n\n return newState;\n }\n\n case 'REMOVE_ITEM': {\n // When an item is removed and it has an associated choice,\n // we want to re-enable it so it can be chosen again\n if (action.choiceId > -1) {\n return state.map((choice) => {\n if (choice.id === parseInt(action.choiceId, 10)) {\n choice.selected = false;\n }\n return choice;\n });\n }\n\n return state;\n }\n\n case 'FILTER_CHOICES': {\n const filteredResults = action.results;\n const filteredState = state.map((choice) => {\n // Set active state based on whether choice is\n // within filtered results\n\n choice.active = filteredResults.some((result) => {\n if (result.item.id === choice.id) {\n choice.score = result.score;\n return true;\n }\n return false;\n });\n\n return choice;\n });\n\n return filteredState;\n }\n\n case 'ACTIVATE_CHOICES': {\n return state.map((choice) => {\n choice.active = action.active;\n return choice;\n });\n }\n\n case 'CLEAR_CHOICES': {\n return state.choices = [];\n }\n\n default: {\n return state;\n }\n }\n};\n\nexport default choices;\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/reducers/choices.js","export const addItem = (value, label, id, choiceId, groupId) => {\n return {\n type: 'ADD_ITEM',\n value,\n label,\n id,\n choiceId,\n groupId,\n };\n};\n\nexport const removeItem = (id, choiceId) => {\n return {\n type: 'REMOVE_ITEM',\n id,\n choiceId,\n };\n};\n\nexport const highlightItem = (id, highlighted) => {\n return {\n type: 'HIGHLIGHT_ITEM',\n id,\n highlighted,\n };\n};\n\nexport const addChoice = (value, label, id, groupId, disabled) => {\n return {\n type: 'ADD_CHOICE',\n value,\n label,\n id,\n groupId,\n disabled,\n };\n};\n\nexport const filterChoices = (results) => {\n return {\n type: 'FILTER_CHOICES',\n results,\n };\n};\n\nexport const activateChoices = (active = true) => {\n return {\n type: 'ACTIVATE_CHOICES',\n active,\n };\n};\n\nexport const clearChoices = () => {\n return {\n type: 'CLEAR_CHOICES',\n };\n};\n\nexport const addGroup = (value, id, active, disabled) => {\n return {\n type: 'ADD_GROUP',\n value,\n id,\n active,\n disabled,\n };\n};\n\nexport const clearAll = () => {\n return {\n type: 'CLEAR_ALL',\n };\n};\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/actions/index.js","/* eslint-disable */\n/**\n * Capitalises the first letter of each word in a string\n * @param {String} str String to capitalise\n * @return {String} Capitalised string\n */\nexport const capitalise = function(str) {\n return str.replace(/\\w\\S*/g, function(txt) {\n return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();\n });\n};\n\n/**\n * Tests the type of an object\n * @param {String} type Type to test object against\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const getType = function(obj) {\n return Object.prototype.toString.call(obj).slice(8, -1);\n};\n\n/**\n * Tests the type of an object\n * @param {String} type Type to test object against\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const isType = function(type, obj) {\n var clas = getType(obj);\n return obj !== undefined && obj !== null && clas === type;\n};\n\n/**\n * Tests to see if a passed object is a node\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const isNode = (o) => {\n return (\n typeof Node === \"object\" ? o instanceof Node :\n o && typeof o === \"object\" && typeof o.nodeType === \"number\" && typeof o.nodeName === \"string\"\n );\n};\n\n/**\n * Tests to see if a passed object is an element\n * @param {Object} obj Object to be tested\n * @return {Boolean}\n */\nexport const isElement = (o) => {\n return (\n typeof HTMLElement === \"object\" ? o instanceof HTMLElement : //DOM2\n o && typeof o === \"object\" && o !== null && o.nodeType === 1 && typeof o.nodeName === \"string\"\n );\n};\n\n/**\n * Merges unspecified amount of objects into new object\n * @private\n * @return {Object} Merged object of arguments\n */\nexport const extend = function() {\n let extended = {};\n let length = arguments.length;\n\n /**\n * Merge one object into another\n * @param {Object} obj Object to merge into extended object\n */\n let merge = function(obj) {\n for (let prop in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, prop)) {\n // If deep merge and property is an object, merge properties\n if (isType('Object', obj[prop])) {\n extended[prop] = extend(true, extended[prop], obj[prop]);\n } else {\n extended[prop] = obj[prop];\n }\n }\n }\n };\n\n // Loop through each passed argument\n for (let i = 0; i < length; i++) {\n // store argument at position i\n let obj = arguments[i];\n\n // If we are in fact dealing with an object, merge it.\n if (isType('Object', obj)) {\n merge(obj);\n }\n }\n\n return extended;\n};\n\n/**\n * CSS transition end event listener\n * @return\n */\nexport const whichTransitionEvent = function() {\n var t,\n el = document.createElement(\"fakeelement\");\n\n var transitions = {\n \"transition\": \"transitionend\",\n \"OTransition\": \"oTransitionEnd\",\n \"MozTransition\": \"transitionend\",\n \"WebkitTransition\": \"webkitTransitionEnd\"\n }\n\n for (t in transitions) {\n if (el.style[t] !== undefined) {\n return transitions[t];\n }\n }\n};\n\n/**\n * CSS animation end event listener\n * @return\n */\nexport const whichAnimationEvent = function() {\n var t,\n el = document.createElement('fakeelement');\n\n var animations = {\n 'animation': 'animationend',\n 'OAnimation': 'oAnimationEnd',\n 'MozAnimation': 'animationend',\n 'WebkitAnimation': 'webkitAnimationEnd'\n };\n\n for (t in animations) {\n if (el.style[t] !== undefined) {\n return animations[t];\n }\n }\n};\n\n/**\n * Get the ancestors of each element in the current set of matched elements,\n * up to but not including the element matched by the selector\n * @param {NodeElement} elem Element to begin search from\n * @param {NodeElement} parent Parent to find\n * @param {String} selector Class to find\n * @return {Array} Array of parent elements\n */\nexport const getParentsUntil = function(elem, parent, selector) {\n var parents = [];\n // Get matches\n for (; elem && elem !== document; elem = elem.parentNode) {\n\n // Check if parent has been reached\n if (parent) {\n\n var parentType = parent.charAt(0);\n\n // If parent is a class\n if (parentType === '.') {\n if (elem.classList.contains(parent.substr(1))) {\n break;\n }\n }\n\n // If parent is an ID\n if (parentType === '#') {\n if (elem.id === parent.substr(1)) {\n break;\n }\n }\n\n // If parent is a data attribute\n if (parentType === '[') {\n if (elem.hasAttribute(parent.substr(1, parent.length - 1))) {\n break;\n }\n }\n\n // If parent is a tag\n if (elem.tagName.toLowerCase() === parent) {\n break;\n }\n\n }\n if (selector) {\n var selectorType = selector.charAt(0);\n\n // If selector is a class\n if (selectorType === '.') {\n if (elem.classList.contains(selector.substr(1))) {\n parents.push(elem);\n }\n }\n\n // If selector is an ID\n if (selectorType === '#') {\n if (elem.id === selector.substr(1)) {\n parents.push(elem);\n }\n }\n\n // If selector is a data attribute\n if (selectorType === '[') {\n if (elem.hasAttribute(selector.substr(1, selector.length - 1))) {\n parents.push(elem);\n }\n }\n\n // If selector is a tag\n if (elem.tagName.toLowerCase() === selector) {\n parents.push(elem);\n }\n\n } else {\n parents.push(elem);\n }\n }\n\n // Return parents if any exist\n if (parents.length === 0) {\n return null;\n } else {\n return parents;\n }\n};\n\nexport const wrap = function(element, wrapper) {\n wrapper = wrapper || document.createElement('div');\n if (element.nextSibling) {\n element.parentNode.insertBefore(wrapper, element.nextSibling);\n } else {\n element.parentNode.appendChild(wrapper);\n }\n return wrapper.appendChild(element);\n};\n\nexport const getSiblings = function(elem) {\n var siblings = [];\n var sibling = elem.parentNode.firstChild;\n for (; sibling; sibling = sibling.nextSibling) {\n if (sibling.nodeType === 1 && sibling !== elem) {\n siblings.push(sibling);\n }\n }\n return siblings;\n};\n\n/**\n * Find ancestor in DOM tree\n * @param {NodeElement} el Element to start search from\n * @param {[type]} cls Class of parent\n * @return {NodeElement} Found parent element\n */\nexport const findAncestor = function(el, cls) {\n while ((el = el.parentElement) && !el.classList.contains(cls));\n return el;\n};\n\n/**\n * Find ancestor in DOM tree by attribute name\n * @param {NodeElement} el Element to start search from\n * @param {string} attr Attribute name of parent\n * @return {?NodeElement} Found parent element or null\n */\nexport const findAncestorByAttrName = function(el, attr) {\n let target = el;\n\n while (target) {\n if (target.hasAttribute(attr)) {\n return target;\n }\n\n target = target.parentElement;\n }\n\n return null;\n};\n\n/**\n * Debounce an event handler.\n * @param {Function} func Function to run after wait\n * @param {Number} wait The delay before the function is executed\n * @param {Boolean} immediate If passed, trigger the function on the leading edge, instead of the trailing.\n * @return {Function} A function will be called after it stops being called for a given delay\n */\nexport const debounce = function(func, wait, immediate) {\n var timeout;\n return function() {\n var context = this,\n args = arguments;\n var later = function() {\n timeout = null;\n if (!immediate) func.apply(context, args);\n };\n var callNow = immediate && !timeout;\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n if (callNow) func.apply(context, args);\n };\n};\n\n/**\n * Get an element's distance from the top of the page\n * @private\n * @param {NodeElement} el Element to test for\n * @return {Number} Elements Distance from top of page\n */\nexport const getElemDistance = function(el) {\n var location = 0;\n if (el.offsetParent) {\n do {\n location += el.offsetTop;\n el = el.offsetParent;\n } while (el);\n }\n return location >= 0 ? location : 0;\n};\n\n/**\n * Determine element height multiplied by any offsets\n * @private\n * @param {HTMLElement} el Element to test for\n * @return {Number} Height of element\n */\nexport const getElementOffset = function(el, offset) {\n var elOffset = offset;\n if (elOffset > 1) elOffset = 1;\n if (elOffset > 0) elOffset = 0;\n\n return Math.max(el.offsetHeight * elOffset);\n};\n\n/**\n * Get the next or previous element from a given start point\n * @param {HTMLElement} startEl Element to start position from\n * @param {String} className The class we will look through\n * @param {Number} direction Positive next element, negative previous element\n * @return {[HTMLElement} Found element\n */\nexport const getAdjacentEl = (startEl, className, direction = 1) => {\n if (!startEl || !className) return;\n\n const parent = startEl.parentNode.parentNode;\n const children = Array.from(parent.querySelectorAll(className));\n\n const startPos = children.indexOf(startEl);\n const operatorDirection = direction > 0 ? 1 : -1;\n\n return children[startPos + operatorDirection];\n};\n\n/**\n * Get scroll position based on top/bottom position\n * @private\n * @return {String} Position of scroll\n */\nexport const getScrollPosition = function(position) {\n if (position === 'bottom') {\n // Scroll position from the bottom of the viewport\n return Math.max((window.scrollY || window.pageYOffset) + (window.innerHeight || document.documentElement.clientHeight));\n } else {\n // Scroll position from the top of the viewport\n return (window.scrollY || window.pageYOffset);\n }\n};\n\n/**\n * Determine whether an element is within the viewport\n * @param {HTMLElement} el Element to test\n * @return {String} Position of scroll\n * @return {Boolean}\n */\nexport const isInView = function(el, position, offset) {\n // If the user has scrolled further than the distance from the element to the top of its parent\n return this.getScrollPosition(position) > (this.getElemDistance(el) + this.getElementOffset(el, offset)) ? true : false;\n};\n\n/**\n * Determine whether an element is within\n * @param {HTMLElement} el Element to test\n * @param {HTMLElement} parent Scrolling parent\n * @param {Number} direction Whether element is visible from above or below\n * @return {Boolean}\n */\nexport const isScrolledIntoView = (el, parent, direction = 1) => {\n if (!el) return;\n\n let isVisible;\n\n if (direction > 0) {\n // In view from bottom\n isVisible = (parent.scrollTop + parent.offsetHeight) >= (el.offsetTop + el.offsetHeight);\n } else {\n // In view from top\n isVisible = el.offsetTop >= parent.scrollTop;\n }\n\n return isVisible;\n};\n\n/**\n * Remove html tags from a string\n * @param {String} Initial string/html\n * @return {String} Sanitised string\n */\nexport const stripHTML = function(html) {\n let el = document.createElement(\"DIV\");\n el.innerHTML = html;\n return el.textContent || el.innerText || \"\";\n};\n\n/**\n * Adds animation to an element and removes it upon animation completion\n * @param {Element} el Element to add animation to\n * @param {String} animation Animation class to add to element\n * @return\n */\nexport const addAnimation = (el, animation) => {\n let animationEvent = whichAnimationEvent();\n\n let removeAnimation = () => {\n el.classList.remove(animation);\n el.removeEventListener(animationEvent, removeAnimation, false);\n };\n\n el.classList.add(animation);\n el.addEventListener(animationEvent, removeAnimation, false);\n};\n\n\n/**\n * Get a random number between a range\n * @param {Number} min Minimum range\n * @param {Number} max Maximum range\n * @return {Number} Random number\n */\nexport const getRandomNumber = function(min, max) {\n return Math.floor(Math.random() * (max - min) + min);\n};\n\n/**\n * Turn a string into a node\n * @param {String} String to convert\n * @return {HTMLElement} Converted node element\n */\nexport const strToEl = (function() {\n var tmpEl = document.createElement('div');\n return function(str) {\n var r;\n tmpEl.innerHTML = str;\n r = tmpEl.children[0];\n\n while (tmpEl.firstChild) {\n tmpEl.removeChild(tmpEl.firstChild);\n }\n\n return r;\n };\n}());\n\n/**\n * Sets the width of a passed input based on its value\n * @return {Number} Width of input\n */\nexport const getWidthOfInput = (input) => {\n const value = input.value || input.placeholder;\n let width = input.offsetWidth;\n\n if (value) {\n const testEl = strToEl(`${ value }`);\n testEl.style.position = 'absolute';\n testEl.style.padding = '0';\n testEl.style.top = '-9999px';\n testEl.style.left = '-9999px';\n testEl.style.width = 'auto';\n testEl.style.whiteSpace = 'pre';\n\n document.body.appendChild(testEl);\n\n if (value && testEl.offsetWidth !== input.offsetWidth) {\n width = testEl.offsetWidth + 4;\n }\n\n document.body.removeChild(testEl);\n }\n\n return `${width}px`;\n};\n\n/**\n * Sorting function for current and previous string\n * @param {String} a Current value\n * @param {String} b Next value\n * @return {Number} -1 for after previous,\n * 1 for before,\n * 0 for same location\n */\nexport const sortByAlpha = (a, b) => {\n const labelA = (a.label || a.value).toLowerCase();\n const labelB = (b.label || b.value).toLowerCase();\n\n if (labelA < labelB) return -1;\n if (labelA > labelB) return 1;\n return 0;\n};\n\n/**\n * Sort by numeric score\n * @param {Object} a Current value\n * @param {Object} b Next value\n * @return {Number} -1 for after previous,\n * 1 for before,\n * 0 for same location\n */\nexport const sortByScore = (a, b) => {\n return a.score - b.score;\n};\n\n/**\n * Trigger native event\n * @param {NodeElement} element Element to trigger event on\n * @param {String} type Type of event to trigger\n * @param {Object} customArgs Data to pass with event\n * @return {Object} Triggered event\n */\nexport const triggerEvent = (element, type, customArgs = null) => {\n const event = new CustomEvent(type, {\n detail: customArgs,\n bubbles: true,\n cancelable: true\n });\n\n return element.dispatchEvent(event);\n};\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/lib/utils.js","/* eslint-disable */\n(function () {\n // Production steps of ECMA-262, Edition 6, 22.1.2.1\n // Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from\n if (!Array.from) {\n Array.from = (function() {\n var toStr = Object.prototype.toString;\n\n var isCallable = function(fn) {\n return typeof fn === 'function' || toStr.call(fn) === '[object Function]';\n };\n\n var toInteger = function(value) {\n var number = Number(value);\n if (isNaN(number)) {\n return 0;\n }\n if (number === 0 || !isFinite(number)) {\n return number;\n }\n return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));\n };\n\n var maxSafeInteger = Math.pow(2, 53) - 1;\n\n var toLength = function(value) {\n var len = toInteger(value);\n return Math.min(Math.max(len, 0), maxSafeInteger);\n };\n\n // The length property of the from method is 1.\n return function from(arrayLike /*, mapFn, thisArg */ ) {\n // 1. Let C be the this value.\n var C = this;\n\n // 2. Let items be ToObject(arrayLike).\n var items = Object(arrayLike);\n\n // 3. ReturnIfAbrupt(items).\n if (arrayLike == null) {\n throw new TypeError(\"Array.from requires an array-like object - not null or undefined\");\n }\n\n // 4. If mapfn is undefined, then let mapping be false.\n var mapFn = arguments.length > 1 ? arguments[1] : void undefined;\n var T;\n if (typeof mapFn !== 'undefined') {\n // 5. else\n // 5. a If IsCallable(mapfn) is false, throw a TypeError exception.\n if (!isCallable(mapFn)) {\n throw new TypeError('Array.from: when provided, the second argument must be a function');\n }\n\n // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.\n if (arguments.length > 2) {\n T = arguments[2];\n }\n }\n\n // 10. Let lenValue be Get(items, \"length\").\n // 11. Let len be ToLength(lenValue).\n var len = toLength(items.length);\n\n // 13. If IsConstructor(C) is true, then\n // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.\n // 14. a. Else, Let A be ArrayCreate(len).\n var A = isCallable(C) ? Object(new C(len)) : new Array(len);\n\n // 16. Let k be 0.\n var k = 0;\n // 17. Repeat, while k < len… (also steps a - h)\n var kValue;\n while (k < len) {\n kValue = items[k];\n if (mapFn) {\n A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);\n } else {\n A[k] = kValue;\n }\n k += 1;\n }\n // 18. Let putStatus be Put(A, \"length\", len, true).\n A.length = len;\n // 20. Return A.\n return A;\n };\n }());\n }\n\n // Reference: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find\n if (!Array.prototype.find) {\n Array.prototype.find = function(predicate) {\n 'use strict';\n if (this == null) {\n throw new TypeError('Array.prototype.find called on null or undefined');\n }\n if (typeof predicate !== 'function') {\n throw new TypeError('predicate must be a function');\n }\n var list = Object(this);\n var length = list.length >>> 0;\n var thisArg = arguments[1];\n var value;\n\n for (var i = 0; i < length; i++) {\n value = list[i];\n if (predicate.call(thisArg, value, i, list)) {\n return value;\n }\n }\n return undefined;\n };\n }\n\n function CustomEvent (event, params) {\n params = params || {\n bubbles: false,\n cancelable: false,\n detail: undefined\n };\n var evt = document.createEvent('CustomEvent');\n evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\n return evt;\n }\n\n CustomEvent.prototype = window.Event.prototype;\n\n window.CustomEvent = CustomEvent;\n})();\n\n\n\n// WEBPACK FOOTER //\n// assets/scripts/src/lib/polyfills.js"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;ACVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;;;;ACtCA;AACA;;;AAAA;AACA;;;AAAA;AACA;AAWA;AACA;AAeA;AACA;;;;;;;;;AAEA;;;AAGA;AACA;AAAA;AACA;AADA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAxBA;AA0BA;AACA;AADA;AAGA;AACA;AAhEA;AACA;AAkEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AAQA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AAAA;AAAA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AASA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;AAQA;AAAA;AACA;AADA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAWA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAzBA;AACA;AA2BA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA3CA;AACA;AA6CA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;AAMA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AAAA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AAUA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;;;;;;;;;;;;AASA;AAAA;AACA;AADA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;AAOA;AACA;AACA;AACA;AAHA;AAAA;AAAA;AACA;AAEA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AACA;AAKA;AACA;AAKA;AACA;AACA;AAGA;AACA;AACA;AAKA;AACA;AACA;AAKA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AACA;AACA;AAGA;AAzEA;AACA;AA2EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAEA;;;;;;ACvvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;AC3zBA;AACA;AAAA;AACA;;;;;;;AACA;AACA;AAAA;AACA;AAAA;AAIA;AACA;AACA;;;;;;;;AAIA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AAAA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AA7JA;AACA;AACA;AA8JA;;;;;;ACnKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACpQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC3BA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACRA;AACA;AACA;AACA;AACA;AACA;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACrBA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AC5BA;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AC7IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AClDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;ACrCA;AACA;AAAA;AACA;;;AAAA;AACA;;;AAAA;AACA;;;;;AACA;AACA;AACA;AACA;AAHA;AACA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACvBA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAPA;AACA;AASA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AA1CA;AA4CA;AACA;;;;;;;;;;;;;;;AC9CA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AAJA;AAMA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAhBA;AAkBA;AACA;;;;;;;;;;;;;;;ACpBA;AAAA;AAAA;AACA;AAAA;AACA;AAAA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AARA;AAUA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AA3FA;AA6FA;AACA;;;;;;;;;;;;AC/FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AANA;AAQA;AACA;AACA;AACA;AACA;AACA;AAFA;AAIA;AACA;AACA;AAAA;AACA;AAAA;AACA;AACA;AAFA;AAIA;AACA;AACA;AACA;AACA;AADA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AALA;AAOA;AACA;AACA;AACA;AACA;AADA;AAGA;;;;;;;;;;;;;;ACxEA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AAIA;AACA;AACA;;;;;AAKA;AACA;AAEA;AAEA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AAJA;AACA;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AACA;AACA;AACA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AAMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;;;;;;AAMA;AACA;AACA;AACA;AACA;;;;;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;AAQA;AACA;AACA;AACA;AACA;;;;;;;AAOA;AAAA;AACA;AAAA;AACA;AACA;AACA;AAHA;AACA;AAKA;;;;;;;;;ACthBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAHA;AAKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;","sourceRoot":""} \ No newline at end of file diff --git a/assets/scripts/dist/choices.min.js b/assets/scripts/dist/choices.min.js index e8df23ac4..36c3fc341 100644 --- a/assets/scripts/dist/choices.min.js +++ b/assets/scripts/dist/choices.min.js @@ -1,4 +1,4 @@ -/*! choices.js v2.7.6 | (c) 2017 Josh Johnson | https://github.com/jshjohnson/Choices#readme */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Choices=t():e.Choices=t()}(this,function(){return function(e){function t(n){if(i[n])return i[n].exports;var s=i[n]={exports:{},id:n,loaded:!1};return e[n].call(s.exports,s,s.exports,t),s.loaded=!0,s.exports}var i={};return t.m=e,t.c=i,t.p="/assets/scripts/dist/",t(0)}([function(e,t,i){e.exports=i(1)},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function o(e){if(Array.isArray(e)){for(var t=0,i=Array(e.length);t0&&void 0!==arguments[0]?arguments[0]:"[data-choice]",n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(r(this,e),(0,p.isType)("String",i)){var s=document.querySelectorAll(i);if(s.length>1)for(var o=1;o"'+e+'"'},maxItemText:function(e){return"Only "+e+" values can be added."},uniqueItemText:"Only unique values can be added.",classNames:{containerOuter:"choices",containerInner:"choices__inner",input:"choices__input",inputCloned:"choices__input--cloned",list:"choices__list",listItems:"choices__list--multiple",listSingle:"choices__list--single",listDropdown:"choices__list--dropdown",item:"choices__item",itemSelectable:"choices__item--selectable",itemDisabled:"choices__item--disabled",itemChoice:"choices__item--choice",placeholder:"choices__placeholder",group:"choices__group",groupHeading:"choices__heading",button:"choices__button",activeState:"is-active",focusState:"is-focused",openState:"is-open",disabledState:"is-disabled",highlightedState:"is-highlighted",hiddenState:"is-hidden",flippedState:"is-flipped",loadingState:"is-loading"},fuseOptions:{include:"score"},callbackOnInit:null,callbackOnCreateTemplates:null};if(this.config=(0,p.extend)(c,n),this.store=new u.default(this.render),this.initialised=!1,this.currentState={},this.prevState={},this.currentValue="",this.element=i,this.passedElement=(0,p.isType)("String",i)?document.querySelector(i):i,this.isSelectElement="select-one"===this.passedElement.type||"select-multiple"===this.passedElement.type,this.isTextElement="text"===this.passedElement.type,!this.passedElement)return void console.error("Passed element not found");this.highlightPosition=0,this.canSearch=this.config.search,this.presetChoices=this.config.choices,this.presetItems=this.config.items,this.passedElement.value&&(this.presetItems=this.presetItems.concat(this.passedElement.value.split(this.config.delimiter))),this.init=this.init.bind(this),this.render=this.render.bind(this),this.destroy=this.destroy.bind(this),this.disable=this.disable.bind(this),this._onFocus=this._onFocus.bind(this),this._onBlur=this._onBlur.bind(this),this._onKeyUp=this._onKeyUp.bind(this),this._onKeyDown=this._onKeyDown.bind(this),this._onClick=this._onClick.bind(this),this._onTouchMove=this._onTouchMove.bind(this),this._onTouchEnd=this._onTouchEnd.bind(this),this._onMouseDown=this._onMouseDown.bind(this),this._onMouseOver=this._onMouseOver.bind(this),this._onPaste=this._onPaste.bind(this),this._onInput=this._onInput.bind(this),this.wasTap=!0;var l="classList"in document.documentElement;l||console.error("Choices: Your browser doesn't support Choices");var h=["select-one","select-multiple","text"].some(function(e){return e===t.passedElement.type}),d=(0,p.isElement)(this.passedElement)&&h;if(d){if("active"===this.passedElement.getAttribute("data-choice"))return;this.init()}else console.error("Incompatible input passed")}return a(e,[{key:"init",value:function(){if(this.initialised!==!0){var e=this.config.callbackOnInit;this.initialised=!0,this._createTemplates(),this._createInput(),this.store.subscribe(this.render),this.render(),this._addEventListeners(),e&&(0,p.isType)("Function",e)&&e.call(this)}}},{key:"destroy",value:function(){this.initialised!==!1&&(this._removeEventListeners(),this.passedElement.classList.remove(this.config.classNames.input,this.config.classNames.hiddenState),this.passedElement.removeAttribute("tabindex"),this.passedElement.removeAttribute("style","display:none;"),this.passedElement.removeAttribute("aria-hidden"),this.passedElement.removeAttribute("data-choice","active"),this.passedElement.value=this.passedElement.value,this.containerOuter.parentNode.insertBefore(this.passedElement,this.containerOuter),this.containerOuter.parentNode.removeChild(this.containerOuter),this.clearStore(),this.config.templates=null,this.initialised=!1)}},{key:"renderGroups",value:function(e,t,i){var n=this,s=i||document.createDocumentFragment(),o=this.config.sortFilter;return this.config.shouldSort&&e.sort(o),e.forEach(function(e){var i=t.filter(function(t){return"select-one"===n.passedElement.type?t.groupId===e.id:t.groupId===e.id&&!t.selected});if(i.length>=1){var o=n._getTemplate("choiceGroup",e);s.appendChild(o),n.renderChoices(i,s)}}),s}},{key:"renderChoices",value:function(e,t){var i=this,n=t||document.createDocumentFragment(),s=this.isSearching?p.sortByScore:this.config.sortFilter;return(this.config.shouldSort||this.isSearching)&&e.sort(s),e.forEach(function(e){var t=i._getTemplate("choice",e),s="select-one"===i.passedElement.type||!e.selected;s&&n.appendChild(t)}),n}},{key:"renderItems",value:function(e,t){var i=this,n=t||document.createDocumentFragment(),s=this.store.getItemsReducedToValues(e);if(this.isTextElement)this.passedElement.setAttribute("value",s.join(this.config.delimiter));else{var o=document.createDocumentFragment();e.forEach(function(e){var t=i._getTemplate("option",e);o.appendChild(t)}),this.passedElement.innerHTML="",this.passedElement.appendChild(o)}return e.forEach(function(e){var t=i._getTemplate("item",e);n.appendChild(t)}),n}},{key:"render",value:function(){if(this.currentState=this.store.getState(),this.currentState!==this.prevState){if(!(this.currentState.choices===this.prevState.choices&&this.currentState.groups===this.prevState.groups||"select-multiple"!==this.passedElement.type&&"select-one"!==this.passedElement.type)){var e=this.store.getGroupsFilteredByActive(),t=this.store.getChoicesFilteredByActive(),i=document.createDocumentFragment();if(this.choiceList.innerHTML="",this.config.resetScrollPosition&&(this.choiceList.scrollTop=0),e.length>=1&&this.isSearching!==!0?i=this.renderGroups(e,t,i):t.length>=1&&(i=this.renderChoices(t,i)),i.childNodes&&i.childNodes.length>0)this.choiceList.appendChild(i),this._highlightChoice();else{var n=void 0,s=void 0;this.isSearching?(s=(0,p.isType)("Function",this.config.noResultsText)?this.config.noResultsText():this.config.noResultsText,n=this._getTemplate("notice",s)):(s=(0,p.isType)("Function",this.config.noChoicesText)?this.config.noChoicesText():this.config.noChoicesText,n=this._getTemplate("notice",s)),this.choiceList.appendChild(n)}}if(this.currentState.items!==this.prevState.items){var o=this.store.getItemsFilteredByActive();if(o){var r=this.renderItems(o);this.itemList.innerHTML="",r.childNodes&&this.itemList.appendChild(r)}}this.prevState=this.currentState}}},{key:"highlightItem",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(e){var i=e.id,n=e.groupId,s=n>=0?this.store.getGroupById(n):null;return this.store.dispatch((0,d.highlightItem)(i,!0)),t&&(s&&s.value?(0,p.triggerEvent)(this.passedElement,"highlightItem",{id:i,value:e.value,label:e.label,groupValue:s.value}):(0,p.triggerEvent)(this.passedElement,"highlightItem",{id:i,value:e.value,label:e.label})),this}}},{key:"unhighlightItem",value:function(e){if(e){var t=e.id,i=e.groupId,n=i>=0?this.store.getGroupById(i):null;return this.store.dispatch((0,d.highlightItem)(t,!1)),n&&n.value?(0,p.triggerEvent)(this.passedElement,"unhighlightItem",{id:t,value:e.value,label:e.label,groupValue:n.value}):(0,p.triggerEvent)(this.passedElement,"unhighlightItem",{id:t,value:e.value,label:e.label}),this}}},{key:"highlightAll",value:function(){var e=this,t=this.store.getItems();return t.forEach(function(t){e.highlightItem(t)}),this}},{key:"unhighlightAll",value:function(){var e=this,t=this.store.getItems();return t.forEach(function(t){e.unhighlightItem(t)}),this}},{key:"removeItemsByValue",value:function(e){var t=this;if(!e||!(0,p.isType)("String",e))return void console.error("removeItemsByValue: No value was passed to be removed");var i=this.store.getItemsFilteredByActive();return i.forEach(function(i){i.value===e&&t._removeItem(i)}),this}},{key:"removeActiveItems",value:function(e){var t=this,i=this.store.getItemsFilteredByActive();return i.forEach(function(i){i.active&&e!==i.id&&t._removeItem(i)}),this}},{key:"removeHighlightedItems",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.store.getItemsFilteredByActive();return i.forEach(function(i){i.highlighted&&i.active&&(e._removeItem(i),t&&e._triggerChange(i.value))}),this}},{key:"showDropdown",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=document.body,i=document.documentElement,n=Math.max(t.scrollHeight,t.offsetHeight,i.clientHeight,i.scrollHeight,i.offsetHeight);this.containerOuter.classList.add(this.config.classNames.openState),this.containerOuter.setAttribute("aria-expanded","true"),this.dropdown.classList.add(this.config.classNames.activeState);var s=this.dropdown.getBoundingClientRect(),o=Math.ceil(s.top+window.scrollY+s.height),r=!1;return"auto"===this.config.position?r=o>=n:"top"===this.config.position&&(r=!0),r?this.containerOuter.classList.add(this.config.classNames.flippedState):this.containerOuter.classList.remove(this.config.classNames.flippedState),e&&this.canSearch&&document.activeElement!==this.input&&this.input.focus(),(0,p.triggerEvent)(this.passedElement,"showDropdown",{}),this}},{key:"hideDropdown",value:function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.containerOuter.classList.contains(this.config.classNames.flippedState);return this.containerOuter.classList.remove(this.config.classNames.openState),this.containerOuter.setAttribute("aria-expanded","false"),this.dropdown.classList.remove(this.config.classNames.activeState),t&&this.containerOuter.classList.remove(this.config.classNames.flippedState),e&&this.canSearch&&document.activeElement===this.input&&this.input.blur(),(0,p.triggerEvent)(this.passedElement,"hideDropdown",{}),this}},{key:"toggleDropdown",value:function(){var e=this.dropdown.classList.contains(this.config.classNames.activeState);return e?this.hideDropdown():this.showDropdown(!0),this}},{key:"getValue",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]&&arguments[0],i=this.store.getItemsFilteredByActive(),n=[];return i.forEach(function(i){e.isTextElement?n.push(t?i.value:i):i.active&&n.push(t?i.value:i)}),"select-one"===this.passedElement.type?n[0]:n}},{key:"setValue",value:function(e){var t=this;if(this.initialised===!0){var i=[].concat(o(e)),n=this.passedElement.type,s=function(e){var i=(0,p.getType)(e);if("Object"===i){if(!e.value)return;"text"!==n?t._addChoice(!0,!1,e.value,e.label,-1):t._addItem(e.value,e.label,e.id)}else"String"===i&&("text"!==n?t._addChoice(!0,!1,e,e,-1):t._addItem(e))};i.length>1?i.forEach(function(e){s(e)}):s(i[0])}return this}},{key:"setValueByChoice",value:function(e){var t=this;if("text"!==this.passedElement.type){var i=this.store.getChoices(),n=(0,p.isType)("Array",e)?e:[e];n.forEach(function(e){var n=i.find(function(t){return t.value===e});n?n.selected?console.warn("Attempting to select choice already selected"):t._addItem(n.value,n.label,n.id,n.groupId):console.warn("Attempting to select choice that does not exist")})}return this}},{key:"setChoices",value:function(e,t,i){var n=this,s=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(this.initialised===!0&&this.isSelectElement){if(!(0,p.isType)("Array",e)||!t)return;s&&this._clearChoices(),e&&e.length&&(this.containerOuter.classList.remove(this.config.classNames.loadingState),e.forEach(function(e,s){var o=!!e.selected&&e.selected,r=!!e.disabled&&e.disabled;e.choices?n._addGroup(e,e.id||null,t,i):n._addChoice(o,r,e[t],e[i])}))}return this}},{key:"clearStore",value:function(){return this.store.dispatch((0,d.clearAll)()),this}},{key:"clearInput",value:function(){return this.input.value&&(this.input.value=""),"select-one"!==this.passedElement.type&&this._setInputWidth(),"text"!==this.passedElement.type&&this.config.search&&(this.isSearching=!1,this.store.dispatch((0,d.activateChoices)(!0))),this}},{key:"enable",value:function(){this.passedElement.disabled=!1;var e=this.containerOuter.classList.contains(this.config.classNames.disabledState);return this.initialised&&e&&(this._addEventListeners(),this.passedElement.removeAttribute("disabled"),this.input.removeAttribute("disabled"),this.containerOuter.classList.remove(this.config.classNames.disabledState),this.containerOuter.removeAttribute("aria-disabled")),this}},{key:"disable",value:function(){this.passedElement.disabled=!0;var e=!this.containerOuter.classList.contains(this.config.classNames.disabledState);return this.initialised&&e&&(this._removeEventListeners(),this.passedElement.setAttribute("disabled",""),this.input.setAttribute("disabled",""),this.containerOuter.classList.add(this.config.classNames.disabledState),this.containerOuter.setAttribute("aria-disabled","true")),this}},{key:"ajax",value:function(e){return this.initialised===!0&&this.isSelectElement&&(this._handleLoadingState(!0),e(this._ajaxCallback())),this}},{key:"_triggerChange",value:function(e){e&&(0,p.triggerEvent)(this.passedElement,"change",{value:e})}},{key:"_handleButtonAction",value:function(e,t){if(e&&t&&this.config.removeItems&&this.config.removeItemButton){var i=t.parentNode.getAttribute("data-id"),n=e.find(function(e){return e.id===parseInt(i,10)});if(this._removeItem(n),this._triggerChange(n.value),"select-one"===this.passedElement.type){var s=!!this.config.placeholder&&(this.config.placeholderValue||this.passedElement.getAttribute("placeholder"));if(s){var o=this._getTemplate("placeholder",s);this.itemList.appendChild(o)}}}}},{key:"_handleItemAction",value:function(e,t){var i=this,n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(e&&t&&this.config.removeItems&&"select-one"!==this.passedElement.type){var s=t.getAttribute("data-id");e.forEach(function(e){e.id!==parseInt(s,10)||e.highlighted?n||e.highlighted&&i.unhighlightItem(e):i.highlightItem(e)}),document.activeElement!==this.input&&this.input.focus()}}},{key:"_handleChoiceAction",value:function(e,t){if(e&&t){var i=t.getAttribute("data-id"),n=this.store.getChoiceById(i),s=this.dropdown.classList.contains(this.config.classNames.activeState);if(n&&!n.selected&&!n.disabled){var o=this._canAddItem(e,n.value);o.response&&(this._addItem(n.value,n.label,n.id,n.groupId),this._triggerChange(n.value))}this.clearInput(this.passedElement),s&&"select-one"===this.passedElement.type&&(this.hideDropdown(),this.containerOuter.focus())}}},{key:"_handleBackspace",value:function(e){if(this.config.removeItems&&e){var t=e[e.length-1],i=e.some(function(e){return e.highlighted===!0});this.config.editItems&&!i&&t?(this.input.value=t.value,this._setInputWidth(),this._removeItem(t),this._triggerChange(t.value)):(i||this.highlightItem(t,!1),this.removeHighlightedItems(!0))}}},{key:"_canAddItem",value:function(e,t){var i=!0,n=(0,p.isType)("Function",this.config.addItemText)?this.config.addItemText(t):this.config.addItemText;if("select-multiple"!==this.passedElement.type&&"text"!==this.passedElement.type||this.config.maxItemCount>0&&this.config.maxItemCount<=this.itemList.children.length&&(i=!1,n=(0,p.isType)("Function",this.config.maxItemText)?this.config.maxItemText(this.config.maxItemCount):this.config.maxItemText),"text"===this.passedElement.type&&this.config.addItems){var s=!e.some(function(e){return e.value===t.trim()});this.config.regexFilter&&(i=this._regexFilter(t)),this.config.duplicateItems!==!1||s||(i=!1,n=(0,p.isType)("Function",this.config.uniqueItemText)?this.config.uniqueItemText(t):this.config.uniqueItemText)}return{response:i,notice:n}}},{key:"_handleLoadingState",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=this.itemList.querySelector("."+this.config.classNames.placeholder);if(e)this.containerOuter.classList.add(this.config.classNames.loadingState),this.containerOuter.setAttribute("aria-busy","true"),"select-one"===this.passedElement.type?t?t.innerHTML=this.config.loadingText:(t=this._getTemplate("placeholder",this.config.loadingText),this.itemList.appendChild(t)):this.input.placeholder=this.config.loadingText;else{this.containerOuter.classList.remove(this.config.classNames.loadingState);var i=!!this.config.placeholder&&(this.config.placeholderValue||this.passedElement.getAttribute("placeholder"));"select-one"===this.passedElement.type?t.innerHTML=i||"":this.input.placeholder=i||""}}},{key:"_ajaxCallback",value:function(){var e=this;return function(t,i,n){if(t&&i){var s=(0,p.isType)("Object",t)?[t]:t;s&&(0,p.isType)("Array",s)&&s.length?(e._handleLoadingState(!1),s.forEach(function(t,s){var o=!!t.selected&&t.selected,r=!!t.disabled&&t.disabled;t.choices?e._addGroup(t,t.id||null,i,n):e._addChoice(o,r,t[i],t[n])})):e._handleLoadingState(!1),e.containerOuter.removeAttribute("aria-busy")}}}},{key:"_searchChoices",value:function(e){var t=(0,p.isType)("String",e)?e.trim():e,i=(0,p.isType)("String",this.currentValue)?this.currentValue.trim():this.currentValue;if(t.length>=1&&t!==i+" "){var n=this.store.getChoicesFilteredBySelectable(),s=t,o=(0,p.isType)("Array",this.config.sortFields)?this.config.sortFields:[this.config.sortFields],r=Object.assign(this.config.fuseOptions,{keys:o}),a=new l.default(n,r),c=a.search(s);this.currentValue=t,this.highlightPosition=0,this.isSearching=!0,this.store.dispatch((0,d.filterChoices)(c))}}},{key:"_handleSearch",value:function(e){if(e){var t=this.store.getChoices(),i=t.some(function(e){return e.active!==!0});this.input===document.activeElement&&(e&&e.length>this.config.searchFloor?(this._searchChoices(e),(0,p.triggerEvent)(this.passedElement,"search",{value:e})):i&&(this.isSearching=!1,this.store.dispatch((0,d.activateChoices)(!0))))}}},{key:"_addEventListeners",value:function(){document.addEventListener("keyup",this._onKeyUp),document.addEventListener("keydown",this._onKeyDown),document.addEventListener("click",this._onClick),document.addEventListener("touchmove",this._onTouchMove),document.addEventListener("touchend",this._onTouchEnd),document.addEventListener("mousedown",this._onMouseDown),document.addEventListener("mouseover",this._onMouseOver),this.passedElement.type&&"select-one"===this.passedElement.type&&(this.containerOuter.addEventListener("focus",this._onFocus),this.containerOuter.addEventListener("blur",this._onBlur)),this.input.addEventListener("input",this._onInput),this.input.addEventListener("paste",this._onPaste),this.input.addEventListener("focus",this._onFocus),this.input.addEventListener("blur",this._onBlur)}},{key:"_removeEventListeners",value:function(){document.removeEventListener("keyup",this._onKeyUp),document.removeEventListener("keydown",this._onKeyDown),document.removeEventListener("click",this._onClick),document.removeEventListener("touchmove",this._onTouchMove),document.removeEventListener("touchend",this._onTouchEnd),document.removeEventListener("mousedown",this._onMouseDown),document.removeEventListener("mouseover",this._onMouseOver),this.passedElement.type&&"select-one"===this.passedElement.type&&(this.containerOuter.removeEventListener("focus",this._onFocus),this.containerOuter.removeEventListener("blur",this._onBlur)),this.input.removeEventListener("input",this._onInput),this.input.removeEventListener("paste",this._onPaste),this.input.removeEventListener("focus",this._onFocus),this.input.removeEventListener("blur",this._onBlur)}},{key:"_setInputWidth",value:function(){if(this.config.placeholder&&(this.config.placeholderValue||this.passedElement.getAttribute("placeholder"))){var e=!!this.config.placeholder&&(this.config.placeholderValue||this.passedElement.getAttribute("placeholder"));this.input.value&&this.input.value.length>=e.length/1.25&&(this.input.style.width=(0,p.getWidthOfInput)(this.input))}else this.input.style.width=(0,p.getWidthOfInput)(this.input)}},{key:"_onKeyDown",value:function(e){var t,i=this;if(e.target===this.input||this.containerOuter.contains(e.target)){var n=e.target,o=this.passedElement.type,r=this.store.getItemsFilteredByActive(),a=this.input===document.activeElement,c=this.dropdown.classList.contains(this.config.classNames.activeState),l=this.itemList&&this.itemList.children,h=String.fromCharCode(e.keyCode),u=46,d=8,f=13,v=65,m=27,g=38,y=40,b=33,E=34,_=e.ctrlKey||e.metaKey;"text"!==o&&/[a-zA-Z0-9-_ ]/.test(h)&&!c&&this.showDropdown(!0),this.canSearch=this.config.search;var I=function(){_&&l&&(i.canSearch=!1,i.config.removeItems&&!i.input.value&&i.input===document.activeElement&&i.highlightAll(i.itemList.children))},w=function(){if("text"===o&&n.value){var t=i.input.value,s=i._canAddItem(r,t);s.response&&(c&&i.hideDropdown(),i._addItem(t),i._triggerChange(t),i.clearInput(i.passedElement))}if(n.hasAttribute("data-button")&&(i._handleButtonAction(r,n),e.preventDefault()),c){e.preventDefault();var a=i.dropdown.querySelector("."+i.config.classNames.highlightedState);a&&i._handleChoiceAction(r,a)}else"select-one"===o&&(c||(i.showDropdown(!0),e.preventDefault()))},S=function(){c&&i.toggleDropdown()},T=function(){if(c||"select-one"===o){c||i.showDropdown(!0),i.canSearch=!1;var t=e.keyCode===y||e.keyCode===E?1:-1,n=e.metaKey||e.keyCode===E||e.keyCode===b,s=void 0;if(n)s=t>0?Array.from(i.dropdown.querySelectorAll("[data-choice-selectable]")).pop():i.dropdown.querySelector("[data-choice-selectable]");else{var r=i.dropdown.querySelector("."+i.config.classNames.highlightedState);s=r?(0,p.getAdjacentEl)(r,"[data-choice-selectable]",t):i.dropdown.querySelector("[data-choice-selectable]")}s&&((0,p.isScrolledIntoView)(s,i.choiceList,t)||i._scrollToChoice(s,t),i._highlightChoice(s)),e.preventDefault()}},A=function(){a&&!e.target.value&&"select-one"!==o&&(i._handleBackspace(r),e.preventDefault())},C=(t={},s(t,v,I),s(t,f,w),s(t,m,S),s(t,g,T),s(t,b,T),s(t,y,T),s(t,E,T),s(t,d,A),s(t,u,A),t);C[e.keyCode]&&C[e.keyCode]()}}},{key:"_onKeyUp",value:function(e){if(e.target===this.input)if(this.isTextElement){var t=this.dropdown.classList.contains(this.config.classNames.activeState),i=this.input.value;if(i){var n=this.store.getItemsFilteredByActive(),s=this._canAddItem(n,i);if(s.notice){var o=this._getTemplate("notice",s.notice);this.dropdown.innerHTML=o.outerHTML}s.response===!0?t||this.showDropdown():!s.notice&&t&&this.hideDropdown()}else t&&this.hideDropdown()}else{var r=46,a=8;e.keyCode!==r&&e.keyCode!==a||e.target.value?this.canSearch&&this._handleSearch(this.input.value):"text"!==this.passedElement.type&&this.isSearching&&(this.isSearching=!1,this.store.dispatch((0,d.activateChoices)(!0)))}}},{key:"_onInput",value:function(){"select-one"!==this.passedElement.type&&this._setInputWidth()}},{key:"_onTouchMove",value:function(){this.wasTap===!0&&(this.wasTap=!1)}},{key:"_onTouchEnd",value:function(e){var t=e.target||e.touches[0].target,i=this.dropdown.classList.contains(this.config.classNames.activeState);this.wasTap===!0&&this.containerOuter.contains(t)&&(t!==this.containerOuter&&t!==this.containerInner||"select-one"===this.passedElement.type||(this.isTextElement?document.activeElement!==this.input&&this.input.focus():i||this.showDropdown(!0)),e.stopPropagation()),this.wasTap=!0}},{key:"_onMouseDown",value:function(e){var t=e.target;if(this.containerOuter.contains(t)&&t!==this.input){var i=this.store.getItemsFilteredByActive(),n=e.shiftKey,s=void 0;(s=(0,p.findAncestorByAttr)(t,"data-item"))?this._handleItemAction(i,s,n):(s=(0,p.findAncestorByAttr)(t,"data-choice"))&&this._handleChoiceAction(i,s),e.preventDefault()}}},{key:"_onClick",value:function(e){var t=e.target,i=this.dropdown.classList.contains(this.config.classNames.activeState),n=this.store.getItemsFilteredByActive();if(this.containerOuter.contains(t))t.hasAttribute("data-button")&&this._handleButtonAction(n,t),i?"select-one"!==this.passedElement.type||t===this.input||this.dropdown.contains(t)||this.hideDropdown(!0):this.isTextElement?document.activeElement!==this.input&&this.input.focus():this.canSearch?this.showDropdown(!0):(this.showDropdown(),this.containerOuter.focus());else{var s=n.some(function(e){return e.highlighted===!0});s&&this.unhighlightAll(),this.containerOuter.classList.remove(this.config.classNames.focusState),i&&this.hideDropdown()}}},{key:"_onMouseOver",value:function(e){(e.target===this.dropdown||this.dropdown.contains(e.target))&&e.target.hasAttribute("data-choice")&&this._highlightChoice(e.target)}},{key:"_onPaste",value:function(e){e.target!==this.input||this.config.paste||e.preventDefault()}},{key:"_onFocus",value:function(e){var t=this,i=e.target;if(this.containerOuter.contains(i)){var n=this.dropdown.classList.contains(this.config.classNames.activeState),s={text:function(){i===t.input&&t.containerOuter.classList.add(t.config.classNames.focusState)},"select-one":function(){t.containerOuter.classList.add(t.config.classNames.focusState),i===t.input&&(n||t.showDropdown())},"select-multiple":function(){i===t.input&&(t.containerOuter.classList.add(t.config.classNames.focusState),n||t.showDropdown(!0))}};s[this.passedElement.type]()}}},{key:"_onBlur",value:function(e){var t=this,i=e.target;if(this.containerOuter.contains(i)){var n=this.store.getItemsFilteredByActive(),s=this.dropdown.classList.contains(this.config.classNames.activeState),o=n.some(function(e){return e.highlighted===!0}),r={text:function(){i===t.input&&(t.containerOuter.classList.remove(t.config.classNames.focusState),o&&t.unhighlightAll(),s&&t.hideDropdown())},"select-one":function(){t.containerOuter.classList.remove(t.config.classNames.focusState),i===t.containerOuter&&s&&!t.canSearch&&t.hideDropdown(),i===t.input&&s&&t.hideDropdown()},"select-multiple":function(){i===t.input&&(t.containerOuter.classList.remove(t.config.classNames.focusState),s&&t.hideDropdown(),o&&t.unhighlightAll())}};r[this.passedElement.type]()}}},{key:"_regexFilter",value:function(e){if(e){var t=this.config.regexFilter,i=new RegExp(t.source,"i");return i.test(e)}}},{key:"_scrollToChoice",value:function(e,t){var i=this;if(e){var n=this.choiceList.offsetHeight,s=e.offsetHeight,o=e.offsetTop+s,r=this.choiceList.scrollTop+n,a=t>0?this.choiceList.scrollTop+o-r:e.offsetTop,c=function e(){var n=4,s=i.choiceList.scrollTop,o=!1,r=void 0,c=void 0;t>0?(r=(a-s)/n,c=r>1?r:1,i.choiceList.scrollTop=s+c,s1?r:1,i.choiceList.scrollTop=s-c,s>a&&(o=!0)),o&&requestAnimationFrame(function(i){e(i,a,t)})};requestAnimationFrame(function(e){c(e,a,t)})}}},{key:"_highlightChoice",value:function(e){var t=this,i=Array.from(this.dropdown.querySelectorAll("[data-choice-selectable]"));if(i&&i.length){var n=Array.from(this.dropdown.querySelectorAll("."+this.config.classNames.highlightedState));if(n.forEach(function(e){e.classList.remove(t.config.classNames.highlightedState),e.setAttribute("aria-selected","false")}),e)e.classList.add(this.config.classNames.highlightedState),this.highlightPosition=i.indexOf(e);else{var s=void 0;s=i.length>this.highlightPosition?i[this.highlightPosition]:i[i.length-1],s||(s=i[0]),s.classList.add(this.config.classNames.highlightedState),s.setAttribute("aria-selected","true")}}}},{key:"_addItem",value:function(e,t){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:-1,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,s=(0,p.isType)("String",e)?e.trim():e,o=this.store.getItems(),r=t||s,a=parseInt(i,10)||-1,c=n>=0?this.store.getGroupById(n):null,l=o?o.length+1:1;return this.config.prependValue&&(s=this.config.prependValue+s.toString()),this.config.appendValue&&(s+=this.config.appendValue.toString()),this.store.dispatch((0,d.addItem)(s,r,l,a,n)),"select-one"===this.passedElement.type&&this.removeActiveItems(l),c&&c.value?(0,p.triggerEvent)(this.passedElement,"addItem",{id:l,value:s,label:r,groupValue:c.value}):(0,p.triggerEvent)(this.passedElement,"addItem",{id:l,value:s,label:r}),this}},{key:"_removeItem",value:function(e){if(!e||!(0,p.isType)("Object",e))return void console.error("removeItem: No item object was passed to be removed");var t=e.id,i=e.value,n=e.label,s=e.choiceId,o=e.groupId,r=o>=0?this.store.getGroupById(o):null;return this.store.dispatch((0,d.removeItem)(t,s)),r&&r.value?(0,p.triggerEvent)(this.passedElement,"removeItem",{id:t,value:i,label:n,groupValue:r.value}):(0,p.triggerEvent)(this.passedElement,"removeItem",{id:t,value:i,label:n}),this}},{key:"_addChoice",value:function(e,t,i,n){var s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;if("undefined"!=typeof i&&null!==i){var o=this.store.getChoices(),r=n||i,a=o?o.length+1:1;this.store.dispatch((0,d.addChoice)(i,r,a,s,t)),e&&this._addItem(i,r,a)}}},{key:"_clearChoices",value:function(){this.store.dispatch((0,d.clearChoices)())}},{key:"_addGroup",value:function(e,t){var i=this,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"value",s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"label",o=(0,p.isType)("Object",e)?e.choices:Array.from(e.getElementsByTagName("OPTION")),r=t?t:Math.floor((new Date).valueOf()*Math.random()),a=!!e.disabled&&e.disabled;o?(this.store.dispatch((0,d.addGroup)(e.label,r,!0,a)),o.forEach(function(e){var t=e.disabled||e.parentNode&&e.parentNode.disabled||!1,o=!!e.selected&&e.selected,a=void 0;a=(0,p.isType)("Object",e)?e[s]||e[n]:e.innerHTML,i._addChoice(o,t,e[n],a,r)})):this.store.dispatch((0,d.addGroup)(e.label,e.id,!1,e.disabled))}},{key:"_getTemplate",value:function(e){if(e){for(var t=this.config.templates,i=arguments.length,n=Array(i>1?i-1:0),s=1;s