Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03.1k
1// NOTE: separate `:not()` selectors has broader browser support than the newer2// `:not([inert], [inert] *)` (Feb 2023)3const candidateSelectors = [4 'input:not([inert]):not([inert] *)',5 'select:not([inert]):not([inert] *)',6 'textarea:not([inert]):not([inert] *)',7 'a[href]:not([inert]):not([inert] *)',8 'button:not([inert]):not([inert] *)',9 '[tabindex]:not(slot):not([inert]):not([inert] *)',10 'audio[controls]:not([inert]):not([inert] *)',11 'video[controls]:not([inert]):not([inert] *)',12 '[contenteditable]:not([contenteditable="false"]):not([inert]):not([inert] *)',13 'details>summary:first-of-type:not([inert]):not([inert] *)',14 'details:not([inert]):not([inert] *)',15];16const candidateSelector = /* #__PURE__ */ candidateSelectors.join(',');17 18const NoElement = typeof Element === 'undefined';19 20const matches = NoElement21 ? function () {}22 : Element.prototype.matches ||23 Element.prototype.msMatchesSelector ||24 Element.prototype.webkitMatchesSelector;25 26const getRootNode =27 !NoElement && Element.prototype.getRootNode28 ? (element) => element?.getRootNode?.()29 : (element) => element?.ownerDocument;30 31/**32 * Determines if a node is inert or in an inert ancestor.33 * @param {Node} [node]34 * @param {boolean} [lookUp] If true and `node` is not inert, looks up at ancestors to35 * see if any of them are inert. If false, only `node` itself is considered.36 * @returns {boolean} True if inert itself or by way of being in an inert ancestor.37 * False if `node` is falsy.38 */39const isInert = function (node, lookUp = true) {40 // CAREFUL: JSDom does not support inert at all, so we can't use the `HTMLElement.inert`41 // JS API property; we have to check the attribute, which can either be empty or 'true';42 // if it's `null` (not specified) or 'false', it's an active element43 const inertAtt = node?.getAttribute?.('inert');44 const inert = inertAtt === '' || inertAtt === 'true';45 46 // NOTE: this could also be handled with `node.matches('[inert], :is([inert] *)')`47 // if it weren't for `matches()` not being a function on shadow roots; the following48 // code works for any kind of node49 const result =50 inert ||51 (lookUp &&52 node &&53 // closest does not exist on shadow roots, so we fall back to a manual54 // lookup upward, in case it is not defined.55 (typeof node.closest === 'function'56 ? node.closest('[inert]')57 : isInert(node.parentNode)));58 59 return result;60};61 62/**63 * Determines if a node's content is editable.64 * @param {Element} [node]65 * @returns True if it's content-editable; false if it's not or `node` is falsy.66 */67const isContentEditable = function (node) {68 // CAREFUL: JSDom does not support the `HTMLElement.isContentEditable` API so we have69 // to use the attribute directly to check for this, which can either be empty or 'true';70 // if it's `null` (not specified) or 'false', it's a non-editable element71 const attValue = node?.getAttribute?.('contenteditable');72 return attValue === '' || attValue === 'true';73};74 75/**76 * @param {Element} el container to check in77 * @param {boolean} includeContainer add container to check78 * @param {(node: Element) => boolean} filter filter candidates79 * @returns {Element[]}80 */81const getCandidates = function (el, includeContainer, filter) {82 // even if `includeContainer=false`, we still have to check it for inertness because83 // if it's inert (either by itself or via its parent), then all its children are inert84 if (isInert(el)) {85 return [];86 }87 88 let candidates = Array.prototype.slice.apply(89 el.querySelectorAll(candidateSelector)90 );91 if (includeContainer && matches.call(el, candidateSelector)) {92 candidates.unshift(el);93 }94 candidates = candidates.filter(filter);95 return candidates;96};97 98/**99 * @callback GetShadowRoot100 * @param {Element} element to check for shadow root101 * @returns {ShadowRoot|boolean} ShadowRoot if available or boolean indicating if a shadowRoot is attached but not available.102 */103 104/**105 * @callback ShadowRootFilter106 * @param {Element} shadowHostNode the element which contains shadow content107 * @returns {boolean} true if a shadow root could potentially contain valid candidates.108 */109 110/**111 * @typedef {Object} CandidateScope112 * @property {Element} scopeParent contains inner candidates113 * @property {Element[]} candidates list of candidates found in the scope parent114 */115 116/**117 * @typedef {Object} IterativeOptions118 * @property {GetShadowRoot|boolean} getShadowRoot true if shadow support is enabled; falsy if not;119 * if a function, implies shadow support is enabled and either returns the shadow root of an element120 * or a boolean stating if it has an undisclosed shadow root121 * @property {(node: Element) => boolean} filter filter candidates122 * @property {boolean} flatten if true then result will flatten any CandidateScope into the returned list123 * @property {ShadowRootFilter} shadowRootFilter filter shadow roots;124 */125 126/**127 * @param {Element[]} elements list of element containers to match candidates from128 * @param {boolean} includeContainer add container list to check129 * @param {IterativeOptions} options130 * @returns {Array.<Element|CandidateScope>}131 */132const getCandidatesIteratively = function (133 elements,134 includeContainer,135 options136) {137 const candidates = [];138 const elementsToCheck = Array.from(elements);139 while (elementsToCheck.length) {140 const element = elementsToCheck.shift();141 if (isInert(element, false)) {142 // no need to look up since we're drilling down143 // anything inside this container will also be inert144 continue;145 }146 147 if (element.tagName === 'SLOT') {148 // add shadow dom slot scope (slot itself cannot be focusable)149 const assigned = element.assignedElements();150 const content = assigned.length ? assigned : element.children;151 const nestedCandidates = getCandidatesIteratively(content, true, options);152 if (options.flatten) {153 candidates.push(...nestedCandidates);154 } else {155 candidates.push({156 scopeParent: element,157 candidates: nestedCandidates,158 });159 }160 } else {161 // check candidate element162 const validCandidate = matches.call(element, candidateSelector);163 if (164 validCandidate &&165 options.filter(element) &&166 (includeContainer || !elements.includes(element))167 ) {168 candidates.push(element);169 }170 171 // iterate over shadow content if possible172 const shadowRoot =173 element.shadowRoot ||174 // check for an undisclosed shadow175 (typeof options.getShadowRoot === 'function' &&176 options.getShadowRoot(element));177 178 // no inert look up because we're already drilling down and checking for inertness179 // on the way down, so all containers to this root node should have already been180 // vetted as non-inert181 const validShadowRoot =182 !isInert(shadowRoot, false) &&183 (!options.shadowRootFilter || options.shadowRootFilter(element));184 185 if (shadowRoot && validShadowRoot) {186 // add shadow dom scope IIF a shadow root node was given; otherwise, an undisclosed187 // shadow exists, so look at light dom children as fallback BUT create a scope for any188 // child candidates found because they're likely slotted elements (elements that are189 // children of the web component element (which has the shadow), in the light dom, but190 // slotted somewhere _inside_ the undisclosed shadow) -- the scope is created below,191 // _after_ we return from this recursive call192 const nestedCandidates = getCandidatesIteratively(193 shadowRoot === true ? element.children : shadowRoot.children,194 true,195 options196 );197 198 if (options.flatten) {199 candidates.push(...nestedCandidates);200 } else {201 candidates.push({202 scopeParent: element,203 candidates: nestedCandidates,204 });205 }206 } else {207 // there's not shadow so just dig into the element's (light dom) children208 // __without__ giving the element special scope treatment209 elementsToCheck.unshift(...element.children);210 }211 }212 }213 return candidates;214};215 216/**217 * @private218 * Determines if the node has an explicitly specified `tabindex` attribute.219 * @param {HTMLElement} node220 * @returns {boolean} True if so; false if not.221 */222const hasTabIndex = function (node) {223 return !isNaN(parseInt(node.getAttribute('tabindex'), 10));224};225 226/**227 * Determine the tab index of a given node.228 * @param {HTMLElement} node229 * @returns {number} Tab order (negative, 0, or positive number).230 * @throws {Error} If `node` is falsy.231 */232const getTabIndex = function (node) {233 if (!node) {234 throw new Error('No node provided');235 }236 237 if (node.tabIndex < 0) {238 // in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default239 // `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,240 // yet they are still part of the regular tab order; in FF, they get a default241 // `tabIndex` of 0; since Chrome still puts those elements in the regular tab242 // order, consider their tab index to be 0.243 // Also browsers do not return `tabIndex` correctly for contentEditable nodes;244 // so if they don't have a tabindex attribute specifically set, assume it's 0.245 if (246 (/^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) ||247 isContentEditable(node)) &&248 !hasTabIndex(node)249 ) {250 return 0;251 }252 }253 254 return node.tabIndex;255};256 257/**258 * Determine the tab index of a given node __for sort order purposes__.259 * @param {HTMLElement} node260 * @param {boolean} [isScope] True for a custom element with shadow root or slot that, by default,261 * has tabIndex -1, but needs to be sorted by document order in order for its content to be262 * inserted into the correct sort position.263 * @returns {number} Tab order (negative, 0, or positive number).264 */265const getSortOrderTabIndex = function (node, isScope) {266 const tabIndex = getTabIndex(node);267 268 if (tabIndex < 0 && isScope && !hasTabIndex(node)) {269 return 0;270 }271 272 return tabIndex;273};274 275const sortOrderedTabbables = function (a, b) {276 return a.tabIndex === b.tabIndex277 ? a.documentOrder - b.documentOrder278 : a.tabIndex - b.tabIndex;279};280 281const isInput = function (node) {282 return node.tagName === 'INPUT';283};284 285const isHiddenInput = function (node) {286 return isInput(node) && node.type === 'hidden';287};288 289const isDetailsWithSummary = function (node) {290 const r =291 node.tagName === 'DETAILS' &&292 Array.prototype.slice293 .apply(node.children)294 .some((child) => child.tagName === 'SUMMARY');295 return r;296};297 298const getCheckedRadio = function (nodes, form) {299 for (let i = 0; i < nodes.length; i++) {300 if (nodes[i].checked && nodes[i].form === form) {301 return nodes[i];302 }303 }304};305 306const isTabbableRadio = function (node) {307 if (!node.name) {308 return true;309 }310 const radioScope = node.form || getRootNode(node);311 const queryRadios = function (name) {312 return radioScope.querySelectorAll(313 'input[type="radio"][name="' + name + '"]'314 );315 };316 317 let radioSet;318 if (319 typeof window !== 'undefined' &&320 typeof window.CSS !== 'undefined' &&321 typeof window.CSS.escape === 'function'322 ) {323 radioSet = queryRadios(window.CSS.escape(node.name));324 } else {325 try {326 radioSet = queryRadios(node.name);327 } catch (err) {328 // eslint-disable-next-line no-console329 console.error(330 'Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s',331 err.message332 );333 return false;334 }335 }336 337 const checked = getCheckedRadio(radioSet, node.form);338 return !checked || checked === node;339};340 341const isRadio = function (node) {342 return isInput(node) && node.type === 'radio';343};344 345const isNonTabbableRadio = function (node) {346 return isRadio(node) && !isTabbableRadio(node);347};348 349// determines if a node is ultimately attached to the window's document350const isNodeAttached = function (node) {351 // The root node is the shadow root if the node is in a shadow DOM; some document otherwise352 // (but NOT _the_ document; see second 'If' comment below for more).353 // If rootNode is shadow root, it'll have a host, which is the element to which the shadow354 // is attached, and the one we need to check if it's in the document or not (because the355 // shadow, and all nodes it contains, is never considered in the document since shadows356 // behave like self-contained DOMs; but if the shadow's HOST, which is part of the document,357 // is hidden, or is not in the document itself but is detached, it will affect the shadow's358 // visibility, including all the nodes it contains). The host could be any normal node,359 // or a custom element (i.e. web component). Either way, that's the one that is considered360 // part of the document, not the shadow root, nor any of its children (i.e. the node being361 // tested).362 // To further complicate things, we have to look all the way up until we find a shadow HOST363 // that is attached (or find none) because the node might be in nested shadows...364 // If rootNode is not a shadow root, it won't have a host, and so rootNode should be the365 // document (per the docs) and while it's a Document-type object, that document does not366 // appear to be the same as the node's `ownerDocument` for some reason, so it's safer367 // to ignore the rootNode at this point, and use `node.ownerDocument`. Otherwise,368 // using `rootNode.contains(node)` will _always_ be true we'll get false-positives when369 // node is actually detached.370 // NOTE: If `nodeRootHost` or `node` happens to be the `document` itself (which is possible371 // if a tabbable/focusable node was quickly added to the DOM, focused, and then removed372 // from the DOM as in https://github.com/focus-trap/focus-trap-react/issues/905), then373 // `ownerDocument` will be `null`, hence the optional chaining on it.374 let nodeRoot = node && getRootNode(node);375 let nodeRootHost = nodeRoot?.host;376 377 // in some cases, a detached node will return itself as the root instead of a document or378 // shadow root object, in which case, we shouldn't try to look further up the host chain379 let attached = false;380 if (nodeRoot && nodeRoot !== node) {381 attached = !!(382 nodeRootHost?.ownerDocument?.contains(nodeRootHost) ||383 node?.ownerDocument?.contains(node)384 );385 386 while (!attached && nodeRootHost) {387 // since it's not attached and we have a root host, the node MUST be in a nested shadow DOM,388 // which means we need to get the host's host and check if that parent host is contained389 // in (i.e. attached to) the document390 nodeRoot = getRootNode(nodeRootHost);391 nodeRootHost = nodeRoot?.host;392 attached = !!nodeRootHost?.ownerDocument?.contains(nodeRootHost);393 }394 }395 396 return attached;397};398 399const isZeroArea = function (node) {400 const { width, height } = node.getBoundingClientRect();401 return width === 0 && height === 0;402};403const isHidden = function (node, { displayCheck, getShadowRoot }) {404 if (displayCheck === 'full-native') {405 if ('checkVisibility' in node) {406 // Chrome >= 105, Edge >= 105, Firefox >= 106, Safari >= 17.4407 // @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility#browser_compatibility408 const visible = node.checkVisibility({409 // Checking opacity might be desirable for some use cases, but natively,410 // opacity zero elements _are_ focusable and tabbable.411 checkOpacity: false,412 opacityProperty: false,413 414 contentVisibilityAuto: true,415 visibilityProperty: true,416 // This is an alias for `visibilityProperty`. Contemporary browsers417 // support both. However, this alias has wider browser support (Chrome418 // >= 105 and Firefox >= 106, vs. Chrome >= 121 and Firefox >= 122), so419 // we include it anyway.420 checkVisibilityCSS: true,421 });422 return !visible;423 }424 // Fall through to manual visibility checks425 }426 427 // NOTE: visibility will be `undefined` if node is detached from the document428 // (see notes about this further down), which means we will consider it visible429 // (this is legacy behavior from a very long way back)430 // NOTE: we check this regardless of `displayCheck="none"` because this is a431 // _visibility_ check, not a _display_ check432 if (getComputedStyle(node).visibility === 'hidden') {433 return true;434 }435 436 const isDirectSummary = matches.call(node, 'details>summary:first-of-type');437 const nodeUnderDetails = isDirectSummary ? node.parentElement : node;438 if (matches.call(nodeUnderDetails, 'details:not([open]) *')) {439 return true;440 }441 442 if (443 !displayCheck ||444 displayCheck === 'full' ||445 // full-native can run this branch when it falls through in case446 // Element#checkVisibility is unsupported447 displayCheck === 'full-native' ||448 displayCheck === 'legacy-full'449 ) {450 if (typeof getShadowRoot === 'function') {451 // figure out if we should consider the node to be in an undisclosed shadow and use the452 // 'non-zero-area' fallback453 const originalNode = node;454 while (node) {455 const parentElement = node.parentElement;456 const rootNode = getRootNode(node);457 if (458 parentElement &&459 !parentElement.shadowRoot &&460 getShadowRoot(parentElement) === true // check if there's an undisclosed shadow461 ) {462 // node has an undisclosed shadow which means we can only treat it as a black box, so we463 // fall back to a non-zero-area test464 return isZeroArea(node);465 } else if (node.assignedSlot) {466 // iterate up slot467 node = node.assignedSlot;468 } else if (!parentElement && rootNode !== node.ownerDocument) {469 // cross shadow boundary470 node = rootNode.host;471 } else {472 // iterate up normal dom473 node = parentElement;474 }475 }476 477 node = originalNode;478 }479 // else, `getShadowRoot` might be true, but all that does is enable shadow DOM support480 // (i.e. it does not also presume that all nodes might have undisclosed shadows); or481 // it might be a falsy value, which means shadow DOM support is disabled482 483 // Since we didn't find it sitting in an undisclosed shadow (or shadows are disabled)484 // now we can just test to see if it would normally be visible or not, provided it's485 // attached to the main document.486 // NOTE: We must consider case where node is inside a shadow DOM and given directly to487 // `isTabbable()` or `isFocusable()` -- regardless of `getShadowRoot` option setting.488 489 if (isNodeAttached(node)) {490 // this works wherever the node is: if there's at least one client rect, it's491 // somehow displayed; it also covers the CSS 'display: contents' case where the492 // node itself is hidden in place of its contents; and there's no need to search493 // up the hierarchy either494 return !node.getClientRects().length;495 }496 497 // Else, the node isn't attached to the document, which means the `getClientRects()`498 // API will __always__ return zero rects (this can happen, for example, if React499 // is used to render nodes onto a detached tree, as confirmed in this thread:500 // https://github.com/facebook/react/issues/9117#issuecomment-284228870)501 //502 // It also means that even window.getComputedStyle(node).display will return `undefined`503 // because styles are only computed for nodes that are in the document.504 //505 // NOTE: THIS HAS BEEN THE CASE FOR YEARS. It is not new, nor is it caused by tabbable506 // somehow. Though it was never stated officially, anyone who has ever used tabbable507 // APIs on nodes in detached containers has actually implicitly used tabbable in what508 // was later (as of v5.2.0 on Apr 9, 2021) called `displayCheck="none"` mode -- essentially509 // considering __everything__ to be visible because of the innability to determine styles.510 //511 // v6.0.0: As of this major release, the default 'full' option __no longer treats detached512 // nodes as visible with the 'none' fallback.__513 if (displayCheck !== 'legacy-full') {514 return true; // hidden515 }516 // else, fallback to 'none' mode and consider the node visible517 } else if (displayCheck === 'non-zero-area') {518 // NOTE: Even though this tests that the node's client rect is non-zero to determine519 // whether it's displayed, and that a detached node will __always__ have a zero-area520 // client rect, we don't special-case for whether the node is attached or not. In521 // this mode, we do want to consider nodes that have a zero area to be hidden at all522 // times, and that includes attached or not.523 return isZeroArea(node);524 }525 526 // visible, as far as we can tell, or per current `displayCheck=none` mode, we assume527 // it's visible528 return false;529};530 531// form fields (nested) inside a disabled fieldset are not focusable/tabbable532// unless they are in the _first_ <legend> element of the top-most disabled533// fieldset534const isDisabledFromFieldset = function (node) {535 if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {536 let parentNode = node.parentElement;537 // check if `node` is contained in a disabled <fieldset>538 while (parentNode) {539 if (parentNode.tagName === 'FIELDSET' && parentNode.disabled) {540 // look for the first <legend> among the children of the disabled <fieldset>541 for (let i = 0; i < parentNode.children.length; i++) {542 const child = parentNode.children.item(i);543 // when the first <legend> (in document order) is found544 if (child.tagName === 'LEGEND') {545 // if its parent <fieldset> is not nested in another disabled <fieldset>,546 // return whether `node` is a descendant of its first <legend>547 return matches.call(parentNode, 'fieldset[disabled] *')548 ? true549 : !child.contains(node);550 }551 }552 // the disabled <fieldset> containing `node` has no <legend>553 return true;554 }555 parentNode = parentNode.parentElement;556 }557 }558 559 // else, node's tabbable/focusable state should not be affected by a fieldset's560 // enabled/disabled state561 return false;562};563 564const isNodeMatchingSelectorFocusable = function (options, node) {565 if (566 node.disabled ||567 isHiddenInput(node) ||568 isHidden(node, options) ||569 // For a details element with a summary, the summary element gets the focus570 isDetailsWithSummary(node) ||571 isDisabledFromFieldset(node)572 ) {573 return false;574 }575 return true;576};577 578const isNodeMatchingSelectorTabbable = function (options, node) {579 if (580 isNonTabbableRadio(node) ||581 getTabIndex(node) < 0 ||582 !isNodeMatchingSelectorFocusable(options, node)583 ) {584 return false;585 }586 return true;587};588 589const isShadowRootTabbable = function (shadowHostNode) {590 const tabIndex = parseInt(shadowHostNode.getAttribute('tabindex'), 10);591 if (isNaN(tabIndex) || tabIndex >= 0) {592 return true;593 }594 // If a custom element has an explicit negative tabindex,595 // browsers will not allow tab targeting said element's children.596 return false;597};598 599/**600 * @param {Array.<Element|CandidateScope>} candidates601 * @returns Element[]602 */603const sortByOrder = function (candidates) {604 const regularTabbables = [];605 const orderedTabbables = [];606 candidates.forEach(function (item, i) {607 const isScope = !!item.scopeParent;608 const element = isScope ? item.scopeParent : item;609 const candidateTabindex = getSortOrderTabIndex(element, isScope);610 const elements = isScope ? sortByOrder(item.candidates) : element;611 if (candidateTabindex === 0) {612 isScope613 ? regularTabbables.push(...elements)614 : regularTabbables.push(element);615 } else {616 orderedTabbables.push({617 documentOrder: i,618 tabIndex: candidateTabindex,619 item: item,620 isScope: isScope,621 content: elements,622 });623 }624 });625 626 return orderedTabbables627 .sort(sortOrderedTabbables)628 .reduce((acc, sortable) => {629 sortable.isScope630 ? acc.push(...sortable.content)631 : acc.push(sortable.content);632 return acc;633 }, [])634 .concat(regularTabbables);635};636 637const tabbable = function (container, options) {638 options = options || {};639 640 let candidates;641 if (options.getShadowRoot) {642 candidates = getCandidatesIteratively(643 [container],644 options.includeContainer,645 {646 filter: isNodeMatchingSelectorTabbable.bind(null, options),647 flatten: false,648 getShadowRoot: options.getShadowRoot,649 shadowRootFilter: isShadowRootTabbable,650 }651 );652 } else {653 candidates = getCandidates(654 container,655 options.includeContainer,656 isNodeMatchingSelectorTabbable.bind(null, options)657 );658 }659 return sortByOrder(candidates);660};661 662const focusable = function (container, options) {663 options = options || {};664 665 let candidates;666 if (options.getShadowRoot) {667 candidates = getCandidatesIteratively(668 [container],669 options.includeContainer,670 {671 filter: isNodeMatchingSelectorFocusable.bind(null, options),672 flatten: true,673 getShadowRoot: options.getShadowRoot,674 }675 );676 } else {677 candidates = getCandidates(678 container,679 options.includeContainer,680 isNodeMatchingSelectorFocusable.bind(null, options)681 );682 }683 684 return candidates;685};686 687const isTabbable = function (node, options) {688 options = options || {};689 if (!node) {690 throw new Error('No node provided');691 }692 if (matches.call(node, candidateSelector) === false) {693 return false;694 }695 return isNodeMatchingSelectorTabbable(options, node);696};697 698const focusableCandidateSelector = /* #__PURE__ */ candidateSelectors699 .concat('iframe:not([inert]):not([inert] *)')700 .join(',');701 702const isFocusable = function (node, options) {703 options = options || {};704 if (!node) {705 throw new Error('No node provided');706 }707 if (matches.call(node, focusableCandidateSelector) === false) {708 return false;709 }710 return isNodeMatchingSelectorFocusable(options, node);711};712 713export { tabbable, focusable, isTabbable, isFocusable, getTabIndex };714 