{"version":3,"sources":["Behavior.js","ElementMissingError.js","Focus.js","Hooks.js","Present.js","registry.js","throttle_single.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DC7OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KCjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBCrGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BCrJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BCxIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"EVABehaviors.js","sourcesContent":["window.EVASuit = window.EVASuit || {};\r\nwindow.EVASuit.Behaviors = window.EVASuit.Behaviors || {};\r\n\r\nwindow.EVASuit.Behaviors.Behavior = function(Element, Document, Behaviors) {\r\n \"use strict\";\r\n\r\n /**\r\n * Determines if an object claims to be a DOM element.\r\n * \r\n * This function is deliberately compatible with DOM elements that are\r\n * foreign to the current window. False positives are possible if classes\r\n * exist that have names like Element or HTMLDocument. Such a situation is\r\n * unlikely.\r\n * \r\n * @param {Object} maybe_elem An object that may or may not be a DOM\r\n * element\r\n * \r\n * @returns True if the element is a DOM element, regardless of the iframe\r\n * it was constructed in. False for all other objects.\r\n */\r\n function isDomElement(maybe_elem) {\r\n var proto = maybe_elem.__proto__;\r\n\r\n while (proto) {\r\n var typeName = Object.prototype.toString.call(proto);\r\n\r\n if (typeName === \"[object Element]\" || typeName === \"[object HTMLDocument]\") {\r\n return true;\r\n }\r\n\r\n proto = proto.__proto__;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Unique name for our list of located instances.\r\n */\r\n const LOCATED_INSTANCES = Symbol(\"locatedInstances\");\r\n\r\n /**\r\n * A custom JavaScript behavior that can be repeatedly located onto a set\r\n * of elements named by a CSS selector.\r\n */\r\n class Behavior {\r\n /**\r\n * Find markup that this Behavior locates onto within a given context\r\n * and instantiate the class on that markup.\r\n * \r\n * The current class's QUERY parameter will be used as the CSS selector\r\n * to find markup with. If the given context itself also matches the\r\n * selector, it \r\n * \r\n * @param {jQuery|Element|null} context The context element to find\r\n * markup in. If null, the current document is checked.\r\n * @param {...any} _ Any arguments to pass on down into the context.\r\n * \r\n * Must either be shaped like a jQuery object or a DOM element.\r\n */\r\n static find_markup(context=null) {\r\n var results = [], i, splitArgs = [], Class = this, nodelist;\r\n\r\n function processElem(index, elem) {\r\n var locateArgs = [elem].concat(splitArgs);\r\n\r\n results.push(Class.locate.apply(Class, locateArgs));\r\n }\r\n\r\n for (i = 1; i < arguments.length; i += 1) {\r\n splitArgs.push(arguments[i]);\r\n }\r\n\r\n if (context === null) {\r\n context = document;\r\n }\r\n\r\n if (isDomElement(context)) { //Element-like context\r\n nodelist = Array.prototype.slice.call(context.querySelectorAll(Class.QUERY));\r\n nodelist.forEach(element => {\r\n processElem(undefined, element);\r\n });\r\n\r\n //Documents lack a matches method\r\n if (context.matches && context.matches(Class.QUERY)) {\r\n processElem(undefined, context);\r\n }\r\n } else if (context.filter && context.find) { //jQuery-like context\r\n context.filter(Class.QUERY).each(processElem);\r\n context.find(Class.QUERY).each(processElem);\r\n } else {\r\n throw new Behaviors.ElementMissingError(\"Behavior.find_markup called without valid context object\");\r\n }\r\n }\r\n \r\n /**\r\n * Instantiate this Behavior onto this element.\r\n * \r\n * Behaviors are designed to locate onto a given element once and only\r\n * once. If it has already been instantiated, then that instance will\r\n * be returned again.\r\n * \r\n * @param {jQuery|Element} elem The element to locate on.\r\n * \r\n * May either be a DOM element or jQuery.\r\n * \r\n * @param {...any} objectArgs Any other arguments to pass to the\r\n * behavior's constructor.\r\n * \r\n * @returns An instance of the Behavior on this element.\r\n * \r\n * @throws ElementMissingError if the element is neither jQuery nor a\r\n * DOM element, or if it's jQuery but has a length of 0.\r\n */\r\n static locate(elem, ...objectArgs) {\r\n var Class = this, instance;\r\n\r\n if (isDomElement(elem)) { //Element-like element\r\n if (Class[LOCATED_INSTANCES] === undefined) {\r\n Class[LOCATED_INSTANCES] = new WeakMap();\r\n }\r\n\r\n if (!Class[LOCATED_INSTANCES].has(elem)) {\r\n Class[LOCATED_INSTANCES].set(elem, new Class(elem, ...objectArgs));\r\n }\r\n\r\n return Class[LOCATED_INSTANCES].get(elem);\r\n } else if (elem !== null && elem.length !== undefined && elem.length > 0) { //jQuery-like element\r\n return self.locate(elem[0], ...objectArgs);\r\n } else {\r\n throw new Behaviors.ElementMissingError(\"Behavior.locate called without valid element\");\r\n }\r\n }\r\n\r\n /**\r\n * Indicates to the class that content was added to the page.\r\n * \r\n * Subclasses that override this function MUST call find_markup on the\r\n * full context eventually. You may use this function to delay Behavior\r\n * processing until a later time, but your Behavior must still be able\r\n * to handle code locating it before that time.\r\n * \r\n * @param {jQuery|Element} context The content that was added to the DOM.\r\n */\r\n static content_ready(context) {\r\n this.find_markup(context);\r\n }\r\n\r\n /**\r\n * Indicates to the class that content is about to be removed from the\r\n * page.\r\n * \r\n * Most Behaviors do not need to worry about content removal; garbage\r\n * collection will detach any event handlers and reclaim your object as\r\n * needed. However, things such as animation timers or other global\r\n * references to the object will keep it live and potentially leak\r\n * memory or keep rendering things off-screen. Content removal\r\n * notifications allow tearing down and disposing of such semantic\r\n * garbage.\r\n * \r\n * Subclasses that need to support tear down upon removal should\r\n * override the instance method `deinitialize` instead.\r\n * \r\n * @param {jQuery|Element} context The content that was removed from\r\n * the DOM.\r\n */\r\n static content_removal(context) {\r\n var Class = this, nodelist;\r\n\r\n function deinitialize_elem(elem) {\r\n var instance = Class.locate(elem);\r\n\r\n instance.deinitialize();\r\n }\r\n\r\n if (isDomElement(context)) { //DOM contexts\r\n nodelist = Array.prototype.slice.call(context.querySelectorAll(Class.QUERY));\r\n nodelist.forEach(deinitialize_elem);\r\n\r\n if (context.matches(Class.QUERY)) {\r\n deinitialize_elem(context);\r\n }\r\n } else if (context.filter && context.find) { //jQuery-like context\r\n context.filter(Class.QUERY).each((index, elem) => deinitialize_elem(elem));\r\n context.find(Class.QUERY).each((index, elem) => deinitialize_elem(elem));\r\n } else {\r\n throw new Behaviors.ElementMissingError(\"Behavior.content_removal called without valid context object\");\r\n }\r\n }\r\n\r\n /**\r\n * Construct a new instance of this Behavior.\r\n * \r\n * The given element will be stored in this.elem. If jQuery is loaded,\r\n * a wrapped jQuery object with the element will be stored in\r\n * this.$elem.\r\n * \r\n * @param {Element} elem The DOM element being located upon.\r\n */\r\n constructor(elem) {\r\n this.elem = elem;\r\n\r\n if (window.jQuery) {\r\n this.$elem = window.jQuery(elem);\r\n }\r\n }\r\n\r\n /**\r\n * Tear down any animation timers or other global references to this\r\n * Behavior.\r\n */\r\n deinitialize() {\r\n\r\n }\r\n\r\n /**\r\n * Called when the Behavior is presented to the user.\r\n * \r\n * Should not be called to programmatically present a Behavior. To do\r\n * so, call Behaviors.present.\r\n */\r\n presented() {\r\n\r\n }\r\n\r\n /**\r\n * Called when the Behavior is dismissed.\r\n * \r\n * Should not be called to programmatically dismiss a Behavior. To do\r\n * so, call Behaviors.dismiss.\r\n */\r\n dismissed() {\r\n\r\n }\r\n }\r\n\r\n return Behavior;\r\n}(window.Element, window.Document, window.EVASuit.Behaviors);","window.EVASuit = window.EVASuit || {};\r\nwindow.EVASuit.Behaviors = window.EVASuit.Behaviors || {};\r\n\r\nwindow.EVASuit.Behaviors.ElementMissingError = function() {\r\n \"use strict\";\r\n\r\n /**\r\n * Error that indicates that a required element is invalid or missing.\r\n */\r\n class ElementMissingError extends Error {\r\n constructor(message) {\r\n super(message);\r\n this.name = \"ElementMissingError\";\r\n }\r\n }\r\n\r\n return ElementMissingError;\r\n}();","window.EVASuit = window.EVASuit || {};\r\nwindow.EVASuit.Behaviors = window.EVASuit.Behaviors || {};\r\n\r\nwindow.EVASuit.Behaviors.Focus = (function() {\r\n \"use strict\";\r\n\r\n var module = {}, element_states = new WeakMap();\r\n\r\n /**\r\n * Make an entire element and its children unfocusable.\r\n * \r\n * Tabindexes will be set to -1 on all elements. Prior existing indexes\r\n * will be retained and restored when the element is made focusable again.\r\n * \r\n * @param {Element} elem The DOM element to exclude from focus.\r\n */\r\n function make_element_unfocusable(elem) {\r\n var i;\r\n\r\n if (elem.attributes.tabIndex !== undefined && (!element_states.has(elem) || elem.tabIndex !== -1)) {\r\n element_states.set(elem, elem.tabIndex);\r\n }\r\n\r\n elem.tabIndex = -1;\r\n\r\n for (i = 0; i < elem.children.length; i += 1) {\r\n if (elem.children[i]) {\r\n make_element_unfocusable(elem.children[i]);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Make an entire element and its children focusable.\r\n * \r\n * This presumes that the element was made unfocusable prior. If it hasn't,\r\n * no change will be made to the element.\r\n * \r\n * @param {Element} elem The DOM element to include back into focus.\r\n */\r\n function make_element_focusable(elem) {\r\n var i;\r\n\r\n if (element_states.has(elem)) {\r\n elem.tabIndex = element_states.get(elem);\r\n } else {\r\n delete elem.tabIndex;\r\n delete elem.removeAttribute(\"tabIndex\");\r\n }\r\n\r\n for (i = 0; i < elem.children.length; i += 1) {\r\n if (elem.children[i]) {\r\n make_element_focusable(elem.children[i]);\r\n }\r\n }\r\n }\r\n\r\n module.make_element_focusable = make_element_focusable;\r\n module.make_element_unfocusable = make_element_unfocusable;\r\n\r\n return module;\r\n}());","window.EVASuit = window.EVASuit || {};\r\nwindow.EVASuit.Behaviors = window.EVASuit.Behaviors || {};\r\n\r\n(window.EVASuit.Behaviors.Hooks = function(Behaviors) {\r\n \"use strict\";\r\n\r\n /**\r\n * Manages global hooks for Behaviors.\r\n * \r\n * A global hook is not tied to any specific instance of a Behavior; unlike\r\n * events. You add hooks to your behavior by adding one as a property of\r\n * your class, defining it's hook types, and triggering them in your\r\n * behavior's methods. Third-party code can then hook into your class by\r\n * attaching to the class's global hooks mechanism.\r\n * \r\n * Hooks are only to be used in cases where you don't particularly care\r\n * about *which* behavior you are talking to, only that you want to\r\n * intercept all of them. They are thus distinct from events, which are\r\n * fired on a specific behavior and can be used to link different, specific\r\n * behaviors.\r\n */\r\n class Hooks {\r\n constructor() {\r\n this.hooks = {};\r\n }\r\n\r\n /**\r\n * Define a hook name.\r\n * \r\n * @param {string} hook_name The name of the hook to attach to.\r\n */\r\n define_hook_type(hook_name) {\r\n if (!this.hooks.hasOwnProperty(hook_name)) {\r\n this.hooks[hook_name] = [];\r\n }\r\n }\r\n \r\n /**\r\n * An attached hook callback. Can optionally filter the hook's inherent\r\n * value.\r\n * \r\n * @callback AttachedHook\r\n * @param {*} value The inherent hook value, which depends on which\r\n * hook is being attached.\r\n * \r\n * May have already been filtered by a previously installed hook\r\n * function.\r\n * \r\n * @param {...*} context Any further context values.\r\n * \r\n * These are always the hook's inherent values and cannot be filtered\r\n * by user code. By convention, the first context value is the hooked\r\n * Behavior instance.\r\n * \r\n * @returns The filtered value.\r\n * \r\n * Returning `undefined` (either explicitly, or by not having a\r\n * `return` statement in your function) indicates that your hook does\r\n * not wish to change the value.\r\n */\r\n \r\n /**\r\n * Attach to a particular named hook.\r\n * \r\n * @param {string} hook_name The name of the hook to attach to.\r\n * @param {AttachedHook} impl The instance to be called at hook time.\r\n * @throws Error if the `hook_name` is invalid.\r\n */\r\n attach(hook_name, impl) {\r\n this.hooks[hook_name].push(impl);\r\n }\r\n\r\n /**\r\n * Trigger a given named hook.\r\n * \r\n * @param {string} hook_name The hook to trigger.\r\n * @param {*} value The hook value, which hook functions will be\r\n * expected to modify.\r\n * @param {Behaviors.Behavior} instance The current behavior being\r\n * hooked.\r\n * @param {*} * \r\n * @returns The hook value, optionally modified by any attached hooks.\r\n */\r\n trigger(hook_name, value, instance) {\r\n var i, new_value, context = [value, instance];\r\n for (i = 3; i < arguments.length; i += 1) {\r\n context.push(arguments[i]);\r\n }\r\n \r\n for (i = 0; i < this.hooks[hook_name].length; i += 1) {\r\n new_value = this.hooks[hook_name][i].apply(this, context);\r\n if (new_value !== undefined) {\r\n context[0] = new_value;\r\n }\r\n }\r\n \r\n return context[0];\r\n }\r\n }\r\n\r\n return Hooks;\r\n}(window.Behaviors));","window.EVASuit = window.EVASuit || {};\r\nwindow.EVASuit.Behaviors = window.EVASuit.Behaviors || {};\r\n\r\nwindow.EVASuit.Behaviors = (function(module) {\r\n \"use strict\";\r\n var presentation_stack = [], stack_is_locked = false;\r\n\r\n /**\r\n * Error that indicates that elements were presented or dismissed in ways\r\n * that are invalid.\r\n */\r\n class PresentationLogicError extends Error {\r\n constructor(message) {\r\n super(message);\r\n this.name = \"PresentationLogicError\";\r\n }\r\n }\r\n\r\n /**\r\n * Present a given item.\r\n * \r\n * Presentation is hierarchial and follows the DOM tree. We maintain a\r\n * stack of currently-presented elements. Presenting a new element\r\n * dismisses all prior elements that are *not* parents of the current one.\r\n * \r\n * Clicking, focusing, tabbing, or ESCing out of the presented element\r\n * automatically dismisses it.\r\n * \r\n * To respond to presentation and dismissal, implement the presented() and\r\n * dismissed() methods of your Behavior.\r\n * \r\n * @param {Behaviors.Behavior} item A located behavior to present to\r\n * the user.\r\n */\r\n function present(item) {\r\n var stack_cleaned = false, i;\r\n \r\n if (stack_is_locked) {\r\n throw new PresentationLogicError(\"Cannot present items recursively.\");\r\n }\r\n\r\n stack_is_locked = true;\r\n\r\n // Dismiss presented elements off the stack until we catch one that is\r\n // a parent of the item to be presented.\r\n while (presentation_stack.length > 0 && !stack_cleaned) {\r\n var iter = item.elem;\r\n\r\n while (iter !== undefined) {\r\n if (presentation_stack[presentation_stack.length - 1] === iter) {\r\n stack_cleaned = true;\r\n break;\r\n }\r\n\r\n iter = iter.parent;\r\n }\r\n\r\n try {\r\n presentation_stack.pop().dismissed();\r\n } catch (e) {\r\n stack_is_locked = false;\r\n throw e;\r\n }\r\n }\r\n \r\n presentation_stack.push(item);\r\n \r\n try {\r\n item.presented();\r\n } finally {\r\n stack_is_locked = false;\r\n }\r\n }\r\n\r\n /**\r\n * Dismiss a given item.\r\n * \r\n * All presented children of this item will also be dismissed.\r\n * \r\n * @param {Behaviors.Behavior} [item] A located behavior to dismiss.\r\n * \r\n * If not provided, the last presented item on the stack will be dismissed.\r\n */\r\n function dismiss(item) {\r\n var stack_index, i = 0;\r\n \r\n if (stack_is_locked) {\r\n throw new PresentationLogicError(\"Cannot dismiss items recursively.\");\r\n }\r\n\r\n if (presentation_stack.length === 0) {\r\n throw new PresentationLogicError(\"Cannot dismiss without presenting first.\");\r\n }\r\n\r\n if (item === undefined) {\r\n stack_index = presentation_stack.length - 1;\r\n item = presentation_stack[stack_index];\r\n } else {\r\n stack_index = presentation_stack.indexOf(item);\r\n }\r\n\r\n if (stack_index === -1) {\r\n throw new PresentationLogicError(\"Cannot dismiss elements that were not presented.\");\r\n }\r\n \r\n while (presentation_stack.length > stack_index) {\r\n try {\r\n presentation_stack.pop().dismissed();\r\n } catch (e) {\r\n stack_is_locked = false;\r\n throw e;\r\n }\r\n }\r\n\r\n stack_is_locked = false;\r\n }\r\n\r\n /**\r\n * Present or dismiss an item based on if it is already presented.\r\n * \r\n * @param {Behaviors.Behavior} item A located behavior to toggle.\r\n */\r\n function toggle(item) {\r\n if (presentation_stack.indexOf(item) !== -1) {\r\n dismiss(item);\r\n } else {\r\n present(item);\r\n }\r\n }\r\n\r\n document.addEventListener(\"keyup\", function(evt) {\r\n if (evt.isComposing || evt.keyCode === 229) {\r\n // Ignore all composition events caused by IMEs (Input Method\r\n // Editors, used for Chinese, Japanese, Korean, etc) on desktop.\r\n return;\r\n }\r\n\r\n if (evt.key === \"Esc\" || evt.key === \"Escape\" || evt.keyCode === 27) {\r\n if (presentation_stack.length > 0) {\r\n dismiss();\r\n }\r\n }\r\n });\r\n\r\n module.present = present;\r\n module.dismiss = dismiss;\r\n module.toggle = toggle;\r\n\r\n return module;\r\n}(window.EVASuit.Behaviors));","window.EVASuit = window.EVASuit || {};\r\nwindow.EVASuit.Behaviors = window.EVASuit.Behaviors || {};\r\n\r\n(function(Behaviors) {\r\n \"use strict\";\r\n\r\n var behavior_registry = {},\r\n content_ready_listeners = [];\r\n\r\n /**\r\n * Add a class to the behavior registry.\r\n * \r\n * @param {Function} Class A behavior subclass.\r\n * @param {String} name The name of the class.\r\n * \r\n * Inferred to be the class's QUERY if not provided.\r\n */\r\n function register_behavior(Class, name) {\r\n if (name === undefined) {\r\n name = Class.QUERY;\r\n }\r\n\r\n if (behavior_registry[name] === Class) {\r\n console.warn(\"Attempted to register the same behavior twice to CSS selector \\\"\" + name + \"\\\"\");\r\n return;\r\n }\r\n\r\n if (behavior_registry[name] !== undefined) {\r\n console.error(\"Attempted to register a second behavior onto CSS selector \\\"\" +\r\n name + \"\\\". Only one behavior may be registered to a given CSS selector \" +\r\n \"at a given time. The offending classes are \" + Class.name +\r\n \" and \" + behavior_registry[name].name + \".\");\r\n \r\n return;\r\n }\r\n\r\n behavior_registry[name] = Class;\r\n }\r\n \r\n /**\r\n * Register a function that is called when content is added to the page.\r\n * \r\n * This function should only be called for tying external code to the\r\n * content listener system. For example, Drupal ships its own behaviors\r\n * system separate from this one; you can use registered listeners to\r\n * trigger it when Behaviors' registry is pinged.\r\n * \r\n * @param {Function} func The function to call when content is added.\r\n */\r\n function register_content_listener(func) {\r\n content_ready_listeners.push(func);\r\n }\r\n\r\n /**\r\n * Indicate that content has been added to the page.\r\n * \r\n * All registered Behaviors will locate any matching elements within the\r\n * provided content. Each Behavior will be isolated to a separate\r\n * setTimeout call to prevent breaking the whole page.\r\n * \r\n * If the page has any alternative frameworks that provide the same\r\n * facility of notifying JS that content has been added to the page, then\r\n * that facility should be altered to call this function, and this function\r\n * should be hotpatched to call that facility. See\r\n * `register_content_listener` for more information.\r\n * \r\n * @param {jQuery|Element} context The content that was added to the page.\r\n */\r\n function content_ready(context) {\r\n var k, i;\r\n \r\n function do_later(obj, func) {\r\n window.setTimeout(func.bind(obj, context), 0);\r\n }\r\n \r\n for (i = 0; i < content_ready_listeners.length; i += 1) {\r\n do_later(undefined, content_ready_listeners[i]);\r\n }\r\n\r\n for (k in behavior_registry) {\r\n if (behavior_registry.hasOwnProperty(k)) {\r\n do_later(behavior_registry[k], behavior_registry[k].content_ready);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Indicate that content is about to be removed from the page.\r\n * \r\n * This should be called *before* removing the actual elements. Registered\r\n * Behaviors will stop any animations timers and remove any global\r\n * references to about-to-be-removed content to prevent it from consuming\r\n * client resources.\r\n * \r\n * If the page has any alternative frameworks that provide the same\r\n * facility of notifying JS that content will be removed from the page,\r\n * then that facility should be altered to call this function, and this\r\n * function should be hotpatched to call that facility.\r\n * \r\n * @param {jQuery|Element} context The content that was added to the page.\r\n */\r\n function content_removal(context) {\r\n var k, i;\r\n \r\n function do_later(obj, func) {\r\n window.setTimeout(func.bind(obj, context), 0);\r\n }\r\n \r\n for (k in behavior_registry) {\r\n if (behavior_registry.hasOwnProperty(k)) {\r\n do_later(behavior_registry[k], behavior_registry[k].content_removal);\r\n }\r\n }\r\n }\r\n\r\n window.document.addEventListener(\"DOMContentLoaded\", function() {\r\n content_ready(window.document);\r\n });\r\n\r\n window.addEventListener(\r\n \"message\",\r\n function(event) {\r\n if (event.data && event.data.EVASuit &&\r\n event.data.EVASuit.Behaviors &&\r\n event.data.EVASuit.Behaviors.content_ready) {\r\n \r\n let context = document.querySelector(event.data.EVASuit.Behaviors.content_ready);\r\n content_ready(context);\r\n }\r\n }\r\n )\r\n\r\n Behaviors.register_behavior = register_behavior;\r\n Behaviors.register_content_listener = register_content_listener;\r\n Behaviors.content_ready = content_ready;\r\n Behaviors.content_removal = content_removal;\r\n}(window.EVASuit.Behaviors));","window.EVASuit = window.EVASuit || {};\r\nwindow.EVASuit.Behaviors = window.EVASuit.Behaviors || {};\r\n\r\nwindow.EVASuit.Behaviors.throttle_single = function() {\r\n \"use strict\";\r\n \r\n /* Throttle an event handler.\r\n *\r\n * Returns a function which, no matter how frequently it's called, will\r\n * only trigger a maximum of once per timeout period. More specifically,\r\n * the first event will always be processed, then, no events will process\r\n * until the end of the timeout period. If one or more events occurred\r\n * during this period, the last event recieved will trigger immediately\r\n * after the end of the timeout period, as well as restart the throttling\r\n * period. Any preceding events will be discarded.\r\n *\r\n * Not to be confused with a debounce, which only fires the event handler\r\n * at the end of a string of events spaced closer than the timeout period.\r\n *\r\n * The nature of this function means that any passed in function's return\r\n * value will be discarded.\r\n */\r\n function throttle_single(func, timeout) {\r\n var lastTimeout, afterLastArgs, afterLastThis;\r\n\r\n function unthrottle() {\r\n if (afterLastArgs !== undefined) {\r\n func.apply(afterLastThis, afterLastArgs);\r\n afterLastArgs = undefined;\r\n lastTimeout = window.setTimeout(unthrottle, timeout);\r\n } else {\r\n lastTimeout = undefined;\r\n }\r\n }\r\n\r\n return function () {\r\n var myThis = this, myArgs = [], i;\r\n\r\n for (i = 0; i < arguments.length; i += 1) {\r\n myArgs.push(arguments[i]);\r\n }\r\n\r\n if (lastTimeout === undefined) {\r\n func.apply(myThis, myArgs);\r\n lastTimeout = window.setTimeout(unthrottle, timeout);\r\n } else {\r\n afterLastArgs = myArgs;\r\n afterLastThis = myThis;\r\n }\r\n };\r\n }\r\n\r\n return throttle_single;\r\n}();"]}