From: Alexander Ebert Date: Wed, 13 Nov 2024 11:59:19 +0000 (+0100) Subject: Update the `focus-trap` lib X-Git-Tag: 6.1.1_dev_1~4^2~1 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=0ab7325e7b74a312e32e7632f7dbcbd1a9ffc005;p=GitHub%2FWoltLab%2FWCF.git Update the `focus-trap` lib --- diff --git a/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js b/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js index 9e83179a62..dc052c6025 100644 --- a/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js +++ b/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js @@ -1,6 +1,6 @@ /*! -* focus-trap 7.5.2 +* focus-trap 7.6.1 * @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("tabbable")):"function"==typeof define&&define.amd?define(["exports","tabbable"],t):(e="undefined"!=typeof globalThis?globalThis:e||self,function(){var n=e.focusTrap,o=e.focusTrap={};t(o,e.tabbable),o.noConflict=function(){return e.focusTrap=n,o}}())}(this,(function(e,t){"use strict";function n(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function o(e){for(var t=1;t0){var n=e[e.length-1];n!==t&&n.pause()}var o=e.indexOf(t);-1===o||e.splice(o,1),e.push(t)},i=function(e,t){var n=e.indexOf(t);-1!==n&&e.splice(n,1),e.length>0&&e[e.length-1].unpause()},u=function(e){return"Tab"===(null==e?void 0:e.key)||9===(null==e?void 0:e.keyCode)},c=function(e){return u(e)&&!e.shiftKey},s=function(e){return u(e)&&e.shiftKey},l=function(e){return setTimeout(e,0)},b=function(e,t){var n=-1;return e.every((function(e,o){return!t(e)||(n=o,!1)})),n},d=function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),o=1;o1?n-1:0),a=1;a=0)e=p.activeElement;else{var n=h.tabbableGroups[0];e=n&&n.firstTabbableNode||T("fallbackFocus")}if(!e)throw new Error("Your focus-trap needs to have at least one focusable element");return e},N=function(){if(h.containerGroups=h.containers.map((function(e){var n=t.tabbable(e,m.tabbableOptions),o=t.focusable(e,m.tabbableOptions),a=n.length>0?n[0]:void 0,r=n.length>0?n[n.length-1]:void 0,i=o.find((function(e){return t.isTabbable(e)})),u=o.slice().reverse().find((function(e){return t.isTabbable(e)})),c=!!n.find((function(e){return t.getTabIndex(e)>0}));return{container:e,tabbableNodes:n,focusableNodes:o,posTabIndexesFound:c,firstTabbableNode:a,lastTabbableNode:r,firstDomTabbableNode:i,lastDomTabbableNode:u,nextTabbableNode:function(e){var a=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],r=n.indexOf(e);return r<0?a?o.slice(o.indexOf(e)+1).find((function(e){return t.isTabbable(e)})):o.slice(0,o.indexOf(e)).reverse().find((function(e){return t.isTabbable(e)})):n[r+(a?1:-1)]}}})),h.tabbableGroups=h.containerGroups.filter((function(e){return e.tabbableNodes.length>0})),h.tabbableGroups.length<=0&&!T("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(h.containerGroups.find((function(e){return e.posTabIndexesFound}))&&h.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},O=function e(t){!1!==t&&t!==p.activeElement&&(t&&t.focus?(t.focus({preventScroll:!!m.preventScroll}),h.mostRecentlyFocusedNode=t,function(e){return e.tagName&&"input"===e.tagName.toLowerCase()&&"function"==typeof e.select}(t)&&t.select()):e(F()))},E=function(e){var t=T("setReturnFocus",e);return t||!1!==t&&e},k=function(e){var n=e.target,o=e.event,a=e.isBackward,r=void 0!==a&&a;n=n||f(o),N();var i=null;if(h.tabbableGroups.length>0){var c=w(n,o),s=c>=0?h.containerGroups[c]:void 0;if(c<0)i=r?h.tabbableGroups[h.tabbableGroups.length-1].lastTabbableNode:h.tabbableGroups[0].firstTabbableNode;else if(r){var l=b(h.tabbableGroups,(function(e){var t=e.firstTabbableNode;return n===t}));if(l<0&&(s.container===n||t.isFocusable(n,m.tabbableOptions)&&!t.isTabbable(n,m.tabbableOptions)&&!s.nextTabbableNode(n,!1))&&(l=c),l>=0){var d=0===l?h.tabbableGroups.length-1:l-1,v=h.tabbableGroups[d];i=t.getTabIndex(n)>=0?v.lastTabbableNode:v.lastDomTabbableNode}else u(o)||(i=s.nextTabbableNode(n,!1))}else{var p=b(h.tabbableGroups,(function(e){var t=e.lastTabbableNode;return n===t}));if(p<0&&(s.container===n||t.isFocusable(n,m.tabbableOptions)&&!t.isTabbable(n,m.tabbableOptions)&&!s.nextTabbableNode(n))&&(p=c),p>=0){var y=p===h.tabbableGroups.length-1?0:p+1,g=h.tabbableGroups[y];i=t.getTabIndex(n)>=0?g.firstTabbableNode:g.firstDomTabbableNode}else u(o)||(i=s.nextTabbableNode(n))}}else i=T("fallbackFocus");return i},P=function(e){var t=f(e);w(t,e)>=0||(d(m.clickOutsideDeactivates,e)?a.deactivate({returnFocus:m.returnFocusOnDeactivate}):d(m.allowOutsideClick,e)||e.preventDefault())},D=function(e){var n=f(e),o=w(n,e)>=0;if(o||n instanceof Document)o&&(h.mostRecentlyFocusedNode=n);else{var a;e.stopImmediatePropagation();var r=!0;if(h.mostRecentlyFocusedNode)if(t.getTabIndex(h.mostRecentlyFocusedNode)>0){var i=w(h.mostRecentlyFocusedNode),u=h.containerGroups[i].tabbableNodes;if(u.length>0){var c=u.findIndex((function(e){return e===h.mostRecentlyFocusedNode}));c>=0&&(m.isKeyForward(h.recentNavEvent)?c+1=0&&(a=u[c-1],r=!1))}}else h.containerGroups.some((function(e){return e.tabbableNodes.some((function(e){return t.getTabIndex(e)>0}))}))||(r=!1);else r=!1;r&&(a=k({target:h.mostRecentlyFocusedNode,isBackward:m.isKeyBackward(h.recentNavEvent)})),O(a||(h.mostRecentlyFocusedNode||F()))}h.recentNavEvent=void 0},x=function(e){if(!(t=e,"Escape"!==(null==t?void 0:t.key)&&"Esc"!==(null==t?void 0:t.key)&&27!==(null==t?void 0:t.keyCode)||!1===d(m.escapeDeactivates,e)))return e.preventDefault(),void a.deactivate();var t;(m.isKeyForward(e)||m.isKeyBackward(e))&&function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];h.recentNavEvent=e;var n=k({event:e,isBackward:t});n&&(u(e)&&e.preventDefault(),O(n))}(e,m.isKeyBackward(e))},G=function(e){var t=f(e);w(t,e)>=0||d(m.clickOutsideDeactivates,e)||d(m.allowOutsideClick,e)||(e.preventDefault(),e.stopImmediatePropagation())},I=function(){if(h.active)return r(y,a),h.delayInitialFocusTimer=m.delayInitialFocus?l((function(){O(F())})):O(F()),p.addEventListener("focusin",D,!0),p.addEventListener("mousedown",P,{capture:!0,passive:!1}),p.addEventListener("touchstart",P,{capture:!0,passive:!1}),p.addEventListener("click",G,{capture:!0,passive:!1}),p.addEventListener("keydown",x,{capture:!0,passive:!1}),a},j=function(){if(h.active)return p.removeEventListener("focusin",D,!0),p.removeEventListener("mousedown",P,!0),p.removeEventListener("touchstart",P,!0),p.removeEventListener("click",G,!0),p.removeEventListener("keydown",x,!0),a},R="undefined"!=typeof window&&"MutationObserver"in window?new MutationObserver((function(e){e.some((function(e){return Array.from(e.removedNodes).some((function(e){return e===h.mostRecentlyFocusedNode}))}))&&O(F())})):void 0,B=function(){R&&(R.disconnect(),h.active&&!h.paused&&h.containers.map((function(e){R.observe(e,{subtree:!0,childList:!0})})))};return(a={get active(){return h.active},get paused(){return h.paused},activate:function(e){if(h.active)return this;var t=g(e,"onActivate"),n=g(e,"onPostActivate"),o=g(e,"checkCanFocusTrap");o||N(),h.active=!0,h.paused=!1,h.nodeFocusedBeforeActivation=p.activeElement,null==t||t();var a=function(){o&&N(),I(),B(),null==n||n()};return o?(o(h.containers.concat()).then(a,a),this):(a(),this)},deactivate:function(e){if(!h.active)return this;var t=o({onDeactivate:m.onDeactivate,onPostDeactivate:m.onPostDeactivate,checkCanReturnFocus:m.checkCanReturnFocus},e);clearTimeout(h.delayInitialFocusTimer),h.delayInitialFocusTimer=void 0,j(),h.active=!1,h.paused=!1,B(),i(y,a);var n=g(t,"onDeactivate"),r=g(t,"onPostDeactivate"),u=g(t,"checkCanReturnFocus"),c=g(t,"returnFocus","returnFocusOnDeactivate");null==n||n();var s=function(){l((function(){c&&O(E(h.nodeFocusedBeforeActivation)),null==r||r()}))};return c&&u?(u(E(h.nodeFocusedBeforeActivation)).then(s,s),this):(s(),this)},pause:function(e){if(h.paused||!h.active)return this;var t=g(e,"onPause"),n=g(e,"onPostPause");return h.paused=!0,null==t||t(),j(),B(),null==n||n(),this},unpause:function(e){if(!h.paused||!h.active)return this;var t=g(e,"onUnpause"),n=g(e,"onPostUnpause");return h.paused=!1,null==t||t(),N(),I(),B(),null==n||n(),this},updateContainerElements:function(e){var t=[].concat(e).filter(Boolean);return h.containers=t.map((function(e){return"string"==typeof e?p.querySelector(e):e})),h.active&&N(),B(),this}}).updateContainerElements(e),a},Object.defineProperty(e,"__esModule",{value:!0})})); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("tabbable")):"function"==typeof define&&define.amd?define(["exports","tabbable"],t):(e="undefined"!=typeof globalThis?globalThis:e||self,function(){var n=e.focusTrap,o=e.focusTrap={};t(o,e.tabbable),o.noConflict=function(){return e.focusTrap=n,o}}())}(this,(function(e,t){"use strict";function n(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=Array(t);n0){var n=e[e.length-1];n!==t&&n.pause()}var o=e.indexOf(t);-1===o||e.splice(o,1),e.push(t)},c=function(e,t){var n=e.indexOf(t);-1!==n&&e.splice(n,1),e.length>0&&e[e.length-1].unpause()},s=function(e){return"Tab"===(null==e?void 0:e.key)||9===(null==e?void 0:e.keyCode)},l=function(e){return s(e)&&!e.shiftKey},b=function(e){return s(e)&&e.shiftKey},d=function(e){return setTimeout(e,0)},f=function(e,t){var n=-1;return e.every((function(e,o){return!t(e)||(n=o,!1)})),n},v=function(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:{},n=t.hasFallback,o=void 0!==n&&n,a=t.params,u=void 0===a?[]:a,c=h[e];if("function"==typeof c&&(c=c.apply(void 0,i(u))),!0===c&&(c=void 0),!c){if(void 0===c||!1===c)return c;throw new Error("`".concat(e,"` was specified but was not a node, or did not return a node"))}var s=c;if("string"==typeof c){try{s=r.querySelector(c)}catch(t){throw new Error("`".concat(e,'` appears to be an invalid selector; error="').concat(t.message,'"'))}if(!s&&!o)throw new Error("`".concat(e,"` as selector refers to no known node"))}return s},N=function(){var e=F("initialFocus",{hasFallback:!0});if(!1===e)return!1;if(void 0===e||e&&!t.isFocusable(e,h.tabbableOptions))if(T(r.activeElement)>=0)e=r.activeElement;else{var n=w.tabbableGroups[0];e=n&&n.firstTabbableNode||F("fallbackFocus")}else null===e&&(e=F("fallbackFocus"));if(!e)throw new Error("Your focus-trap needs to have at least one focusable element");return e},O=function(){if(w.containerGroups=w.containers.map((function(e){var n=t.tabbable(e,h.tabbableOptions),o=t.focusable(e,h.tabbableOptions),r=n.length>0?n[0]:void 0,a=n.length>0?n[n.length-1]:void 0,i=o.find((function(e){return t.isTabbable(e)})),u=o.slice().reverse().find((function(e){return t.isTabbable(e)})),c=!!n.find((function(e){return t.getTabIndex(e)>0}));return{container:e,tabbableNodes:n,focusableNodes:o,posTabIndexesFound:c,firstTabbableNode:r,lastTabbableNode:a,firstDomTabbableNode:i,lastDomTabbableNode:u,nextTabbableNode:function(e){var r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],a=n.indexOf(e);return a<0?r?o.slice(o.indexOf(e)+1).find((function(e){return t.isTabbable(e)})):o.slice(0,o.indexOf(e)).reverse().find((function(e){return t.isTabbable(e)})):n[a+(r?1:-1)]}}})),w.tabbableGroups=w.containerGroups.filter((function(e){return e.tabbableNodes.length>0})),w.tabbableGroups.length<=0&&!F("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(w.containerGroups.find((function(e){return e.posTabIndexesFound}))&&w.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},E=function(e){var t=e.activeElement;if(t)return t.shadowRoot&&null!==t.shadowRoot.activeElement?E(t.shadowRoot):t},k=function(e){!1!==e&&e!==E(document)&&(e&&e.focus?(e.focus({preventScroll:!!h.preventScroll}),w.mostRecentlyFocusedNode=e,function(e){return e.tagName&&"input"===e.tagName.toLowerCase()&&"function"==typeof e.select}(e)&&e.select()):k(N()))},D=function(e){var t=F("setReturnFocus",{params:[e]});return t||!1!==t&&e},P=function(e){var n=e.target,o=e.event,r=e.isBackward,a=void 0!==r&&r;n=n||p(o),O();var i=null;if(w.tabbableGroups.length>0){var u=T(n,o),c=u>=0?w.containerGroups[u]:void 0;if(u<0)i=a?w.tabbableGroups[w.tabbableGroups.length-1].lastTabbableNode:w.tabbableGroups[0].firstTabbableNode;else if(a){var l=f(w.tabbableGroups,(function(e){var t=e.firstTabbableNode;return n===t}));if(l<0&&(c.container===n||t.isFocusable(n,h.tabbableOptions)&&!t.isTabbable(n,h.tabbableOptions)&&!c.nextTabbableNode(n,!1))&&(l=u),l>=0){var b=0===l?w.tabbableGroups.length-1:l-1,d=w.tabbableGroups[b];i=t.getTabIndex(n)>=0?d.lastTabbableNode:d.lastDomTabbableNode}else s(o)||(i=c.nextTabbableNode(n,!1))}else{var v=f(w.tabbableGroups,(function(e){var t=e.lastTabbableNode;return n===t}));if(v<0&&(c.container===n||t.isFocusable(n,h.tabbableOptions)&&!t.isTabbable(n,h.tabbableOptions)&&!c.nextTabbableNode(n))&&(v=u),v>=0){var m=v===w.tabbableGroups.length-1?0:v+1,y=w.tabbableGroups[m];i=t.getTabIndex(n)>=0?y.firstTabbableNode:y.firstDomTabbableNode}else s(o)||(i=c.nextTabbableNode(n))}}else i=F("fallbackFocus");return i},x=function(e){var t=p(e);T(t,e)>=0||(v(h.clickOutsideDeactivates,e)?o.deactivate({returnFocus:h.returnFocusOnDeactivate}):v(h.allowOutsideClick,e)||e.preventDefault())},G=function(e){var n=p(e),o=T(n,e)>=0;if(o||n instanceof Document)o&&(w.mostRecentlyFocusedNode=n);else{var r;e.stopImmediatePropagation();var a=!0;if(w.mostRecentlyFocusedNode)if(t.getTabIndex(w.mostRecentlyFocusedNode)>0){var i=T(w.mostRecentlyFocusedNode),u=w.containerGroups[i].tabbableNodes;if(u.length>0){var c=u.findIndex((function(e){return e===w.mostRecentlyFocusedNode}));c>=0&&(h.isKeyForward(w.recentNavEvent)?c+1=0&&(r=u[c-1],a=!1))}}else w.containerGroups.some((function(e){return e.tabbableNodes.some((function(e){return t.getTabIndex(e)>0}))}))||(a=!1);else a=!1;a&&(r=P({target:w.mostRecentlyFocusedNode,isBackward:h.isKeyBackward(w.recentNavEvent)})),k(r||(w.mostRecentlyFocusedNode||N()))}w.recentNavEvent=void 0},I=function(e){(h.isKeyForward(e)||h.isKeyBackward(e))&&function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1];w.recentNavEvent=e;var n=P({event:e,isBackward:t});n&&(s(e)&&e.preventDefault(),k(n))}(e,h.isKeyBackward(e))},R=function(e){var t;"Escape"!==(null==(t=e)?void 0:t.key)&&"Esc"!==(null==t?void 0:t.key)&&27!==(null==t?void 0:t.keyCode)||!1===v(h.escapeDeactivates,e)||(e.preventDefault(),o.deactivate())},j=function(e){var t=p(e);T(t,e)>=0||v(h.clickOutsideDeactivates,e)||v(h.allowOutsideClick,e)||(e.preventDefault(),e.stopImmediatePropagation())},A=function(){if(w.active)return u(y,o),w.delayInitialFocusTimer=h.delayInitialFocus?d((function(){k(N())})):k(N()),r.addEventListener("focusin",G,!0),r.addEventListener("mousedown",x,{capture:!0,passive:!1}),r.addEventListener("touchstart",x,{capture:!0,passive:!1}),r.addEventListener("click",j,{capture:!0,passive:!1}),r.addEventListener("keydown",I,{capture:!0,passive:!1}),r.addEventListener("keydown",R),o},L=function(){if(w.active)return r.removeEventListener("focusin",G,!0),r.removeEventListener("mousedown",x,!0),r.removeEventListener("touchstart",x,!0),r.removeEventListener("click",j,!0),r.removeEventListener("keydown",I,!0),r.removeEventListener("keydown",R),o},S="undefined"!=typeof window&&"MutationObserver"in window?new MutationObserver((function(e){e.some((function(e){return Array.from(e.removedNodes).some((function(e){return e===w.mostRecentlyFocusedNode}))}))&&k(N())})):void 0,C=function(){S&&(S.disconnect(),w.active&&!w.paused&&w.containers.map((function(e){S.observe(e,{subtree:!0,childList:!0})})))};return(o={get active(){return w.active},get paused(){return w.paused},activate:function(e){if(w.active)return this;var t=g(e,"onActivate"),n=g(e,"onPostActivate"),o=g(e,"checkCanFocusTrap");o||O(),w.active=!0,w.paused=!1,w.nodeFocusedBeforeActivation=r.activeElement,null==t||t();var a=function(){o&&O(),A(),C(),null==n||n()};return o?(o(w.containers.concat()).then(a,a),this):(a(),this)},deactivate:function(e){if(!w.active)return this;var t=a({onDeactivate:h.onDeactivate,onPostDeactivate:h.onPostDeactivate,checkCanReturnFocus:h.checkCanReturnFocus},e);clearTimeout(w.delayInitialFocusTimer),w.delayInitialFocusTimer=void 0,L(),w.active=!1,w.paused=!1,C(),c(y,o);var n=g(t,"onDeactivate"),r=g(t,"onPostDeactivate"),i=g(t,"checkCanReturnFocus"),u=g(t,"returnFocus","returnFocusOnDeactivate");null==n||n();var s=function(){d((function(){u&&k(D(w.nodeFocusedBeforeActivation)),null==r||r()}))};return u&&i?(i(D(w.nodeFocusedBeforeActivation)).then(s,s),this):(s(),this)},pause:function(e){if(w.paused||!w.active)return this;var t=g(e,"onPause"),n=g(e,"onPostPause");return w.paused=!0,null==t||t(),L(),C(),null==n||n(),this},unpause:function(e){if(!w.paused||!w.active)return this;var t=g(e,"onUnpause"),n=g(e,"onPostUnpause");return w.paused=!1,null==t||t(),O(),A(),C(),null==n||n(),this},updateContainerElements:function(e){var t=[].concat(e).filter(Boolean);return w.containers=t.map((function(e){return"string"==typeof e?r.querySelector(e):e})),w.active&&O(),C(),this}}).updateContainerElements(e),o}})); //# sourceMappingURL=focus-trap.umd.min.js.map diff --git a/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js.map b/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js.map index fefe8fada1..2dffc2fc3e 100644 --- a/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js.map +++ b/wcfsetup/install/files/js/3rdParty/focus-trap/focus-trap.umd.min.js.map @@ -1 +1 @@ -{"version":3,"file":"focus-trap.umd.min.js","sources":["../index.js"],"sourcesContent":["import {\n tabbable,\n focusable,\n isFocusable,\n isTabbable,\n getTabIndex,\n} from 'tabbable';\n\nconst activeFocusTraps = {\n activateTrap(trapStack, trap) {\n if (trapStack.length > 0) {\n const activeTrap = trapStack[trapStack.length - 1];\n if (activeTrap !== trap) {\n activeTrap.pause();\n }\n }\n\n const trapIndex = trapStack.indexOf(trap);\n if (trapIndex === -1) {\n trapStack.push(trap);\n } else {\n // move this existing trap to the front of the queue\n trapStack.splice(trapIndex, 1);\n trapStack.push(trap);\n }\n },\n\n deactivateTrap(trapStack, trap) {\n const trapIndex = trapStack.indexOf(trap);\n if (trapIndex !== -1) {\n trapStack.splice(trapIndex, 1);\n }\n\n if (trapStack.length > 0) {\n trapStack[trapStack.length - 1].unpause();\n }\n },\n};\n\nconst isSelectableInput = function (node) {\n return (\n node.tagName &&\n node.tagName.toLowerCase() === 'input' &&\n typeof node.select === 'function'\n );\n};\n\nconst isEscapeEvent = function (e) {\n return e?.key === 'Escape' || e?.key === 'Esc' || e?.keyCode === 27;\n};\n\nconst isTabEvent = function (e) {\n return e?.key === 'Tab' || e?.keyCode === 9;\n};\n\n// checks for TAB by default\nconst isKeyForward = function (e) {\n return isTabEvent(e) && !e.shiftKey;\n};\n\n// checks for SHIFT+TAB by default\nconst isKeyBackward = function (e) {\n return isTabEvent(e) && e.shiftKey;\n};\n\nconst delay = function (fn) {\n return setTimeout(fn, 0);\n};\n\n// Array.find/findIndex() are not supported on IE; this replicates enough\n// of Array.findIndex() for our needs\nconst findIndex = function (arr, fn) {\n let idx = -1;\n\n arr.every(function (value, i) {\n if (fn(value)) {\n idx = i;\n return false; // break\n }\n\n return true; // next\n });\n\n return idx;\n};\n\n/**\n * Get an option's value when it could be a plain value, or a handler that provides\n * the value.\n * @param {*} value Option's value to check.\n * @param {...*} [params] Any parameters to pass to the handler, if `value` is a function.\n * @returns {*} The `value`, or the handler's returned value.\n */\nconst valueOrHandler = function (value, ...params) {\n return typeof value === 'function' ? value(...params) : value;\n};\n\nconst getActualTarget = function (event) {\n // NOTE: If the trap is _inside_ a shadow DOM, event.target will always be the\n // shadow host. However, event.target.composedPath() will be an array of\n // nodes \"clicked\" from inner-most (the actual element inside the shadow) to\n // outer-most (the host HTML document). If we have access to composedPath(),\n // then use its first element; otherwise, fall back to event.target (and\n // this only works for an _open_ shadow DOM; otherwise,\n // composedPath()[0] === event.target always).\n return event.target.shadowRoot && typeof event.composedPath === 'function'\n ? event.composedPath()[0]\n : event.target;\n};\n\n// NOTE: this must be _outside_ `createFocusTrap()` to make sure all traps in this\n// current instance use the same stack if `userOptions.trapStack` isn't specified\nconst internalTrapStack = [];\n\nconst createFocusTrap = function (elements, userOptions) {\n // SSR: a live trap shouldn't be created in this type of environment so this\n // should be safe code to execute if the `document` option isn't specified\n const doc = userOptions?.document || document;\n\n const trapStack = userOptions?.trapStack || internalTrapStack;\n\n const config = {\n returnFocusOnDeactivate: true,\n escapeDeactivates: true,\n delayInitialFocus: true,\n isKeyForward,\n isKeyBackward,\n ...userOptions,\n };\n\n const state = {\n // containers given to createFocusTrap()\n // @type {Array}\n containers: [],\n\n // list of objects identifying tabbable nodes in `containers` in the trap\n // NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap\n // is active, but the trap should never get to a state where there isn't at least one group\n // with at least one tabbable node in it (that would lead to an error condition that would\n // result in an error being thrown)\n // @type {Array<{\n // container: HTMLElement,\n // tabbableNodes: Array, // empty if none\n // focusableNodes: Array, // empty if none\n // posTabIndexesFound: boolean,\n // firstTabbableNode: HTMLElement|undefined,\n // lastTabbableNode: HTMLElement|undefined,\n // firstDomTabbableNode: HTMLElement|undefined,\n // lastDomTabbableNode: HTMLElement|undefined,\n // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined\n // }>}\n containerGroups: [], // same order/length as `containers` list\n\n // references to objects in `containerGroups`, but only those that actually have\n // tabbable nodes in them\n // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__\n // the same length\n tabbableGroups: [],\n\n nodeFocusedBeforeActivation: null,\n mostRecentlyFocusedNode: null,\n active: false,\n paused: false,\n\n // timer ID for when delayInitialFocus is true and initial focus in this trap\n // has been delayed during activation\n delayInitialFocusTimer: undefined,\n\n // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any\n recentNavEvent: undefined,\n };\n\n let trap; // eslint-disable-line prefer-const -- some private functions reference it, and its methods reference private functions, so we must declare here and define later\n\n /**\n * Gets a configuration option value.\n * @param {Object|undefined} configOverrideOptions If true, and option is defined in this set,\n * value will be taken from this object. Otherwise, value will be taken from base configuration.\n * @param {string} optionName Name of the option whose value is sought.\n * @param {string|undefined} [configOptionName] Name of option to use __instead of__ `optionName`\n * IIF `configOverrideOptions` is not defined. Otherwise, `optionName` is used.\n */\n const getOption = (configOverrideOptions, optionName, configOptionName) => {\n return configOverrideOptions &&\n configOverrideOptions[optionName] !== undefined\n ? configOverrideOptions[optionName]\n : config[configOptionName || optionName];\n };\n\n /**\n * Finds the index of the container that contains the element.\n * @param {HTMLElement} element\n * @param {Event} [event] If available, and `element` isn't directly found in any container,\n * the event's composed path is used to see if includes any known trap containers in the\n * case where the element is inside a Shadow DOM.\n * @returns {number} Index of the container in either `state.containers` or\n * `state.containerGroups` (the order/length of these lists are the same); -1\n * if the element isn't found.\n */\n const findContainerIndex = function (element, event) {\n const composedPath =\n typeof event?.composedPath === 'function'\n ? event.composedPath()\n : undefined;\n // NOTE: search `containerGroups` because it's possible a group contains no tabbable\n // nodes, but still contains focusable nodes (e.g. if they all have `tabindex=-1`)\n // and we still need to find the element in there\n return state.containerGroups.findIndex(\n ({ container, tabbableNodes }) =>\n container.contains(element) ||\n // fall back to explicit tabbable search which will take into consideration any\n // web components if the `tabbableOptions.getShadowRoot` option was used for\n // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't\n // look inside web components even if open)\n composedPath?.includes(container) ||\n tabbableNodes.find((node) => node === element)\n );\n };\n\n /**\n * Gets the node for the given option, which is expected to be an option that\n * can be either a DOM node, a string that is a selector to get a node, `false`\n * (if a node is explicitly NOT given), or a function that returns any of these\n * values.\n * @param {string} optionName\n * @returns {undefined | false | HTMLElement | SVGElement} Returns\n * `undefined` if the option is not specified; `false` if the option\n * resolved to `false` (node explicitly not given); otherwise, the resolved\n * DOM node.\n * @throws {Error} If the option is set, not `false`, and is not, or does not\n * resolve to a node.\n */\n const getNodeForOption = function (optionName, ...params) {\n let optionValue = config[optionName];\n\n if (typeof optionValue === 'function') {\n optionValue = optionValue(...params);\n }\n\n if (optionValue === true) {\n optionValue = undefined; // use default value\n }\n\n if (!optionValue) {\n if (optionValue === undefined || optionValue === false) {\n return optionValue;\n }\n // else, empty string (invalid), null (invalid), 0 (invalid)\n\n throw new Error(\n `\\`${optionName}\\` was specified but was not a node, or did not return a node`\n );\n }\n\n let node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point\n\n if (typeof optionValue === 'string') {\n node = doc.querySelector(optionValue); // resolve to node, or null if fails\n if (!node) {\n throw new Error(\n `\\`${optionName}\\` as selector refers to no known node`\n );\n }\n }\n\n return node;\n };\n\n const getInitialFocusNode = function () {\n let node = getNodeForOption('initialFocus');\n\n // false explicitly indicates we want no initialFocus at all\n if (node === false) {\n return false;\n }\n\n if (node === undefined || !isFocusable(node, config.tabbableOptions)) {\n // option not specified nor focusable: use fallback options\n if (findContainerIndex(doc.activeElement) >= 0) {\n node = doc.activeElement;\n } else {\n const firstTabbableGroup = state.tabbableGroups[0];\n const firstTabbableNode =\n firstTabbableGroup && firstTabbableGroup.firstTabbableNode;\n\n // NOTE: `fallbackFocus` option function cannot return `false` (not supported)\n node = firstTabbableNode || getNodeForOption('fallbackFocus');\n }\n }\n\n if (!node) {\n throw new Error(\n 'Your focus-trap needs to have at least one focusable element'\n );\n }\n\n return node;\n };\n\n const updateTabbableNodes = function () {\n state.containerGroups = state.containers.map((container) => {\n const tabbableNodes = tabbable(container, config.tabbableOptions);\n\n // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes\n // are a superset of tabbable nodes since nodes with negative `tabindex` attributes\n // are focusable but not tabbable\n const focusableNodes = focusable(container, config.tabbableOptions);\n\n const firstTabbableNode =\n tabbableNodes.length > 0 ? tabbableNodes[0] : undefined;\n const lastTabbableNode =\n tabbableNodes.length > 0\n ? tabbableNodes[tabbableNodes.length - 1]\n : undefined;\n\n const firstDomTabbableNode = focusableNodes.find((node) =>\n isTabbable(node)\n );\n const lastDomTabbableNode = focusableNodes\n .slice()\n .reverse()\n .find((node) => isTabbable(node));\n\n const posTabIndexesFound = !!tabbableNodes.find(\n (node) => getTabIndex(node) > 0\n );\n\n return {\n container,\n tabbableNodes,\n focusableNodes,\n\n /** True if at least one node with positive `tabindex` was found in this container. */\n posTabIndexesFound,\n\n /** First tabbable node in container, __tabindex__ order; `undefined` if none. */\n firstTabbableNode,\n /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */\n lastTabbableNode,\n\n // NOTE: DOM order is NOT NECESSARILY \"document position\" order, but figuring that out\n // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition\n // because that API doesn't work with Shadow DOM as well as it should (@see\n // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,\n // to address an edge case related to positive tabindex support, this seems like a much easier,\n // \"close enough most of the time\" alternative for positive tabindexes which should generally\n // be avoided anyway...\n /** First tabbable node in container, __DOM__ order; `undefined` if none. */\n firstDomTabbableNode,\n /** Last tabbable node in container, __DOM__ order; `undefined` if none. */\n lastDomTabbableNode,\n\n /**\n * Finds the __tabbable__ node that follows the given node in the specified direction,\n * in this container, if any.\n * @param {HTMLElement} node\n * @param {boolean} [forward] True if going in forward tab order; false if going\n * in reverse.\n * @returns {HTMLElement|undefined} The next tabbable node, if any.\n */\n nextTabbableNode(node, forward = true) {\n const nodeIdx = tabbableNodes.indexOf(node);\n if (nodeIdx < 0) {\n // either not tabbable nor focusable, or was focused but not tabbable (negative tabindex):\n // since `node` should at least have been focusable, we assume that's the case and mimic\n // what browsers do, which is set focus to the next node in __document position order__,\n // regardless of positive tabindexes, if any -- and for reasons explained in the NOTE\n // above related to `firstDomTabbable` and `lastDomTabbable` properties, we fall back to\n // basic DOM order\n if (forward) {\n return focusableNodes\n .slice(focusableNodes.indexOf(node) + 1)\n .find((el) => isTabbable(el));\n }\n\n return focusableNodes\n .slice(0, focusableNodes.indexOf(node))\n .reverse()\n .find((el) => isTabbable(el));\n }\n\n return tabbableNodes[nodeIdx + (forward ? 1 : -1)];\n },\n };\n });\n\n state.tabbableGroups = state.containerGroups.filter(\n (group) => group.tabbableNodes.length > 0\n );\n\n // throw if no groups have tabbable nodes and we don't have a fallback focus node either\n if (\n state.tabbableGroups.length <= 0 &&\n !getNodeForOption('fallbackFocus') // returning false not supported for this option\n ) {\n throw new Error(\n 'Your focus-trap must have at least one container with at least one tabbable node in it at all times'\n );\n }\n\n // NOTE: Positive tabindexes are only properly supported in single-container traps because\n // doing it across multiple containers where tabindexes could be all over the place\n // would require Tabbable to support multiple containers, would require additional\n // specialized Shadow DOM support, and would require Tabbable's multi-container support\n // to look at those containers in document position order rather than user-provided\n // order (as they are treated in Focus-trap, for legacy reasons). See discussion on\n // https://github.com/focus-trap/focus-trap/issues/375 for more details.\n if (\n state.containerGroups.find((g) => g.posTabIndexesFound) &&\n state.containerGroups.length > 1\n ) {\n throw new Error(\n \"At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.\"\n );\n }\n };\n\n const tryFocus = function (node) {\n if (node === false) {\n return;\n }\n\n if (node === doc.activeElement) {\n return;\n }\n\n if (!node || !node.focus) {\n tryFocus(getInitialFocusNode());\n return;\n }\n\n node.focus({ preventScroll: !!config.preventScroll });\n // NOTE: focus() API does not trigger focusIn event so set MRU node manually\n state.mostRecentlyFocusedNode = node;\n\n if (isSelectableInput(node)) {\n node.select();\n }\n };\n\n const getReturnFocusNode = function (previousActiveElement) {\n const node = getNodeForOption('setReturnFocus', previousActiveElement);\n return node ? node : node === false ? false : previousActiveElement;\n };\n\n /**\n * Finds the next node (in either direction) where focus should move according to a\n * keyboard focus-in event.\n * @param {Object} params\n * @param {Node} [params.target] Known target __from which__ to navigate, if any.\n * @param {KeyboardEvent|FocusEvent} [params.event] Event to use if `target` isn't known (event\n * will be used to determine the `target`). Ignored if `target` is specified.\n * @param {boolean} [params.isBackward] True if focus should move backward.\n * @returns {Node|undefined} The next node, or `undefined` if a next node couldn't be\n * determined given the current state of the trap.\n */\n const findNextNavNode = function ({ target, event, isBackward = false }) {\n target = target || getActualTarget(event);\n updateTabbableNodes();\n\n let destinationNode = null;\n\n if (state.tabbableGroups.length > 0) {\n // make sure the target is actually contained in a group\n // NOTE: the target may also be the container itself if it's focusable\n // with tabIndex='-1' and was given initial focus\n const containerIndex = findContainerIndex(target, event);\n const containerGroup =\n containerIndex >= 0 ? state.containerGroups[containerIndex] : undefined;\n\n if (containerIndex < 0) {\n // target not found in any group: quite possible focus has escaped the trap,\n // so bring it back into...\n if (isBackward) {\n // ...the last node in the last group\n destinationNode =\n state.tabbableGroups[state.tabbableGroups.length - 1]\n .lastTabbableNode;\n } else {\n // ...the first node in the first group\n destinationNode = state.tabbableGroups[0].firstTabbableNode;\n }\n } else if (isBackward) {\n // REVERSE\n\n // is the target the first tabbable node in a group?\n let startOfGroupIndex = findIndex(\n state.tabbableGroups,\n ({ firstTabbableNode }) => target === firstTabbableNode\n );\n\n if (\n startOfGroupIndex < 0 &&\n (containerGroup.container === target ||\n (isFocusable(target, config.tabbableOptions) &&\n !isTabbable(target, config.tabbableOptions) &&\n !containerGroup.nextTabbableNode(target, false)))\n ) {\n // an exception case where the target is either the container itself, or\n // a non-tabbable node that was given focus (i.e. tabindex is negative\n // and user clicked on it or node was programmatically given focus)\n // and is not followed by any other tabbable node, in which\n // case, we should handle shift+tab as if focus were on the container's\n // first tabbable node, and go to the last tabbable node of the LAST group\n startOfGroupIndex = containerIndex;\n }\n\n if (startOfGroupIndex >= 0) {\n // YES: then shift+tab should go to the last tabbable node in the\n // previous group (and wrap around to the last tabbable node of\n // the LAST group if it's the first tabbable node of the FIRST group)\n const destinationGroupIndex =\n startOfGroupIndex === 0\n ? state.tabbableGroups.length - 1\n : startOfGroupIndex - 1;\n\n const destinationGroup = state.tabbableGroups[destinationGroupIndex];\n\n destinationNode =\n getTabIndex(target) >= 0\n ? destinationGroup.lastTabbableNode\n : destinationGroup.lastDomTabbableNode;\n } else if (!isTabEvent(event)) {\n // user must have customized the nav keys so we have to move focus manually _within_\n // the active group: do this based on the order determined by tabbable()\n destinationNode = containerGroup.nextTabbableNode(target, false);\n }\n } else {\n // FORWARD\n\n // is the target the last tabbable node in a group?\n let lastOfGroupIndex = findIndex(\n state.tabbableGroups,\n ({ lastTabbableNode }) => target === lastTabbableNode\n );\n\n if (\n lastOfGroupIndex < 0 &&\n (containerGroup.container === target ||\n (isFocusable(target, config.tabbableOptions) &&\n !isTabbable(target, config.tabbableOptions) &&\n !containerGroup.nextTabbableNode(target)))\n ) {\n // an exception case where the target is the container itself, or\n // a non-tabbable node that was given focus (i.e. tabindex is negative\n // and user clicked on it or node was programmatically given focus)\n // and is not followed by any other tabbable node, in which\n // case, we should handle tab as if focus were on the container's\n // last tabbable node, and go to the first tabbable node of the FIRST group\n lastOfGroupIndex = containerIndex;\n }\n\n if (lastOfGroupIndex >= 0) {\n // YES: then tab should go to the first tabbable node in the next\n // group (and wrap around to the first tabbable node of the FIRST\n // group if it's the last tabbable node of the LAST group)\n const destinationGroupIndex =\n lastOfGroupIndex === state.tabbableGroups.length - 1\n ? 0\n : lastOfGroupIndex + 1;\n\n const destinationGroup = state.tabbableGroups[destinationGroupIndex];\n\n destinationNode =\n getTabIndex(target) >= 0\n ? destinationGroup.firstTabbableNode\n : destinationGroup.firstDomTabbableNode;\n } else if (!isTabEvent(event)) {\n // user must have customized the nav keys so we have to move focus manually _within_\n // the active group: do this based on the order determined by tabbable()\n destinationNode = containerGroup.nextTabbableNode(target);\n }\n }\n } else {\n // no groups available\n // NOTE: the fallbackFocus option does not support returning false to opt-out\n destinationNode = getNodeForOption('fallbackFocus');\n }\n\n return destinationNode;\n };\n\n // This needs to be done on mousedown and touchstart instead of click\n // so that it precedes the focus event.\n const checkPointerDown = function (e) {\n const target = getActualTarget(e);\n\n if (findContainerIndex(target, e) >= 0) {\n // allow the click since it ocurred inside the trap\n return;\n }\n\n if (valueOrHandler(config.clickOutsideDeactivates, e)) {\n // immediately deactivate the trap\n trap.deactivate({\n // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,\n // which will result in the outside click setting focus to the node\n // that was clicked (and if not focusable, to \"nothing\"); by setting\n // `returnFocus: true`, we'll attempt to re-focus the node originally-focused\n // on activation (or the configured `setReturnFocus` node), whether the\n // outside click was on a focusable node or not\n returnFocus: config.returnFocusOnDeactivate,\n });\n return;\n }\n\n // This is needed for mobile devices.\n // (If we'll only let `click` events through,\n // then on mobile they will be blocked anyways if `touchstart` is blocked.)\n if (valueOrHandler(config.allowOutsideClick, e)) {\n // allow the click outside the trap to take place\n return;\n }\n\n // otherwise, prevent the click\n e.preventDefault();\n };\n\n // In case focus escapes the trap for some strange reason, pull it back in.\n // NOTE: the focusIn event is NOT cancelable, so if focus escapes, it may cause unexpected\n // scrolling if the node that got focused was out of view; there's nothing we can do to\n // prevent that from happening by the time we discover that focus escaped\n const checkFocusIn = function (event) {\n const target = getActualTarget(event);\n const targetContained = findContainerIndex(target, event) >= 0;\n\n // In Firefox when you Tab out of an iframe the Document is briefly focused.\n if (targetContained || target instanceof Document) {\n if (targetContained) {\n state.mostRecentlyFocusedNode = target;\n }\n } else {\n // escaped! pull it back in to where it just left\n event.stopImmediatePropagation();\n\n // focus will escape if the MRU node had a positive tab index and user tried to nav forward;\n // it will also escape if the MRU node had a 0 tab index and user tried to nav backward\n // toward a node with a positive tab index\n let nextNode; // next node to focus, if we find one\n let navAcrossContainers = true;\n if (state.mostRecentlyFocusedNode) {\n if (getTabIndex(state.mostRecentlyFocusedNode) > 0) {\n // MRU container index must be >=0 otherwise we wouldn't have it as an MRU node...\n const mruContainerIdx = findContainerIndex(\n state.mostRecentlyFocusedNode\n );\n // there MAY not be any tabbable nodes in the container if there are at least 2 containers\n // and the MRU node is focusable but not tabbable (focus-trap requires at least 1 container\n // with at least one tabbable node in order to function, so this could be the other container\n // with nothing tabbable in it)\n const { tabbableNodes } = state.containerGroups[mruContainerIdx];\n if (tabbableNodes.length > 0) {\n // MRU tab index MAY not be found if the MRU node is focusable but not tabbable\n const mruTabIdx = tabbableNodes.findIndex(\n (node) => node === state.mostRecentlyFocusedNode\n );\n if (mruTabIdx >= 0) {\n if (config.isKeyForward(state.recentNavEvent)) {\n if (mruTabIdx + 1 < tabbableNodes.length) {\n nextNode = tabbableNodes[mruTabIdx + 1];\n navAcrossContainers = false;\n }\n // else, don't wrap within the container as focus should move to next/previous\n // container\n } else {\n if (mruTabIdx - 1 >= 0) {\n nextNode = tabbableNodes[mruTabIdx - 1];\n navAcrossContainers = false;\n }\n // else, don't wrap within the container as focus should move to next/previous\n // container\n }\n // else, don't find in container order without considering direction too\n }\n }\n // else, no tabbable nodes in that container (which means we must have at least one other\n // container with at least one tabbable node in it, otherwise focus-trap would've thrown\n // an error the last time updateTabbableNodes() was run): find next node among all known\n // containers\n } else {\n // check to see if there's at least one tabbable node with a positive tab index inside\n // the trap because focus seems to escape when navigating backward from a tabbable node\n // with tabindex=0 when this is the case (instead of wrapping to the tabbable node with\n // the greatest positive tab index like it should)\n if (\n !state.containerGroups.some((g) =>\n g.tabbableNodes.some((n) => getTabIndex(n) > 0)\n )\n ) {\n // no containers with tabbable nodes with positive tab indexes which means the focus\n // escaped for some other reason and we should just execute the fallback to the\n // MRU node or initial focus node, if any\n navAcrossContainers = false;\n }\n }\n } else {\n // no MRU node means we're likely in some initial condition when the trap has just\n // been activated and initial focus hasn't been given yet, in which case we should\n // fall through to trying to focus the initial focus node, which is what should\n // happen below at this point in the logic\n navAcrossContainers = false;\n }\n\n if (navAcrossContainers) {\n nextNode = findNextNavNode({\n // move FROM the MRU node, not event-related node (which will be the node that is\n // outside the trap causing the focus escape we're trying to fix)\n target: state.mostRecentlyFocusedNode,\n isBackward: config.isKeyBackward(state.recentNavEvent),\n });\n }\n\n if (nextNode) {\n tryFocus(nextNode);\n } else {\n tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());\n }\n }\n\n state.recentNavEvent = undefined; // clear\n };\n\n // Hijack key nav events on the first and last focusable nodes of the trap,\n // in order to prevent focus from escaping. If it escapes for even a\n // moment it can end up scrolling the page and causing confusion so we\n // kind of need to capture the action at the keydown phase.\n const checkKeyNav = function (event, isBackward = false) {\n state.recentNavEvent = event;\n\n const destinationNode = findNextNavNode({ event, isBackward });\n if (destinationNode) {\n if (isTabEvent(event)) {\n // since tab natively moves focus, we wouldn't have a destination node unless we\n // were on the edge of a container and had to move to the next/previous edge, in\n // which case we want to prevent default to keep the browser from moving focus\n // to where it normally would\n event.preventDefault();\n }\n tryFocus(destinationNode);\n }\n // else, let the browser take care of [shift+]tab and move the focus\n };\n\n const checkKey = function (event) {\n if (\n isEscapeEvent(event) &&\n valueOrHandler(config.escapeDeactivates, event) !== false\n ) {\n event.preventDefault();\n trap.deactivate();\n return;\n }\n\n if (config.isKeyForward(event) || config.isKeyBackward(event)) {\n checkKeyNav(event, config.isKeyBackward(event));\n }\n };\n\n const checkClick = function (e) {\n const target = getActualTarget(e);\n\n if (findContainerIndex(target, e) >= 0) {\n return;\n }\n\n if (valueOrHandler(config.clickOutsideDeactivates, e)) {\n return;\n }\n\n if (valueOrHandler(config.allowOutsideClick, e)) {\n return;\n }\n\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n\n //\n // EVENT LISTENERS\n //\n\n const addListeners = function () {\n if (!state.active) {\n return;\n }\n\n // There can be only one listening focus trap at a time\n activeFocusTraps.activateTrap(trapStack, trap);\n\n // Delay ensures that the focused element doesn't capture the event\n // that caused the focus trap activation.\n state.delayInitialFocusTimer = config.delayInitialFocus\n ? delay(function () {\n tryFocus(getInitialFocusNode());\n })\n : tryFocus(getInitialFocusNode());\n\n doc.addEventListener('focusin', checkFocusIn, true);\n doc.addEventListener('mousedown', checkPointerDown, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('touchstart', checkPointerDown, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('click', checkClick, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('keydown', checkKey, {\n capture: true,\n passive: false,\n });\n\n return trap;\n };\n\n const removeListeners = function () {\n if (!state.active) {\n return;\n }\n\n doc.removeEventListener('focusin', checkFocusIn, true);\n doc.removeEventListener('mousedown', checkPointerDown, true);\n doc.removeEventListener('touchstart', checkPointerDown, true);\n doc.removeEventListener('click', checkClick, true);\n doc.removeEventListener('keydown', checkKey, true);\n\n return trap;\n };\n\n //\n // MUTATION OBSERVER\n //\n\n const checkDomRemoval = function (mutations) {\n const isFocusedNodeRemoved = mutations.some(function (mutation) {\n const removedNodes = Array.from(mutation.removedNodes);\n return removedNodes.some(function (node) {\n return node === state.mostRecentlyFocusedNode;\n });\n });\n\n // If the currently focused is removed then browsers will move focus to the\n // element. If this happens, try to move focus back into the trap.\n if (isFocusedNodeRemoved) {\n tryFocus(getInitialFocusNode());\n }\n };\n\n // Use MutationObserver - if supported - to detect if focused node is removed\n // from the DOM.\n const mutationObserver =\n typeof window !== 'undefined' && 'MutationObserver' in window\n ? new MutationObserver(checkDomRemoval)\n : undefined;\n\n const updateObservedNodes = function () {\n if (!mutationObserver) {\n return;\n }\n\n mutationObserver.disconnect();\n if (state.active && !state.paused) {\n state.containers.map(function (container) {\n mutationObserver.observe(container, {\n subtree: true,\n childList: true,\n });\n });\n }\n };\n\n //\n // TRAP DEFINITION\n //\n\n trap = {\n get active() {\n return state.active;\n },\n\n get paused() {\n return state.paused;\n },\n\n activate(activateOptions) {\n if (state.active) {\n return this;\n }\n\n const onActivate = getOption(activateOptions, 'onActivate');\n const onPostActivate = getOption(activateOptions, 'onPostActivate');\n const checkCanFocusTrap = getOption(activateOptions, 'checkCanFocusTrap');\n\n if (!checkCanFocusTrap) {\n updateTabbableNodes();\n }\n\n state.active = true;\n state.paused = false;\n state.nodeFocusedBeforeActivation = doc.activeElement;\n\n onActivate?.();\n\n const finishActivation = () => {\n if (checkCanFocusTrap) {\n updateTabbableNodes();\n }\n addListeners();\n updateObservedNodes();\n onPostActivate?.();\n };\n\n if (checkCanFocusTrap) {\n checkCanFocusTrap(state.containers.concat()).then(\n finishActivation,\n finishActivation\n );\n return this;\n }\n\n finishActivation();\n return this;\n },\n\n deactivate(deactivateOptions) {\n if (!state.active) {\n return this;\n }\n\n const options = {\n onDeactivate: config.onDeactivate,\n onPostDeactivate: config.onPostDeactivate,\n checkCanReturnFocus: config.checkCanReturnFocus,\n ...deactivateOptions,\n };\n\n clearTimeout(state.delayInitialFocusTimer); // noop if undefined\n state.delayInitialFocusTimer = undefined;\n\n removeListeners();\n state.active = false;\n state.paused = false;\n updateObservedNodes();\n\n activeFocusTraps.deactivateTrap(trapStack, trap);\n\n const onDeactivate = getOption(options, 'onDeactivate');\n const onPostDeactivate = getOption(options, 'onPostDeactivate');\n const checkCanReturnFocus = getOption(options, 'checkCanReturnFocus');\n const returnFocus = getOption(\n options,\n 'returnFocus',\n 'returnFocusOnDeactivate'\n );\n\n onDeactivate?.();\n\n const finishDeactivation = () => {\n delay(() => {\n if (returnFocus) {\n tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));\n }\n onPostDeactivate?.();\n });\n };\n\n if (returnFocus && checkCanReturnFocus) {\n checkCanReturnFocus(\n getReturnFocusNode(state.nodeFocusedBeforeActivation)\n ).then(finishDeactivation, finishDeactivation);\n return this;\n }\n\n finishDeactivation();\n return this;\n },\n\n pause(pauseOptions) {\n if (state.paused || !state.active) {\n return this;\n }\n\n const onPause = getOption(pauseOptions, 'onPause');\n const onPostPause = getOption(pauseOptions, 'onPostPause');\n\n state.paused = true;\n onPause?.();\n\n removeListeners();\n updateObservedNodes();\n\n onPostPause?.();\n return this;\n },\n\n unpause(unpauseOptions) {\n if (!state.paused || !state.active) {\n return this;\n }\n\n const onUnpause = getOption(unpauseOptions, 'onUnpause');\n const onPostUnpause = getOption(unpauseOptions, 'onPostUnpause');\n\n state.paused = false;\n onUnpause?.();\n\n updateTabbableNodes();\n addListeners();\n updateObservedNodes();\n\n onPostUnpause?.();\n return this;\n },\n\n updateContainerElements(containerElements) {\n const elementsAsArray = [].concat(containerElements).filter(Boolean);\n\n state.containers = elementsAsArray.map((element) =>\n typeof element === 'string' ? doc.querySelector(element) : element\n );\n\n if (state.active) {\n updateTabbableNodes();\n }\n\n updateObservedNodes();\n\n return this;\n },\n };\n\n // initialize container elements\n trap.updateContainerElements(elements);\n\n return trap;\n};\n\nexport { createFocusTrap };\n"],"names":["activeFocusTraps","activateTrap","trapStack","trap","length","activeTrap","pause","trapIndex","indexOf","splice","push","deactivateTrap","unpause","isTabEvent","e","key","keyCode","isKeyForward","shiftKey","isKeyBackward","delay","fn","setTimeout","findIndex","arr","idx","every","value","i","valueOrHandler","_len","arguments","params","Array","_key","apply","getActualTarget","event","target","shadowRoot","composedPath","internalTrapStack","elements","userOptions","doc","document","config","_objectSpread","returnFocusOnDeactivate","escapeDeactivates","delayInitialFocus","state","containers","containerGroups","tabbableGroups","nodeFocusedBeforeActivation","mostRecentlyFocusedNode","active","paused","delayInitialFocusTimer","undefined","recentNavEvent","getOption","configOverrideOptions","optionName","configOptionName","findContainerIndex","element","_ref","container","tabbableNodes","contains","includes","find","node","getNodeForOption","optionValue","_len2","_key2","Error","concat","querySelector","getInitialFocusNode","isFocusable","tabbableOptions","activeElement","firstTabbableGroup","firstTabbableNode","updateTabbableNodes","map","tabbable","focusableNodes","focusable","lastTabbableNode","firstDomTabbableNode","isTabbable","lastDomTabbableNode","slice","reverse","posTabIndexesFound","getTabIndex","nextTabbableNode","forward","nodeIdx","el","filter","group","g","tryFocus","focus","preventScroll","tagName","toLowerCase","select","isSelectableInput","getReturnFocusNode","previousActiveElement","findNextNavNode","_ref2","_ref2$isBackward","isBackward","destinationNode","containerIndex","containerGroup","startOfGroupIndex","_ref3","destinationGroupIndex","destinationGroup","lastOfGroupIndex","_ref4","checkPointerDown","clickOutsideDeactivates","deactivate","returnFocus","allowOutsideClick","preventDefault","checkFocusIn","targetContained","Document","nextNode","stopImmediatePropagation","navAcrossContainers","mruContainerIdx","mruTabIdx","some","n","checkKey","checkKeyNav","checkClick","addListeners","addEventListener","capture","passive","removeListeners","removeEventListener","mutationObserver","window","MutationObserver","mutations","mutation","from","removedNodes","updateObservedNodes","disconnect","observe","subtree","childList","activate","activateOptions","this","onActivate","onPostActivate","checkCanFocusTrap","finishActivation","then","deactivateOptions","options","onDeactivate","onPostDeactivate","checkCanReturnFocus","clearTimeout","finishDeactivation","pauseOptions","onPause","onPostPause","unpauseOptions","onUnpause","onPostUnpause","updateContainerElements","containerElements","elementsAsArray","Boolean"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"focus-trap.umd.min.js","sources":["../index.js"],"sourcesContent":["import {\n tabbable,\n focusable,\n isFocusable,\n isTabbable,\n getTabIndex,\n} from 'tabbable';\n\nconst activeFocusTraps = {\n activateTrap(trapStack, trap) {\n if (trapStack.length > 0) {\n const activeTrap = trapStack[trapStack.length - 1];\n if (activeTrap !== trap) {\n activeTrap.pause();\n }\n }\n\n const trapIndex = trapStack.indexOf(trap);\n if (trapIndex === -1) {\n trapStack.push(trap);\n } else {\n // move this existing trap to the front of the queue\n trapStack.splice(trapIndex, 1);\n trapStack.push(trap);\n }\n },\n\n deactivateTrap(trapStack, trap) {\n const trapIndex = trapStack.indexOf(trap);\n if (trapIndex !== -1) {\n trapStack.splice(trapIndex, 1);\n }\n\n if (trapStack.length > 0) {\n trapStack[trapStack.length - 1].unpause();\n }\n },\n};\n\nconst isSelectableInput = function (node) {\n return (\n node.tagName &&\n node.tagName.toLowerCase() === 'input' &&\n typeof node.select === 'function'\n );\n};\n\nconst isEscapeEvent = function (e) {\n return e?.key === 'Escape' || e?.key === 'Esc' || e?.keyCode === 27;\n};\n\nconst isTabEvent = function (e) {\n return e?.key === 'Tab' || e?.keyCode === 9;\n};\n\n// checks for TAB by default\nconst isKeyForward = function (e) {\n return isTabEvent(e) && !e.shiftKey;\n};\n\n// checks for SHIFT+TAB by default\nconst isKeyBackward = function (e) {\n return isTabEvent(e) && e.shiftKey;\n};\n\nconst delay = function (fn) {\n return setTimeout(fn, 0);\n};\n\n// Array.find/findIndex() are not supported on IE; this replicates enough\n// of Array.findIndex() for our needs\nconst findIndex = function (arr, fn) {\n let idx = -1;\n\n arr.every(function (value, i) {\n if (fn(value)) {\n idx = i;\n return false; // break\n }\n\n return true; // next\n });\n\n return idx;\n};\n\n/**\n * Get an option's value when it could be a plain value, or a handler that provides\n * the value.\n * @param {*} value Option's value to check.\n * @param {...*} [params] Any parameters to pass to the handler, if `value` is a function.\n * @returns {*} The `value`, or the handler's returned value.\n */\nconst valueOrHandler = function (value, ...params) {\n return typeof value === 'function' ? value(...params) : value;\n};\n\nconst getActualTarget = function (event) {\n // NOTE: If the trap is _inside_ a shadow DOM, event.target will always be the\n // shadow host. However, event.target.composedPath() will be an array of\n // nodes \"clicked\" from inner-most (the actual element inside the shadow) to\n // outer-most (the host HTML document). If we have access to composedPath(),\n // then use its first element; otherwise, fall back to event.target (and\n // this only works for an _open_ shadow DOM; otherwise,\n // composedPath()[0] === event.target always).\n return event.target.shadowRoot && typeof event.composedPath === 'function'\n ? event.composedPath()[0]\n : event.target;\n};\n\n// NOTE: this must be _outside_ `createFocusTrap()` to make sure all traps in this\n// current instance use the same stack if `userOptions.trapStack` isn't specified\nconst internalTrapStack = [];\n\nconst createFocusTrap = function (elements, userOptions) {\n // SSR: a live trap shouldn't be created in this type of environment so this\n // should be safe code to execute if the `document` option isn't specified\n const doc = userOptions?.document || document;\n\n const trapStack = userOptions?.trapStack || internalTrapStack;\n\n const config = {\n returnFocusOnDeactivate: true,\n escapeDeactivates: true,\n delayInitialFocus: true,\n isKeyForward,\n isKeyBackward,\n ...userOptions,\n };\n\n const state = {\n // containers given to createFocusTrap()\n // @type {Array}\n containers: [],\n\n // list of objects identifying tabbable nodes in `containers` in the trap\n // NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap\n // is active, but the trap should never get to a state where there isn't at least one group\n // with at least one tabbable node in it (that would lead to an error condition that would\n // result in an error being thrown)\n // @type {Array<{\n // container: HTMLElement,\n // tabbableNodes: Array, // empty if none\n // focusableNodes: Array, // empty if none\n // posTabIndexesFound: boolean,\n // firstTabbableNode: HTMLElement|undefined,\n // lastTabbableNode: HTMLElement|undefined,\n // firstDomTabbableNode: HTMLElement|undefined,\n // lastDomTabbableNode: HTMLElement|undefined,\n // nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined\n // }>}\n containerGroups: [], // same order/length as `containers` list\n\n // references to objects in `containerGroups`, but only those that actually have\n // tabbable nodes in them\n // NOTE: same order as `containers` and `containerGroups`, but __not necessarily__\n // the same length\n tabbableGroups: [],\n\n nodeFocusedBeforeActivation: null,\n mostRecentlyFocusedNode: null,\n active: false,\n paused: false,\n\n // timer ID for when delayInitialFocus is true and initial focus in this trap\n // has been delayed during activation\n delayInitialFocusTimer: undefined,\n\n // the most recent KeyboardEvent for the configured nav key (typically [SHIFT+]TAB), if any\n recentNavEvent: undefined,\n };\n\n let trap; // eslint-disable-line prefer-const -- some private functions reference it, and its methods reference private functions, so we must declare here and define later\n\n /**\n * Gets a configuration option value.\n * @param {Object|undefined} configOverrideOptions If true, and option is defined in this set,\n * value will be taken from this object. Otherwise, value will be taken from base configuration.\n * @param {string} optionName Name of the option whose value is sought.\n * @param {string|undefined} [configOptionName] Name of option to use __instead of__ `optionName`\n * IIF `configOverrideOptions` is not defined. Otherwise, `optionName` is used.\n */\n const getOption = (configOverrideOptions, optionName, configOptionName) => {\n return configOverrideOptions &&\n configOverrideOptions[optionName] !== undefined\n ? configOverrideOptions[optionName]\n : config[configOptionName || optionName];\n };\n\n /**\n * Finds the index of the container that contains the element.\n * @param {HTMLElement} element\n * @param {Event} [event] If available, and `element` isn't directly found in any container,\n * the event's composed path is used to see if includes any known trap containers in the\n * case where the element is inside a Shadow DOM.\n * @returns {number} Index of the container in either `state.containers` or\n * `state.containerGroups` (the order/length of these lists are the same); -1\n * if the element isn't found.\n */\n const findContainerIndex = function (element, event) {\n const composedPath =\n typeof event?.composedPath === 'function'\n ? event.composedPath()\n : undefined;\n // NOTE: search `containerGroups` because it's possible a group contains no tabbable\n // nodes, but still contains focusable nodes (e.g. if they all have `tabindex=-1`)\n // and we still need to find the element in there\n return state.containerGroups.findIndex(\n ({ container, tabbableNodes }) =>\n container.contains(element) ||\n // fall back to explicit tabbable search which will take into consideration any\n // web components if the `tabbableOptions.getShadowRoot` option was used for\n // the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't\n // look inside web components even if open)\n composedPath?.includes(container) ||\n tabbableNodes.find((node) => node === element)\n );\n };\n\n /**\n * Gets the node for the given option, which is expected to be an option that\n * can be either a DOM node, a string that is a selector to get a node, `false`\n * (if a node is explicitly NOT given), or a function that returns any of these\n * values.\n * @param {string} optionName\n * @param {Object} options\n * @param {boolean} [options.hasFallback] True if the option could be a selector string\n * and the option allows for a fallback scenario in the case where the selector is\n * valid but does not match a node (i.e. the queried node doesn't exist in the DOM).\n * @param {Array} [options.params] Params to pass to the option if it's a function.\n * @returns {undefined | null | false | HTMLElement | SVGElement} Returns\n * `undefined` if the option is not specified; `null` if the option didn't resolve\n * to a node but `options.hasFallback=true`, `false` if the option resolved to `false`\n * (node explicitly not given); otherwise, the resolved DOM node.\n * @throws {Error} If the option is set, not `false`, and is not, or does not\n * resolve to a node, unless the option is a selector string and `options.hasFallback=true`.\n */\n const getNodeForOption = function (\n optionName,\n { hasFallback = false, params = [] } = {}\n ) {\n let optionValue = config[optionName];\n\n if (typeof optionValue === 'function') {\n optionValue = optionValue(...params);\n }\n\n if (optionValue === true) {\n optionValue = undefined; // use default value\n }\n\n if (!optionValue) {\n if (optionValue === undefined || optionValue === false) {\n return optionValue;\n }\n // else, empty string (invalid), null (invalid), 0 (invalid)\n\n throw new Error(\n `\\`${optionName}\\` was specified but was not a node, or did not return a node`\n );\n }\n\n let node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point\n\n if (typeof optionValue === 'string') {\n try {\n node = doc.querySelector(optionValue); // resolve to node, or null if fails\n } catch (err) {\n throw new Error(\n `\\`${optionName}\\` appears to be an invalid selector; error=\"${err.message}\"`\n );\n }\n\n if (!node) {\n if (!hasFallback) {\n throw new Error(\n `\\`${optionName}\\` as selector refers to no known node`\n );\n }\n // else, `node` MUST be `null` because that's what `Document.querySelector()` returns\n // if the selector is valid but doesn't match anything\n }\n }\n\n return node;\n };\n\n const getInitialFocusNode = function () {\n let node = getNodeForOption('initialFocus', { hasFallback: true });\n\n // false explicitly indicates we want no initialFocus at all\n if (node === false) {\n return false;\n }\n\n if (\n node === undefined ||\n (node && !isFocusable(node, config.tabbableOptions))\n ) {\n // option not specified nor focusable: use fallback options\n if (findContainerIndex(doc.activeElement) >= 0) {\n node = doc.activeElement;\n } else {\n const firstTabbableGroup = state.tabbableGroups[0];\n const firstTabbableNode =\n firstTabbableGroup && firstTabbableGroup.firstTabbableNode;\n\n // NOTE: `fallbackFocus` option function cannot return `false` (not supported)\n node = firstTabbableNode || getNodeForOption('fallbackFocus');\n }\n } else if (node === null) {\n // option is a VALID selector string that doesn't yield a node: use the `fallbackFocus`\n // option instead of the default behavior when the option isn't specified at all\n node = getNodeForOption('fallbackFocus');\n }\n\n if (!node) {\n throw new Error(\n 'Your focus-trap needs to have at least one focusable element'\n );\n }\n\n return node;\n };\n\n const updateTabbableNodes = function () {\n state.containerGroups = state.containers.map((container) => {\n const tabbableNodes = tabbable(container, config.tabbableOptions);\n\n // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes\n // are a superset of tabbable nodes since nodes with negative `tabindex` attributes\n // are focusable but not tabbable\n const focusableNodes = focusable(container, config.tabbableOptions);\n\n const firstTabbableNode =\n tabbableNodes.length > 0 ? tabbableNodes[0] : undefined;\n const lastTabbableNode =\n tabbableNodes.length > 0\n ? tabbableNodes[tabbableNodes.length - 1]\n : undefined;\n\n const firstDomTabbableNode = focusableNodes.find((node) =>\n isTabbable(node)\n );\n const lastDomTabbableNode = focusableNodes\n .slice()\n .reverse()\n .find((node) => isTabbable(node));\n\n const posTabIndexesFound = !!tabbableNodes.find(\n (node) => getTabIndex(node) > 0\n );\n\n return {\n container,\n tabbableNodes,\n focusableNodes,\n\n /** True if at least one node with positive `tabindex` was found in this container. */\n posTabIndexesFound,\n\n /** First tabbable node in container, __tabindex__ order; `undefined` if none. */\n firstTabbableNode,\n /** Last tabbable node in container, __tabindex__ order; `undefined` if none. */\n lastTabbableNode,\n\n // NOTE: DOM order is NOT NECESSARILY \"document position\" order, but figuring that out\n // would require more than just https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition\n // because that API doesn't work with Shadow DOM as well as it should (@see\n // https://github.com/whatwg/dom/issues/320) and since this first/last is only needed, so far,\n // to address an edge case related to positive tabindex support, this seems like a much easier,\n // \"close enough most of the time\" alternative for positive tabindexes which should generally\n // be avoided anyway...\n /** First tabbable node in container, __DOM__ order; `undefined` if none. */\n firstDomTabbableNode,\n /** Last tabbable node in container, __DOM__ order; `undefined` if none. */\n lastDomTabbableNode,\n\n /**\n * Finds the __tabbable__ node that follows the given node in the specified direction,\n * in this container, if any.\n * @param {HTMLElement} node\n * @param {boolean} [forward] True if going in forward tab order; false if going\n * in reverse.\n * @returns {HTMLElement|undefined} The next tabbable node, if any.\n */\n nextTabbableNode(node, forward = true) {\n const nodeIdx = tabbableNodes.indexOf(node);\n if (nodeIdx < 0) {\n // either not tabbable nor focusable, or was focused but not tabbable (negative tabindex):\n // since `node` should at least have been focusable, we assume that's the case and mimic\n // what browsers do, which is set focus to the next node in __document position order__,\n // regardless of positive tabindexes, if any -- and for reasons explained in the NOTE\n // above related to `firstDomTabbable` and `lastDomTabbable` properties, we fall back to\n // basic DOM order\n if (forward) {\n return focusableNodes\n .slice(focusableNodes.indexOf(node) + 1)\n .find((el) => isTabbable(el));\n }\n\n return focusableNodes\n .slice(0, focusableNodes.indexOf(node))\n .reverse()\n .find((el) => isTabbable(el));\n }\n\n return tabbableNodes[nodeIdx + (forward ? 1 : -1)];\n },\n };\n });\n\n state.tabbableGroups = state.containerGroups.filter(\n (group) => group.tabbableNodes.length > 0\n );\n\n // throw if no groups have tabbable nodes and we don't have a fallback focus node either\n if (\n state.tabbableGroups.length <= 0 &&\n !getNodeForOption('fallbackFocus') // returning false not supported for this option\n ) {\n throw new Error(\n 'Your focus-trap must have at least one container with at least one tabbable node in it at all times'\n );\n }\n\n // NOTE: Positive tabindexes are only properly supported in single-container traps because\n // doing it across multiple containers where tabindexes could be all over the place\n // would require Tabbable to support multiple containers, would require additional\n // specialized Shadow DOM support, and would require Tabbable's multi-container support\n // to look at those containers in document position order rather than user-provided\n // order (as they are treated in Focus-trap, for legacy reasons). See discussion on\n // https://github.com/focus-trap/focus-trap/issues/375 for more details.\n if (\n state.containerGroups.find((g) => g.posTabIndexesFound) &&\n state.containerGroups.length > 1\n ) {\n throw new Error(\n \"At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.\"\n );\n }\n };\n\n /**\n * Gets the current activeElement. If it's a web-component and has open shadow-root\n * it will recursively search inside shadow roots for the \"true\" activeElement.\n *\n * @param {Document | ShadowRoot} el\n *\n * @returns {HTMLElement} The element that currently has the focus\n **/\n const getActiveElement = function (el) {\n const activeElement = el.activeElement;\n\n if (!activeElement) {\n return;\n }\n\n if (\n activeElement.shadowRoot &&\n activeElement.shadowRoot.activeElement !== null\n ) {\n return getActiveElement(activeElement.shadowRoot);\n }\n\n return activeElement;\n };\n\n const tryFocus = function (node) {\n if (node === false) {\n return;\n }\n\n if (node === getActiveElement(document)) {\n return;\n }\n\n if (!node || !node.focus) {\n tryFocus(getInitialFocusNode());\n return;\n }\n\n node.focus({ preventScroll: !!config.preventScroll });\n // NOTE: focus() API does not trigger focusIn event so set MRU node manually\n state.mostRecentlyFocusedNode = node;\n\n if (isSelectableInput(node)) {\n node.select();\n }\n };\n\n const getReturnFocusNode = function (previousActiveElement) {\n const node = getNodeForOption('setReturnFocus', {\n params: [previousActiveElement],\n });\n return node ? node : node === false ? false : previousActiveElement;\n };\n\n /**\n * Finds the next node (in either direction) where focus should move according to a\n * keyboard focus-in event.\n * @param {Object} params\n * @param {Node} [params.target] Known target __from which__ to navigate, if any.\n * @param {KeyboardEvent|FocusEvent} [params.event] Event to use if `target` isn't known (event\n * will be used to determine the `target`). Ignored if `target` is specified.\n * @param {boolean} [params.isBackward] True if focus should move backward.\n * @returns {Node|undefined} The next node, or `undefined` if a next node couldn't be\n * determined given the current state of the trap.\n */\n const findNextNavNode = function ({ target, event, isBackward = false }) {\n target = target || getActualTarget(event);\n updateTabbableNodes();\n\n let destinationNode = null;\n\n if (state.tabbableGroups.length > 0) {\n // make sure the target is actually contained in a group\n // NOTE: the target may also be the container itself if it's focusable\n // with tabIndex='-1' and was given initial focus\n const containerIndex = findContainerIndex(target, event);\n const containerGroup =\n containerIndex >= 0 ? state.containerGroups[containerIndex] : undefined;\n\n if (containerIndex < 0) {\n // target not found in any group: quite possible focus has escaped the trap,\n // so bring it back into...\n if (isBackward) {\n // ...the last node in the last group\n destinationNode =\n state.tabbableGroups[state.tabbableGroups.length - 1]\n .lastTabbableNode;\n } else {\n // ...the first node in the first group\n destinationNode = state.tabbableGroups[0].firstTabbableNode;\n }\n } else if (isBackward) {\n // REVERSE\n\n // is the target the first tabbable node in a group?\n let startOfGroupIndex = findIndex(\n state.tabbableGroups,\n ({ firstTabbableNode }) => target === firstTabbableNode\n );\n\n if (\n startOfGroupIndex < 0 &&\n (containerGroup.container === target ||\n (isFocusable(target, config.tabbableOptions) &&\n !isTabbable(target, config.tabbableOptions) &&\n !containerGroup.nextTabbableNode(target, false)))\n ) {\n // an exception case where the target is either the container itself, or\n // a non-tabbable node that was given focus (i.e. tabindex is negative\n // and user clicked on it or node was programmatically given focus)\n // and is not followed by any other tabbable node, in which\n // case, we should handle shift+tab as if focus were on the container's\n // first tabbable node, and go to the last tabbable node of the LAST group\n startOfGroupIndex = containerIndex;\n }\n\n if (startOfGroupIndex >= 0) {\n // YES: then shift+tab should go to the last tabbable node in the\n // previous group (and wrap around to the last tabbable node of\n // the LAST group if it's the first tabbable node of the FIRST group)\n const destinationGroupIndex =\n startOfGroupIndex === 0\n ? state.tabbableGroups.length - 1\n : startOfGroupIndex - 1;\n\n const destinationGroup = state.tabbableGroups[destinationGroupIndex];\n\n destinationNode =\n getTabIndex(target) >= 0\n ? destinationGroup.lastTabbableNode\n : destinationGroup.lastDomTabbableNode;\n } else if (!isTabEvent(event)) {\n // user must have customized the nav keys so we have to move focus manually _within_\n // the active group: do this based on the order determined by tabbable()\n destinationNode = containerGroup.nextTabbableNode(target, false);\n }\n } else {\n // FORWARD\n\n // is the target the last tabbable node in a group?\n let lastOfGroupIndex = findIndex(\n state.tabbableGroups,\n ({ lastTabbableNode }) => target === lastTabbableNode\n );\n\n if (\n lastOfGroupIndex < 0 &&\n (containerGroup.container === target ||\n (isFocusable(target, config.tabbableOptions) &&\n !isTabbable(target, config.tabbableOptions) &&\n !containerGroup.nextTabbableNode(target)))\n ) {\n // an exception case where the target is the container itself, or\n // a non-tabbable node that was given focus (i.e. tabindex is negative\n // and user clicked on it or node was programmatically given focus)\n // and is not followed by any other tabbable node, in which\n // case, we should handle tab as if focus were on the container's\n // last tabbable node, and go to the first tabbable node of the FIRST group\n lastOfGroupIndex = containerIndex;\n }\n\n if (lastOfGroupIndex >= 0) {\n // YES: then tab should go to the first tabbable node in the next\n // group (and wrap around to the first tabbable node of the FIRST\n // group if it's the last tabbable node of the LAST group)\n const destinationGroupIndex =\n lastOfGroupIndex === state.tabbableGroups.length - 1\n ? 0\n : lastOfGroupIndex + 1;\n\n const destinationGroup = state.tabbableGroups[destinationGroupIndex];\n\n destinationNode =\n getTabIndex(target) >= 0\n ? destinationGroup.firstTabbableNode\n : destinationGroup.firstDomTabbableNode;\n } else if (!isTabEvent(event)) {\n // user must have customized the nav keys so we have to move focus manually _within_\n // the active group: do this based on the order determined by tabbable()\n destinationNode = containerGroup.nextTabbableNode(target);\n }\n }\n } else {\n // no groups available\n // NOTE: the fallbackFocus option does not support returning false to opt-out\n destinationNode = getNodeForOption('fallbackFocus');\n }\n\n return destinationNode;\n };\n\n // This needs to be done on mousedown and touchstart instead of click\n // so that it precedes the focus event.\n const checkPointerDown = function (e) {\n const target = getActualTarget(e);\n\n if (findContainerIndex(target, e) >= 0) {\n // allow the click since it ocurred inside the trap\n return;\n }\n\n if (valueOrHandler(config.clickOutsideDeactivates, e)) {\n // immediately deactivate the trap\n trap.deactivate({\n // NOTE: by setting `returnFocus: false`, deactivate() will do nothing,\n // which will result in the outside click setting focus to the node\n // that was clicked (and if not focusable, to \"nothing\"); by setting\n // `returnFocus: true`, we'll attempt to re-focus the node originally-focused\n // on activation (or the configured `setReturnFocus` node), whether the\n // outside click was on a focusable node or not\n returnFocus: config.returnFocusOnDeactivate,\n });\n return;\n }\n\n // This is needed for mobile devices.\n // (If we'll only let `click` events through,\n // then on mobile they will be blocked anyways if `touchstart` is blocked.)\n if (valueOrHandler(config.allowOutsideClick, e)) {\n // allow the click outside the trap to take place\n return;\n }\n\n // otherwise, prevent the click\n e.preventDefault();\n };\n\n // In case focus escapes the trap for some strange reason, pull it back in.\n // NOTE: the focusIn event is NOT cancelable, so if focus escapes, it may cause unexpected\n // scrolling if the node that got focused was out of view; there's nothing we can do to\n // prevent that from happening by the time we discover that focus escaped\n const checkFocusIn = function (event) {\n const target = getActualTarget(event);\n const targetContained = findContainerIndex(target, event) >= 0;\n\n // In Firefox when you Tab out of an iframe the Document is briefly focused.\n if (targetContained || target instanceof Document) {\n if (targetContained) {\n state.mostRecentlyFocusedNode = target;\n }\n } else {\n // escaped! pull it back in to where it just left\n event.stopImmediatePropagation();\n\n // focus will escape if the MRU node had a positive tab index and user tried to nav forward;\n // it will also escape if the MRU node had a 0 tab index and user tried to nav backward\n // toward a node with a positive tab index\n let nextNode; // next node to focus, if we find one\n let navAcrossContainers = true;\n if (state.mostRecentlyFocusedNode) {\n if (getTabIndex(state.mostRecentlyFocusedNode) > 0) {\n // MRU container index must be >=0 otherwise we wouldn't have it as an MRU node...\n const mruContainerIdx = findContainerIndex(\n state.mostRecentlyFocusedNode\n );\n // there MAY not be any tabbable nodes in the container if there are at least 2 containers\n // and the MRU node is focusable but not tabbable (focus-trap requires at least 1 container\n // with at least one tabbable node in order to function, so this could be the other container\n // with nothing tabbable in it)\n const { tabbableNodes } = state.containerGroups[mruContainerIdx];\n if (tabbableNodes.length > 0) {\n // MRU tab index MAY not be found if the MRU node is focusable but not tabbable\n const mruTabIdx = tabbableNodes.findIndex(\n (node) => node === state.mostRecentlyFocusedNode\n );\n if (mruTabIdx >= 0) {\n if (config.isKeyForward(state.recentNavEvent)) {\n if (mruTabIdx + 1 < tabbableNodes.length) {\n nextNode = tabbableNodes[mruTabIdx + 1];\n navAcrossContainers = false;\n }\n // else, don't wrap within the container as focus should move to next/previous\n // container\n } else {\n if (mruTabIdx - 1 >= 0) {\n nextNode = tabbableNodes[mruTabIdx - 1];\n navAcrossContainers = false;\n }\n // else, don't wrap within the container as focus should move to next/previous\n // container\n }\n // else, don't find in container order without considering direction too\n }\n }\n // else, no tabbable nodes in that container (which means we must have at least one other\n // container with at least one tabbable node in it, otherwise focus-trap would've thrown\n // an error the last time updateTabbableNodes() was run): find next node among all known\n // containers\n } else {\n // check to see if there's at least one tabbable node with a positive tab index inside\n // the trap because focus seems to escape when navigating backward from a tabbable node\n // with tabindex=0 when this is the case (instead of wrapping to the tabbable node with\n // the greatest positive tab index like it should)\n if (\n !state.containerGroups.some((g) =>\n g.tabbableNodes.some((n) => getTabIndex(n) > 0)\n )\n ) {\n // no containers with tabbable nodes with positive tab indexes which means the focus\n // escaped for some other reason and we should just execute the fallback to the\n // MRU node or initial focus node, if any\n navAcrossContainers = false;\n }\n }\n } else {\n // no MRU node means we're likely in some initial condition when the trap has just\n // been activated and initial focus hasn't been given yet, in which case we should\n // fall through to trying to focus the initial focus node, which is what should\n // happen below at this point in the logic\n navAcrossContainers = false;\n }\n\n if (navAcrossContainers) {\n nextNode = findNextNavNode({\n // move FROM the MRU node, not event-related node (which will be the node that is\n // outside the trap causing the focus escape we're trying to fix)\n target: state.mostRecentlyFocusedNode,\n isBackward: config.isKeyBackward(state.recentNavEvent),\n });\n }\n\n if (nextNode) {\n tryFocus(nextNode);\n } else {\n tryFocus(state.mostRecentlyFocusedNode || getInitialFocusNode());\n }\n }\n\n state.recentNavEvent = undefined; // clear\n };\n\n // Hijack key nav events on the first and last focusable nodes of the trap,\n // in order to prevent focus from escaping. If it escapes for even a\n // moment it can end up scrolling the page and causing confusion so we\n // kind of need to capture the action at the keydown phase.\n const checkKeyNav = function (event, isBackward = false) {\n state.recentNavEvent = event;\n\n const destinationNode = findNextNavNode({ event, isBackward });\n if (destinationNode) {\n if (isTabEvent(event)) {\n // since tab natively moves focus, we wouldn't have a destination node unless we\n // were on the edge of a container and had to move to the next/previous edge, in\n // which case we want to prevent default to keep the browser from moving focus\n // to where it normally would\n event.preventDefault();\n }\n tryFocus(destinationNode);\n }\n // else, let the browser take care of [shift+]tab and move the focus\n };\n\n const checkTabKey = function (event) {\n if (config.isKeyForward(event) || config.isKeyBackward(event)) {\n checkKeyNav(event, config.isKeyBackward(event));\n }\n };\n\n // we use a different event phase for the Escape key to allow canceling the event and checking for this in escapeDeactivates\n const checkEscapeKey = function (event) {\n if (\n isEscapeEvent(event) &&\n valueOrHandler(config.escapeDeactivates, event) !== false\n ) {\n event.preventDefault();\n trap.deactivate();\n }\n };\n\n const checkClick = function (e) {\n const target = getActualTarget(e);\n\n if (findContainerIndex(target, e) >= 0) {\n return;\n }\n\n if (valueOrHandler(config.clickOutsideDeactivates, e)) {\n return;\n }\n\n if (valueOrHandler(config.allowOutsideClick, e)) {\n return;\n }\n\n e.preventDefault();\n e.stopImmediatePropagation();\n };\n\n //\n // EVENT LISTENERS\n //\n\n const addListeners = function () {\n if (!state.active) {\n return;\n }\n\n // There can be only one listening focus trap at a time\n activeFocusTraps.activateTrap(trapStack, trap);\n\n // Delay ensures that the focused element doesn't capture the event\n // that caused the focus trap activation.\n state.delayInitialFocusTimer = config.delayInitialFocus\n ? delay(function () {\n tryFocus(getInitialFocusNode());\n })\n : tryFocus(getInitialFocusNode());\n\n doc.addEventListener('focusin', checkFocusIn, true);\n doc.addEventListener('mousedown', checkPointerDown, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('touchstart', checkPointerDown, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('click', checkClick, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('keydown', checkTabKey, {\n capture: true,\n passive: false,\n });\n doc.addEventListener('keydown', checkEscapeKey);\n\n return trap;\n };\n\n const removeListeners = function () {\n if (!state.active) {\n return;\n }\n\n doc.removeEventListener('focusin', checkFocusIn, true);\n doc.removeEventListener('mousedown', checkPointerDown, true);\n doc.removeEventListener('touchstart', checkPointerDown, true);\n doc.removeEventListener('click', checkClick, true);\n doc.removeEventListener('keydown', checkTabKey, true);\n doc.removeEventListener('keydown', checkEscapeKey);\n\n return trap;\n };\n\n //\n // MUTATION OBSERVER\n //\n\n const checkDomRemoval = function (mutations) {\n const isFocusedNodeRemoved = mutations.some(function (mutation) {\n const removedNodes = Array.from(mutation.removedNodes);\n return removedNodes.some(function (node) {\n return node === state.mostRecentlyFocusedNode;\n });\n });\n\n // If the currently focused is removed then browsers will move focus to the\n // element. If this happens, try to move focus back into the trap.\n if (isFocusedNodeRemoved) {\n tryFocus(getInitialFocusNode());\n }\n };\n\n // Use MutationObserver - if supported - to detect if focused node is removed\n // from the DOM.\n const mutationObserver =\n typeof window !== 'undefined' && 'MutationObserver' in window\n ? new MutationObserver(checkDomRemoval)\n : undefined;\n\n const updateObservedNodes = function () {\n if (!mutationObserver) {\n return;\n }\n\n mutationObserver.disconnect();\n if (state.active && !state.paused) {\n state.containers.map(function (container) {\n mutationObserver.observe(container, {\n subtree: true,\n childList: true,\n });\n });\n }\n };\n\n //\n // TRAP DEFINITION\n //\n\n trap = {\n get active() {\n return state.active;\n },\n\n get paused() {\n return state.paused;\n },\n\n activate(activateOptions) {\n if (state.active) {\n return this;\n }\n\n const onActivate = getOption(activateOptions, 'onActivate');\n const onPostActivate = getOption(activateOptions, 'onPostActivate');\n const checkCanFocusTrap = getOption(activateOptions, 'checkCanFocusTrap');\n\n if (!checkCanFocusTrap) {\n updateTabbableNodes();\n }\n\n state.active = true;\n state.paused = false;\n state.nodeFocusedBeforeActivation = doc.activeElement;\n\n onActivate?.();\n\n const finishActivation = () => {\n if (checkCanFocusTrap) {\n updateTabbableNodes();\n }\n addListeners();\n updateObservedNodes();\n onPostActivate?.();\n };\n\n if (checkCanFocusTrap) {\n checkCanFocusTrap(state.containers.concat()).then(\n finishActivation,\n finishActivation\n );\n return this;\n }\n\n finishActivation();\n return this;\n },\n\n deactivate(deactivateOptions) {\n if (!state.active) {\n return this;\n }\n\n const options = {\n onDeactivate: config.onDeactivate,\n onPostDeactivate: config.onPostDeactivate,\n checkCanReturnFocus: config.checkCanReturnFocus,\n ...deactivateOptions,\n };\n\n clearTimeout(state.delayInitialFocusTimer); // noop if undefined\n state.delayInitialFocusTimer = undefined;\n\n removeListeners();\n state.active = false;\n state.paused = false;\n updateObservedNodes();\n\n activeFocusTraps.deactivateTrap(trapStack, trap);\n\n const onDeactivate = getOption(options, 'onDeactivate');\n const onPostDeactivate = getOption(options, 'onPostDeactivate');\n const checkCanReturnFocus = getOption(options, 'checkCanReturnFocus');\n const returnFocus = getOption(\n options,\n 'returnFocus',\n 'returnFocusOnDeactivate'\n );\n\n onDeactivate?.();\n\n const finishDeactivation = () => {\n delay(() => {\n if (returnFocus) {\n tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));\n }\n onPostDeactivate?.();\n });\n };\n\n if (returnFocus && checkCanReturnFocus) {\n checkCanReturnFocus(\n getReturnFocusNode(state.nodeFocusedBeforeActivation)\n ).then(finishDeactivation, finishDeactivation);\n return this;\n }\n\n finishDeactivation();\n return this;\n },\n\n pause(pauseOptions) {\n if (state.paused || !state.active) {\n return this;\n }\n\n const onPause = getOption(pauseOptions, 'onPause');\n const onPostPause = getOption(pauseOptions, 'onPostPause');\n\n state.paused = true;\n onPause?.();\n\n removeListeners();\n updateObservedNodes();\n\n onPostPause?.();\n return this;\n },\n\n unpause(unpauseOptions) {\n if (!state.paused || !state.active) {\n return this;\n }\n\n const onUnpause = getOption(unpauseOptions, 'onUnpause');\n const onPostUnpause = getOption(unpauseOptions, 'onPostUnpause');\n\n state.paused = false;\n onUnpause?.();\n\n updateTabbableNodes();\n addListeners();\n updateObservedNodes();\n\n onPostUnpause?.();\n return this;\n },\n\n updateContainerElements(containerElements) {\n const elementsAsArray = [].concat(containerElements).filter(Boolean);\n\n state.containers = elementsAsArray.map((element) =>\n typeof element === 'string' ? doc.querySelector(element) : element\n );\n\n if (state.active) {\n updateTabbableNodes();\n }\n\n updateObservedNodes();\n\n return this;\n },\n };\n\n // initialize container elements\n trap.updateContainerElements(elements);\n\n return trap;\n};\n\nexport { createFocusTrap };\n"],"names":["activeFocusTraps","trapStack","trap","length","activeTrap","pause","trapIndex","indexOf","splice","push","unpause","isTabEvent","e","key","keyCode","isKeyForward","shiftKey","isKeyBackward","delay","fn","setTimeout","findIndex","arr","idx","every","value","i","valueOrHandler","_len","arguments","params","Array","_key","apply","getActualTarget","event","target","shadowRoot","composedPath","internalTrapStack","elements","userOptions","doc","document","config","_objectSpread","returnFocusOnDeactivate","escapeDeactivates","delayInitialFocus","state","containers","containerGroups","tabbableGroups","nodeFocusedBeforeActivation","mostRecentlyFocusedNode","active","paused","delayInitialFocusTimer","undefined","recentNavEvent","getOption","configOverrideOptions","optionName","configOptionName","findContainerIndex","element","_ref","container","tabbableNodes","contains","includes","find","node","getNodeForOption","_ref2","_ref2$hasFallback","hasFallback","_ref2$params","optionValue","_toConsumableArray","Error","concat","querySelector","err","message","getInitialFocusNode","isFocusable","tabbableOptions","activeElement","firstTabbableGroup","firstTabbableNode","updateTabbableNodes","map","tabbable","focusableNodes","focusable","lastTabbableNode","firstDomTabbableNode","isTabbable","lastDomTabbableNode","slice","reverse","posTabIndexesFound","getTabIndex","nextTabbableNode","forward","nodeIdx","el","filter","group","g","getActiveElement","tryFocus","focus","preventScroll","tagName","toLowerCase","select","isSelectableInput","getReturnFocusNode","previousActiveElement","findNextNavNode","_ref3","_ref3$isBackward","isBackward","destinationNode","containerIndex","containerGroup","startOfGroupIndex","_ref4","destinationGroupIndex","destinationGroup","lastOfGroupIndex","_ref5","checkPointerDown","clickOutsideDeactivates","deactivate","returnFocus","allowOutsideClick","preventDefault","checkFocusIn","targetContained","Document","nextNode","stopImmediatePropagation","navAcrossContainers","mruContainerIdx","mruTabIdx","some","n","checkTabKey","checkKeyNav","checkEscapeKey","checkClick","addListeners","addEventListener","capture","passive","removeListeners","removeEventListener","mutationObserver","window","MutationObserver","mutations","mutation","from","removedNodes","updateObservedNodes","disconnect","observe","subtree","childList","activate","activateOptions","this","onActivate","onPostActivate","checkCanFocusTrap","finishActivation","then","deactivateOptions","options","onDeactivate","onPostDeactivate","checkCanReturnFocus","clearTimeout","finishDeactivation","pauseOptions","onPause","onPostPause","unpauseOptions","onUnpause","onPostUnpause","updateContainerElements","containerElements","elementsAsArray","Boolean"],"mappings":";;;;6kEAQA,IAAMA,WACSC,EAAWC,GACtB,GAAID,EAAUE,OAAS,EAAG,CACxB,IAAMC,EAAaH,EAAUA,EAAUE,OAAS,GAC5CC,IAAeF,GACjBE,EAAWC,OAEf,CAEA,IAAMC,EAAYL,EAAUM,QAAQL,IACjB,IAAfI,GAIFL,EAAUO,OAAOF,EAAW,GAH5BL,EAAUQ,KAAKP,EAMlB,EAjBGF,WAmBWC,EAAWC,GACxB,IAAMI,EAAYL,EAAUM,QAAQL,IACjB,IAAfI,GACFL,EAAUO,OAAOF,EAAW,GAG1BL,EAAUE,OAAS,GACrBF,EAAUA,EAAUE,OAAS,GAAGO,SAEpC,EAeIC,EAAa,SAAUC,GAC3B,MAAkB,SAAXA,eAAAA,EAAGC,MAAgC,KAAfD,aAAC,EAADA,EAAGE,QAChC,EAGMC,EAAe,SAAUH,GAC7B,OAAOD,EAAWC,KAAOA,EAAEI,QAC7B,EAGMC,EAAgB,SAAUL,GAC9B,OAAOD,EAAWC,IAAMA,EAAEI,QAC5B,EAEME,EAAQ,SAAUC,GACtB,OAAOC,WAAWD,EAAI,EACxB,EAIME,EAAY,SAAUC,EAAKH,GAC/B,IAAII,GAAO,EAWX,OATAD,EAAIE,OAAM,SAAUC,EAAOC,GACzB,OAAIP,EAAGM,KACLF,EAAMG,GACC,EAIX,IAEOH,CACT,EASMI,EAAiB,SAAUF,GAAkB,IAAAG,IAAAA,EAAAC,UAAA1B,OAAR2B,MAAMC,MAAAH,EAAAA,EAAAA,OAAAI,EAAA,EAAAA,EAAAJ,EAAAI,IAANF,EAAME,EAAAH,GAAAA,UAAAG,GAC/C,MAAwB,mBAAVP,EAAuBA,EAAKQ,WAAIH,EAAAA,GAAUL,CAC1D,EAEMS,EAAkB,SAAUC,GAQhC,OAAOA,EAAMC,OAAOC,YAA4C,mBAAvBF,EAAMG,aAC3CH,EAAMG,eAAe,GACrBH,EAAMC,MACZ,EAIMG,EAAoB,qBAEF,SAAUC,EAAUC,GAG1C,IAuDIvC,EAvDEwC,GAAMD,aAAW,EAAXA,EAAaE,WAAYA,SAE/B1C,GAAYwC,aAAW,EAAXA,EAAaxC,YAAasC,EAEtCK,EAAMC,EAAA,CACVC,yBAAyB,EACzBC,mBAAmB,EACnBC,mBAAmB,EACnBjC,aAAAA,EACAE,cAAAA,GACGwB,GAGCQ,EAAQ,CAGZC,WAAY,GAkBZC,gBAAiB,GAMjBC,eAAgB,GAEhBC,4BAA6B,KAC7BC,wBAAyB,KACzBC,QAAQ,EACRC,QAAQ,EAIRC,4BAAwBC,EAGxBC,oBAAgBD,GAaZE,EAAY,SAACC,EAAuBC,EAAYC,GACpD,OAAOF,QACiCH,IAAtCG,EAAsBC,GACpBD,EAAsBC,GACtBlB,EAAOmB,GAAoBD,EAChC,EAYKE,EAAqB,SAAUC,EAAS9B,GAC5C,IAAMG,EAC2B,mBAAxBH,eAAAA,EAAOG,cACVH,EAAMG,oBACNoB,EAIN,OAAOT,EAAME,gBAAgB9B,WAC3B,SAAA6C,GAAA,IAAGC,EAASD,EAATC,UAAWC,EAAaF,EAAbE,cAAa,OACzBD,EAAUE,SAASJ,KAKnB3B,aAAAA,EAAAA,EAAcgC,SAASH,KACvBC,EAAcG,MAAK,SAACC,GAAI,OAAKA,IAASP,IAAQ,GAEnD,EAoBKQ,EAAmB,SACvBX,GAEA,IAAAY,EAAA7C,UAAA1B,OAAA,QAAAuD,IAAA7B,UAAA,GAAAA,UAAA,GADuC,CAAE,EAAA8C,EAAAD,EAAvCE,YAAAA,OAAc,IAAHD,GAAQA,EAAAE,EAAAH,EAAE5C,OAAAA,OAAS,IAAH+C,EAAG,GAAEA,EAE9BC,EAAclC,EAAOkB,GAUzB,GAR2B,mBAAhBgB,IACTA,EAAcA,EAAW7C,aAAA8C,EAAIjD,MAGX,IAAhBgD,IACFA,OAAcpB,IAGXoB,EAAa,CAChB,QAAoBpB,IAAhBoB,IAA6C,IAAhBA,EAC/B,OAAOA,EAIT,MAAM,IAAIE,MAAK,IAAAC,OACRnB,kEAET,CAEA,IAAIU,EAAOM,EAEX,GAA2B,iBAAhBA,EAA0B,CACnC,IACEN,EAAO9B,EAAIwC,cAAcJ,EAC1B,CAAC,MAAOK,GACP,MAAM,IAAIH,MAAKC,IAAAA,OACRnB,EAAUmB,gDAAAA,OAAgDE,EAAIC,aAEvE,CAEA,IAAKZ,IACEI,EACH,MAAM,IAAII,MAAK,IAAAC,OACRnB,2CAMb,CAEA,OAAOU,CACR,EAEKa,EAAsB,WAC1B,IAAIb,EAAOC,EAAiB,eAAgB,CAAEG,aAAa,IAG3D,IAAa,IAATJ,EACF,OAAO,EAGT,QACWd,IAATc,GACCA,IAASc,EAAWA,YAACd,EAAM5B,EAAO2C,iBAGnC,GAAIvB,EAAmBtB,EAAI8C,gBAAkB,EAC3ChB,EAAO9B,EAAI8C,kBACN,CACL,IAAMC,EAAqBxC,EAAMG,eAAe,GAKhDoB,EAHEiB,GAAsBA,EAAmBC,mBAGfjB,EAAiB,gBAC/C,MACkB,OAATD,IAGTA,EAAOC,EAAiB,kBAG1B,IAAKD,EACH,MAAM,IAAIQ,MACR,gEAIJ,OAAOR,CACR,EAEKmB,EAAsB,WA4F1B,GA3FA1C,EAAME,gBAAkBF,EAAMC,WAAW0C,KAAI,SAACzB,GAC5C,IAAMC,EAAgByB,EAAQA,SAAC1B,EAAWvB,EAAO2C,iBAK3CO,EAAiBC,EAASA,UAAC5B,EAAWvB,EAAO2C,iBAE7CG,EACJtB,EAAcjE,OAAS,EAAIiE,EAAc,QAAKV,EAC1CsC,EACJ5B,EAAcjE,OAAS,EACnBiE,EAAcA,EAAcjE,OAAS,QACrCuD,EAEAuC,EAAuBH,EAAevB,MAAK,SAACC,GAAI,OACpD0B,EAAAA,WAAW1B,EAAK,IAEZ2B,EAAsBL,EACzBM,QACAC,UACA9B,MAAK,SAACC,GAAI,OAAK0B,EAAAA,WAAW1B,MAEvB8B,IAAuBlC,EAAcG,MACzC,SAACC,GAAI,OAAK+B,EAAWA,YAAC/B,GAAQ,CAAC,IAGjC,MAAO,CACLL,UAAAA,EACAC,cAAAA,EACA0B,eAAAA,EAGAQ,mBAAAA,EAGAZ,kBAAAA,EAEAM,iBAAAA,EAUAC,qBAAAA,EAEAE,oBAAAA,EAUAK,iBAAAA,SAAiBhC,GAAsB,IAAhBiC,IAAO5E,UAAA1B,OAAA,QAAAuD,IAAA7B,UAAA,KAAAA,UAAA,GACtB6E,EAAUtC,EAAc7D,QAAQiE,GACtC,OAAIkC,EAAU,EAORD,EACKX,EACJM,MAAMN,EAAevF,QAAQiE,GAAQ,GACrCD,MAAK,SAACoC,GAAE,OAAKT,EAAAA,WAAWS,MAGtBb,EACJM,MAAM,EAAGN,EAAevF,QAAQiE,IAChC6B,UACA9B,MAAK,SAACoC,GAAE,OAAKT,EAAAA,WAAWS,MAGtBvC,EAAcsC,GAAWD,EAAU,GAAK,GACjD,EAEJ,IAEAxD,EAAMG,eAAiBH,EAAME,gBAAgByD,QAC3C,SAACC,GAAK,OAAKA,EAAMzC,cAAcjE,OAAS,CAAC,IAKzC8C,EAAMG,eAAejD,QAAU,IAC9BsE,EAAiB,iBAElB,MAAM,IAAIO,MACR,uGAWJ,GACE/B,EAAME,gBAAgBoB,MAAK,SAACuC,GAAC,OAAKA,EAAER,kBAAmB,KACvDrD,EAAME,gBAAgBhD,OAAS,EAE/B,MAAM,IAAI6E,MACR,gLAGL,EAUK+B,EAAmB,SAAUJ,GACjC,IAAMnB,EAAgBmB,EAAGnB,cAEzB,GAAKA,EAIL,OACEA,EAAcnD,YAC6B,OAA3CmD,EAAcnD,WAAWmD,cAElBuB,EAAiBvB,EAAcnD,YAGjCmD,CACR,EAEKwB,EAAW,SAAUxC,IACZ,IAATA,GAIAA,IAASuC,EAAiBpE,YAIzB6B,GAASA,EAAKyC,OAKnBzC,EAAKyC,MAAM,CAAEC,gBAAiBtE,EAAOsE,gBAErCjE,EAAMK,wBAA0BkB,EA7bV,SAAUA,GAClC,OACEA,EAAK2C,SAC0B,UAA/B3C,EAAK2C,QAAQC,eACU,mBAAhB5C,EAAK6C,MAEhB,CAybQC,CAAkB9C,IACpBA,EAAK6C,UATLL,EAAS3B,KAWZ,EAEKkC,EAAqB,SAAUC,GACnC,IAAMhD,EAAOC,EAAiB,iBAAkB,CAC9C3C,OAAQ,CAAC0F,KAEX,OAAOhD,IAAuB,IAATA,GAAyBgD,CAC/C,EAaKC,EAAkB,SAAHC,GAAoD,IAArCtF,EAAMsF,EAANtF,OAAQD,EAAKuF,EAALvF,MAAKwF,EAAAD,EAAEE,WAAAA,OAAa,IAAHD,GAAQA,EACnEvF,EAASA,GAAUF,EAAgBC,GACnCwD,IAEA,IAAIkC,EAAkB,KAEtB,GAAI5E,EAAMG,eAAejD,OAAS,EAAG,CAInC,IAAM2H,EAAiB9D,EAAmB5B,EAAQD,GAC5C4F,EACJD,GAAkB,EAAI7E,EAAME,gBAAgB2E,QAAkBpE,EAEhE,GAAIoE,EAAiB,EAKjBD,EAFED,EAGA3E,EAAMG,eAAeH,EAAMG,eAAejD,OAAS,GAChD6F,iBAGa/C,EAAMG,eAAe,GAAGsC,uBAEvC,GAAIkC,EAAY,CAIrB,IAAII,EAAoB3G,EACtB4B,EAAMG,gBACN,SAAA6E,GAAA,IAAGvC,EAAiBuC,EAAjBvC,kBAAiB,OAAOtD,IAAWsD,CAAiB,IAmBzD,GAfEsC,EAAoB,IACnBD,EAAe5D,YAAc/B,GAC3BkD,cAAYlD,EAAQQ,EAAO2C,mBACzBW,EAAAA,WAAW9D,EAAQQ,EAAO2C,mBAC1BwC,EAAevB,iBAAiBpE,GAAQ,MAQ7C4F,EAAoBF,GAGlBE,GAAqB,EAAG,CAI1B,IAAME,EACkB,IAAtBF,EACI/E,EAAMG,eAAejD,OAAS,EAC9B6H,EAAoB,EAEpBG,EAAmBlF,EAAMG,eAAe8E,GAE9CL,EACEtB,EAAWA,YAACnE,IAAW,EACnB+F,EAAiBnC,iBACjBmC,EAAiBhC,mBACzB,MAAYxF,EAAWwB,KAGrB0F,EAAkBE,EAAevB,iBAAiBpE,GAAQ,GAE9D,KAAO,CAIL,IAAIgG,EAAmB/G,EACrB4B,EAAMG,gBACN,SAAAiF,GAAA,IAAGrC,EAAgBqC,EAAhBrC,iBAAgB,OAAO5D,IAAW4D,CAAgB,IAmBvD,GAfEoC,EAAmB,IAClBL,EAAe5D,YAAc/B,GAC3BkD,EAAWA,YAAClD,EAAQQ,EAAO2C,mBACzBW,aAAW9D,EAAQQ,EAAO2C,mBAC1BwC,EAAevB,iBAAiBpE,MAQrCgG,EAAmBN,GAGjBM,GAAoB,EAAG,CAIzB,IAAMF,EACJE,IAAqBnF,EAAMG,eAAejD,OAAS,EAC/C,EACAiI,EAAmB,EAEnBD,EAAmBlF,EAAMG,eAAe8E,GAE9CL,EACEtB,EAAWA,YAACnE,IAAW,EACnB+F,EAAiBzC,kBACjByC,EAAiBlC,oBACzB,MAAYtF,EAAWwB,KAGrB0F,EAAkBE,EAAevB,iBAAiBpE,GAEtD,CACF,MAGEyF,EAAkBpD,EAAiB,iBAGrC,OAAOoD,CACR,EAIKS,EAAmB,SAAU1H,GACjC,IAAMwB,EAASF,EAAgBtB,GAE3BoD,EAAmB5B,EAAQxB,IAAM,IAKjCe,EAAeiB,EAAO2F,wBAAyB3H,GAEjDV,EAAKsI,WAAW,CAOdC,YAAa7F,EAAOE,0BAQpBnB,EAAeiB,EAAO8F,kBAAmB9H,IAM7CA,EAAE+H,iBACH,EAMKC,EAAe,SAAUzG,GAC7B,IAAMC,EAASF,EAAgBC,GACzB0G,EAAkB7E,EAAmB5B,EAAQD,IAAU,EAG7D,GAAI0G,GAAmBzG,aAAkB0G,SACnCD,IACF5F,EAAMK,wBAA0BlB,OAE7B,CAOL,IAAI2G,EALJ5G,EAAM6G,2BAMN,IAAIC,GAAsB,EAC1B,GAAIhG,EAAMK,wBACR,GAAIiD,cAAYtD,EAAMK,yBAA2B,EAAG,CAElD,IAAM4F,EAAkBlF,EACtBf,EAAMK,yBAMAc,EAAkBnB,EAAME,gBAAgB+F,GAAxC9E,cACR,GAAIA,EAAcjE,OAAS,EAAG,CAE5B,IAAMgJ,EAAY/E,EAAc/C,WAC9B,SAACmD,GAAI,OAAKA,IAASvB,EAAMK,uBAAuB,IAE9C6F,GAAa,IACXvG,EAAO7B,aAAakC,EAAMU,gBACxBwF,EAAY,EAAI/E,EAAcjE,SAChC4I,EAAW3E,EAAc+E,EAAY,GACrCF,GAAsB,GAKpBE,EAAY,GAAK,IACnBJ,EAAW3E,EAAc+E,EAAY,GACrCF,GAAsB,GAO9B,CAKF,MAMKhG,EAAME,gBAAgBiG,MAAK,SAACtC,GAAC,OAC5BA,EAAE1C,cAAcgF,MAAK,SAACC,GAAC,OAAK9C,EAAWA,YAAC8C,GAAK,IAAE,MAMjDJ,GAAsB,QAQ1BA,GAAsB,EAGpBA,IACFF,EAAWtB,EAAgB,CAGzBrF,OAAQa,EAAMK,wBACdsE,WAAYhF,EAAO3B,cAAcgC,EAAMU,mBAKzCqD,EADE+B,IAGO9F,EAAMK,yBAA2B+B,KAE9C,CAEApC,EAAMU,oBAAiBD,CACxB,EAuBK4F,EAAc,SAAUnH,IACxBS,EAAO7B,aAAaoB,IAAUS,EAAO3B,cAAckB,KAlBrC,SAAUA,GAA2B,IAApByF,EAAU/F,UAAA1B,OAAA,QAAAuD,IAAA7B,UAAA,IAAAA,UAAA,GAC7CoB,EAAMU,eAAiBxB,EAEvB,IAAM0F,EAAkBJ,EAAgB,CAAEtF,MAAAA,EAAOyF,WAAAA,IAC7CC,IACElH,EAAWwB,IAKbA,EAAMwG,iBAER3B,EAASa,GAGZ,CAIG0B,CAAYpH,EAAOS,EAAO3B,cAAckB,GAE3C,EAGKqH,EAAiB,SAAUrH,GApvBb,IAAUvB,EACZ,YAAXA,OADuBA,EAsvBZuB,QArvBXvB,EAAAA,EAAGC,MAA+B,SAAXD,aAAAA,EAAAA,EAAGC,MAAgC,MAAfD,aAAAA,EAAAA,EAAGE,WAsvBG,IAApDa,EAAeiB,EAAOG,kBAAmBZ,KAEzCA,EAAMwG,iBACNzI,EAAKsI,aAER,EAEKiB,EAAa,SAAU7I,GAC3B,IAAMwB,EAASF,EAAgBtB,GAE3BoD,EAAmB5B,EAAQxB,IAAM,GAIjCe,EAAeiB,EAAO2F,wBAAyB3H,IAI/Ce,EAAeiB,EAAO8F,kBAAmB9H,KAI7CA,EAAE+H,iBACF/H,EAAEoI,2BACH,EAMKU,EAAe,WACnB,GAAKzG,EAAMM,OAkCX,OA7BAvD,EAA8BC,EAAWC,GAIzC+C,EAAMQ,uBAAyBb,EAAOI,kBAClC9B,GAAM,WACJ8F,EAAS3B,IACX,IACA2B,EAAS3B,KAEb3C,EAAIiH,iBAAiB,UAAWf,GAAc,GAC9ClG,EAAIiH,iBAAiB,YAAarB,EAAkB,CAClDsB,SAAS,EACTC,SAAS,IAEXnH,EAAIiH,iBAAiB,aAAcrB,EAAkB,CACnDsB,SAAS,EACTC,SAAS,IAEXnH,EAAIiH,iBAAiB,QAASF,EAAY,CACxCG,SAAS,EACTC,SAAS,IAEXnH,EAAIiH,iBAAiB,UAAWL,EAAa,CAC3CM,SAAS,EACTC,SAAS,IAEXnH,EAAIiH,iBAAiB,UAAWH,GAEzBtJ,CACR,EAEK4J,EAAkB,WACtB,GAAK7G,EAAMM,OAWX,OAPAb,EAAIqH,oBAAoB,UAAWnB,GAAc,GACjDlG,EAAIqH,oBAAoB,YAAazB,GAAkB,GACvD5F,EAAIqH,oBAAoB,aAAczB,GAAkB,GACxD5F,EAAIqH,oBAAoB,QAASN,GAAY,GAC7C/G,EAAIqH,oBAAoB,UAAWT,GAAa,GAChD5G,EAAIqH,oBAAoB,UAAWP,GAE5BtJ,CACR,EAuBK8J,EACc,oBAAXC,QAA0B,qBAAsBA,OACnD,IAAIC,kBAnBc,SAAUC,GACHA,EAAUf,MAAK,SAAUgB,GAEpD,OADqBrI,MAAMsI,KAAKD,EAASE,cACrBlB,MAAK,SAAU5E,GACjC,OAAOA,IAASvB,EAAMK,uBACxB,GACF,KAKE0D,EAAS3B,IAEZ,SAOK3B,EAEA6G,EAAsB,WACrBP,IAILA,EAAiBQ,aACbvH,EAAMM,SAAWN,EAAMO,QACzBP,EAAMC,WAAW0C,KAAI,SAAUzB,GAC7B6F,EAAiBS,QAAQtG,EAAW,CAClCuG,SAAS,EACTC,WAAW,GAEf,IAEH,EAqKD,OA/JAzK,EAAO,CACL,UAAIqD,GACF,OAAON,EAAMM,MACd,EAED,UAAIC,GACF,OAAOP,EAAMO,MACd,EAEDoH,SAAAA,SAASC,GACP,GAAI5H,EAAMM,OACR,OAAOuH,KAGT,IAAMC,EAAanH,EAAUiH,EAAiB,cACxCG,EAAiBpH,EAAUiH,EAAiB,kBAC5CI,EAAoBrH,EAAUiH,EAAiB,qBAEhDI,GACHtF,IAGF1C,EAAMM,QAAS,EACfN,EAAMO,QAAS,EACfP,EAAMI,4BAA8BX,EAAI8C,cAExCuF,SAAAA,IAEA,IAAMG,EAAmB,WACnBD,GACFtF,IAEF+D,IACAa,IACAS,SAAAA,GACD,EAED,OAAIC,GACFA,EAAkBhI,EAAMC,WAAW+B,UAAUkG,KAC3CD,EACAA,GAEKJ,OAGTI,IACOJ,KACR,EAEDtC,WAAAA,SAAW4C,GACT,IAAKnI,EAAMM,OACT,OAAOuH,KAGT,IAAMO,EAAOxI,EAAA,CACXyI,aAAc1I,EAAO0I,aACrBC,iBAAkB3I,EAAO2I,iBACzBC,oBAAqB5I,EAAO4I,qBACzBJ,GAGLK,aAAaxI,EAAMQ,wBACnBR,EAAMQ,4BAAyBC,EAE/BoG,IACA7G,EAAMM,QAAS,EACfN,EAAMO,QAAS,EACf+G,IAEAvK,EAAgCC,EAAWC,GAE3C,IAAMoL,EAAe1H,EAAUyH,EAAS,gBAClCE,EAAmB3H,EAAUyH,EAAS,oBACtCG,EAAsB5H,EAAUyH,EAAS,uBACzC5C,EAAc7E,EAClByH,EACA,cACA,2BAGFC,SAAAA,IAEA,IAAMI,EAAqB,WACzBxK,GAAM,WACAuH,GACFzB,EAASO,EAAmBtE,EAAMI,8BAEpCkI,SAAAA,GACF,GACD,EAED,OAAI9C,GAAe+C,GACjBA,EACEjE,EAAmBtE,EAAMI,8BACzB8H,KAAKO,EAAoBA,GACpBZ,OAGTY,IACOZ,KACR,EAEDzK,MAAAA,SAAMsL,GACJ,GAAI1I,EAAMO,SAAWP,EAAMM,OACzB,OAAOuH,KAGT,IAAMc,EAAUhI,EAAU+H,EAAc,WAClCE,EAAcjI,EAAU+H,EAAc,eAS5C,OAPA1I,EAAMO,QAAS,EACfoI,SAAAA,IAEA9B,IACAS,IAEAsB,SAAAA,IACOf,IACR,EAEDpK,QAAAA,SAAQoL,GACN,IAAK7I,EAAMO,SAAWP,EAAMM,OAC1B,OAAOuH,KAGT,IAAMiB,EAAYnI,EAAUkI,EAAgB,aACtCE,EAAgBpI,EAAUkI,EAAgB,iBAUhD,OARA7I,EAAMO,QAAS,EACfuI,SAAAA,IAEApG,IACA+D,IACAa,IAEAyB,SAAAA,IACOlB,IACR,EAEDmB,wBAAAA,SAAwBC,GACtB,IAAMC,EAAkB,GAAGlH,OAAOiH,GAAmBtF,OAAOwF,SAY5D,OAVAnJ,EAAMC,WAAaiJ,EAAgBvG,KAAI,SAAC3B,GAAO,MAC1B,iBAAZA,EAAuBvB,EAAIwC,cAAcjB,GAAWA,CAAO,IAGhEhB,EAAMM,QACRoC,IAGF4E,IAEOO,IACT,IAIGmB,wBAAwBzJ,GAEtBtC,CACT"} \ No newline at end of file