/* /web/static/lib/hoot-dom/helpers/dom.js */ odoo.define('@web/../lib/hoot-dom/helpers/dom',['@web/../lib/hoot-dom/hoot_dom_utils','@web/../lib/hoot-dom/helpers/time'],function(require){'use strict';let __exports={};const{getTag,isFirefox,isInstanceOf,isIterable,parseRegExp}=require("@web/../lib/hoot-dom/hoot_dom_utils");const{waitUntil}=require("@web/../lib/hoot-dom/helpers/time");const{document,DOMParser,Error,innerWidth,innerHeight,Map,Number:{isInteger:$isInteger,isNaN:$isNaN,parseInt:$parseInt,parseFloat:$parseFloat},Object:{entries:$entries,keys:$keys,values:$values},RegExp,String:{raw:$raw},window,}=globalThis;function applyFilters(filters,nodes){for(const filter of filters){const filteredGroupNodes=[];for(let i=0;ik!=="has"&&k!=="not");return new RegExp(`:(${customKeys.join("|")})`);} function elementsMatch(elements,selector){if(!elements.length){return false;} return parseSelector(selector).some((selectorParts)=>{const[baseSelector,...filters]=selectorParts.at(-1);for(let i=0;imatchFilter(filter,elements,i))){return false;}} return true;});} function ensureCount(options){options={...options};if(!("eq"in options||"first"in options||"last"in options)){options.first=true;} return options;} function ensureElement(node){if(node){if(isDocument(node)){return node.documentElement;} if(isWindow(node)){return node.document.documentElement;} if(isElement(node)){return node;}} return null;} function extractLayers(nodes,level,keepInlineTextNodes){const layers=[];for(const node of nodes){if(node.nodeType===Node.COMMENT_NODE){continue;} if(node.nodeType===Node.TEXT_NODE){const textContent=node.nodeValue.replaceAll(/\n/g,"");const trimmedTextContent=textContent.trim();if(trimmedTextContent){const inline=textContent===trimmedTextContent;layers.push({inline,level,value:{textContent:trimmedTextContent}});} continue;} const[open,close]=node.outerHTML.replace(`>${node.innerHTML}<`,">\n<").split("\n");const layer={inline:false,level,value:{open,close}};layers.push(layer);const childLayers=extractLayers(node.childNodes,level+1,false);if(keepInlineTextNodes&&childLayers.length===1&&childLayers[0].inline){layer.value.textContent=childLayers[0].value.textContent;}else{layers.push(...childLayers);}} return layers;} function filterUniqueNodes(nodesToFilter){const nodes=[];for(const node of nodesToFilter){if(isQueryableNode(node)&&!nodes.includes(node)){nodes.push(node);}} return nodes;} function generateStringFromLayers(layers,tabSize){const result=[];let layerIndex=0;while(layers.length>0){const layer=layers[layerIndex];const{level,value}=layer;const pad=" ".repeat(tabSize*level);let nextLayerIndex=layerIndex+1;if(value.open){if(value.textContent){result.push(`${pad}${value.open}${value.textContent}${value.close}`);layers.splice(layerIndex,1);nextLayerIndex--;}else{result.push(`${pad}${value.open}`);delete value.open;}}else{if(value.close){result.push(`${pad}${value.close}`);}else if(value.textContent){result.push(`${pad}${value.textContent}`);} layers.splice(layerIndex,1);nextLayerIndex--;} if(nextLayerIndex>=layers.length){layerIndex=nextLayerIndex-1;continue;} const nextLayer=layers[nextLayerIndex];if(nextLayerIndex===0||nextLayer.level>layers[nextLayerIndex-1].level){layerIndex=nextLayerIndex;}else{layerIndex=nextLayerIndex-1;}} return result.join("\n");} function getFiltersDescription(modifierInfo){const description=[];for(const[modifier,content,count=0]of modifierInfo){const makeLabel=MODIFIER_SUFFIX_LABELS[modifier];const elements=plural("element",count);if(typeof makeLabel==="function"){description.push(`${count} ${elements} ${makeLabel(content)}`);}else{description.push(`${count} ${modifier} ${elements}`);} if(!count){break;}} return description;} function getInlineNodeText(node){return getNodeText(node,{inline:true});} function getNodeContent(node){switch(getTag(node)){case"input":case"option":case"textarea":return getNodeValue(node);case"select":return[...node.selectedOptions].map((node)=>getNodeValue(node)).join(",");} return getNodeText(node);} function getNodeIframe(node){const doc=node.contentDocument;return doc&&doc.readyState!=="loading"?doc:false;} function getNodeShadowRoot(node){return node.shadowRoot;} function getQueryFilter(pseudoClass,content){const makeQueryFilter=customPseudoClasses.get(pseudoClass);try{return makeQueryFilter(content);}catch(err){let message=`error while parsing pseudo-class ':${pseudoClass}'`;const cause=String(err?.message||err);if(cause){message+=`: ${cause}`;} throw new HootDomError(message);}} function getRawValue(node){return node.value;} function getStringContent(string){return string.match(R_QUOTE_CONTENT)?.[2]||string;} function getWaitForMessage(){const message=`expected at least 1 element after %timeout%ms and ${lastQueryMessage}`;lastQueryMessage="";return message;} function getWaitForNoneMessage(){const message=`expected 0 elements after %timeout%ms and ${lastQueryMessage}`;lastQueryMessage="";return message;} function hasNodeCount(count,_node,_i,nodes){return count===nodes.length;} function isChar(char){return!!char&&R_CHAR.test(char);} function isDocument(object){return object?.nodeType===Node.DOCUMENT_NODE;} function isElement(object){return object?.nodeType===Node.ELEMENT_NODE;} function isNodeHaving(selector,node){return!!_queryAll(selector,{root:node}).length;} function isNodeHidden(node){return!isNodeVisible(node);} function isNodeInteractive(node){return(getStyle(node).pointerEvents!=="none"&&!node.closest?.("[inert]")&&!getParentFrame(node)?.inert);} function isNodeNotMatching(selector,node){return!matches(node,selector);} function isNodeSelected(node){return!!node.selected;} function isOnlyNode(_node,_i,nodes){return nodes.length===1;} function isQueryableNode(node){return QUERYABLE_NODE_TYPES.includes(node.nodeType);} function isRootElement(el){return el&&R_ROOT_ELEMENT.test(el.nodeName||"");} function isShadowRoot(el){return el.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&!!el.host;} function isWindow(object){return object?.window===object&&object.constructor.name==="Window";} function isWhiteSpace(char){return!!char&&R_HORIZONTAL_WHITESPACE.test(char);} function makePseudoClassMatcher(getContent,exact){return function makePartialMatcher(content){const regex=parseRegExp(content);if(isInstanceOf(regex,RegExp)){return function stringMatches(node){return regex.test(getContent(node));};}else{const lowerContent=content.toLowerCase();if(exact){return function stringEquals(node){return getContent(node).toLowerCase()===lowerContent;};}else{return function stringContains(node){return getContent(node).toLowerCase().includes(lowerContent);};}}};} function matchFilter(filter,nodes,index){if(typeof filter==="number"){if(filter<0){return filter+nodes.length===index;}else{return filter===index;}} const node=nodes[index];if(typeof filter==="function"){return filter(node,index,nodes);}else{return!!node.matches?.(String(filter));}} function nodeFlatMap(nodes,flatMapFn){const result=[];for(const node of nodes){const nodeList=flatMapFn(node);if(isNode(nodeList)){result.push(nodeList);}else if(isIterable(nodeList)){result.push(...nodeList);}} return result;} function parseNumberTuple(value,propsA,propsB){let result=[];if(value&&typeof value==="object"){if(isIterable(value)){[result[0],result[1]]=[...value];}else{for(const prop of propsA){result[0]??=value[prop];} for(const prop of propsB){result[1]??=value[prop];}}}else{result=[value,value];} return result.map($parseFloat);} function parseRawArgs(args){return args[0]?.raw?[$raw(...args)]:args;} function parseSelector(selector){function addToSelector(selector){registerChar=false;const index=currentPart.length-1;if(typeof currentPart[index]==="string"){currentPart[index]+=selector;}else{currentPart.push(selector);}} const firstPart=[""];const firstGroup=[firstPart];const groups=[firstGroup];const parens=[0,0];let currentGroup=groups.at(-1);let currentPart=currentGroup.at(-1);let currentPseudo=null;let currentQuote=null;let registerChar=true;for(let i=0;i1){currentGroup.push([""]);currentPart=currentGroup.at(-1);} registerChar=false;} break;} case`'`:case`"`:{if(char===currentQuote){currentQuote=null;}else if(!currentQuote){currentQuote=char;} break;} case">":case"+":case"~":{if(!currentQuote&&!currentPseudo){while(isWhiteSpace(selector[i+1])){i++;} addToSelector(char);} break;} case":":{if(!currentQuote&&!currentPseudo){let pseudo="";while(isChar(selector[i+1])){pseudo+=selector[++i];} if(customPseudoClasses.has(pseudo)){if(selector[i+1]==="("){parens[0]++;i++;registerChar=false;} currentPseudo=[pseudo,""];}else{addToSelector(char+pseudo);}} break;} case"(":{if(!currentQuote){parens[0]++;} break;} case")":{if(!currentQuote){parens[1]++;} break;}} if(currentPseudo){if(parens[0]===parens[1]){const[pseudo,content]=currentPseudo;if(pseudo==="iframe"&&!currentPart[0].startsWith("iframe")){currentPart[0]=`iframe${currentPart[0]}`;} const filter=getQueryFilter(pseudo,getStringContent(content));selectorFilterDescriptors.set(filter,[pseudo,content]);currentPart.push(filter);currentPseudo=null;}else if(registerChar){currentPseudo[1]+=selector[i];}}else if(registerChar){addToSelector(selector[i]);}} return groups;} function parseXml(xmlString,type){const wrapperTag=type==="html"?"body":"templates";const doc=parser.parseFromString(`<${wrapperTag}>${xmlString}`,`text/${type}`);if(doc.getElementsByTagName("parsererror").length){const trimmed=xmlString.length>80?xmlString.slice(0,80)+"…":xmlString;throw new HootDomError(`error while parsing ${trimmed}: ${getNodeText( doc.getElementsByTagName("parsererror")[0] )}`);} return doc.getElementsByTagName(wrapperTag)[0].childNodes;} function pixelValueToNumber(val){return $parseFloat(val.endsWith("px")?val.slice(0,-2):val);} function plural(word,count){return count===1?word:`${word}s`;} function queryWithCustomSelector(nodes,selector){const selectorGroups=parseSelector(selector);const foundNodes=[];for(const selectorParts of selectorGroups){let groupNodes=nodes;for(const selectorPart of selectorParts){let baseSelector=selectorPart[0];let nodeGetter;switch(baseSelector[0]){case"+":{nodeGetter=NEXT_SIBLING;break;} case">":{nodeGetter=DIRECT_CHILDREN;break;} case"~":{nodeGetter=NEXT_SIBLINGS;break;}} if(nodeGetter){baseSelector=baseSelector.slice(1);} nodeGetter||=DESCENDANTS;const currentGroupNodes=nodeFlatMap(groupNodes,(node)=>nodeGetter(node,baseSelector));groupNodes=applyFilters(selectorPart.slice(1),currentGroupNodes);} foundNodes.push(...groupNodes);} return filterUniqueNodes(foundNodes);} function registerQueryMessage(filteredNodes,expectedCount){lastQueryMessage="";const filteredCount=filteredNodes.length;const invalidCount=$isInteger(expectedCount)&&filteredCount!==expectedCount;if(shouldRegisterQueryMessage||invalidCount){const globalModifierInfo=[...globalFilterDescriptors.values()];lastQueryMessage+=`found ${filteredCount} ${plural("element", filteredCount)}`;if(invalidCount){lastQueryMessage+=` instead of ${expectedCount}`;} const rootModifierInfo=globalModifierInfo.shift();const[,rootContent,initialCount=0]=rootModifierInfo;if(typeof rootContent==="string"){lastQueryMessage+=`: ${initialCount} matching ${JSON.stringify(rootContent)}`;if(selectorFilterDescriptors.size){const selectorModifierInfo=[...selectorFilterDescriptors.values()];lastQueryMessage+=` (${getFiltersDescription(selectorModifierInfo).join(" > ")})`;}}else if(filteredCount!==initialCount){lastQueryMessage+=`: ${initialCount} ${plural("element", initialCount)}`;} if(initialCount){lastQueryMessage+=getFiltersDescription(globalModifierInfo).map((part)=>`, including ${part}`).join("");}}else{lastQueryMessage="";} if(queryAllLevel<=1){globalFilterDescriptors.clear();selectorFilterDescriptors.clear();} return invalidCount?lastQueryMessage:"";} function _guardedQueryAll(target,options){try{return _queryAll(target,options);}catch(error){queryAllLevel=0;shouldRegisterQueryMessage=false;globalFilterDescriptors.clear();selectorFilterDescriptors.clear();throw error;}} function _queryAll(target,options){queryAllLevel++;const{count,root,...modifiers}=options||{};if(count!==null&&count!==undefined&&(!$isInteger(count)||count<=0)){throw new HootDomError(`invalid 'count' option: should be a positive integer`);} let nodes=[];let selector;if(typeof target==="string"){if(target){nodes=root?_queryAll(root):[getDefaultRoot()];} selector=target.trim();}else if(isIterable(target)&&!isNode(target)){nodes=filterUniqueNodes(target);}else if(target){nodes=filterUniqueNodes([target]);} globalFilterDescriptors.set("root",["",target]);if(selector&&nodes.length){if(rCustomPseudoClass.test(selector)){nodes=queryWithCustomSelector(nodes,selector);}else{nodes=filterUniqueNodes(nodeFlatMap(nodes,(node)=>DESCENDANTS(node,selector)));}} globalFilterDescriptors.get("root").push(nodes.length);if(modifiers.visible&&modifiers.displayed){throw new HootDomError(`cannot use more than one visibility modifier ('visible' implies 'displayed')`);} const modifierFilters=[];for(const[modifier,content]of $entries(modifiers)){if(content===false||!customPseudoClasses.has(modifier)){continue;} const filter=getQueryFilter(modifier,content);modifierFilters.push(filter);globalFilterDescriptors.set(filter,[modifier,content]);} const filteredNodes=applyFilters(modifierFilters,nodes);const message=registerQueryMessage(filteredNodes,count);if(message){throw new HootDomError(message);} queryAllLevel--;return filteredNodes;} function _queryOne(target,options){return _guardedQueryAll(target,{...options,count:1})[0];} function _waitForFirst(target,options,isLast){shouldRegisterQueryMessage=isLast;const result=_guardedQueryAll(target,options)[0];shouldRegisterQueryMessage=false;return result;} function _waitForNone(target,options,isLast){shouldRegisterQueryMessage=isLast;const result=_guardedQueryAll(target,options).length===0;shouldRegisterQueryMessage=false;return result;} class HootDomError extends Error{name="HootDomError";} const R_CHAR=/[\w-]/;const R_HORIZONTAL_WHITESPACE=/[\r\t\f \u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/g;const R_LINEBREAK=/\s*\n+\s*/g;const R_QUOTE_CONTENT=/^\s*(['"])?([^]*?)\1\s*$/;const R_ROOT_ELEMENT=/^(HTML|HEAD|BODY)$/;const R_SCROLLABLE_OVERFLOW=/\bauto\b|\bscroll\b/;const MODIFIER_SUFFIX_LABELS={contains:(content)=>`with text "${content}"`,eq:(content)=>`at index ${content}`,has:(content)=>`containing selector "${content}"`,not:(content)=>`not matching "${content}"`,value:(content)=>`with value "${content}"`,viewPort:()=>"in viewport",};const QUERYABLE_NODE_TYPES=[Node.ELEMENT_NODE,Node.DOCUMENT_NODE,Node.DOCUMENT_FRAGMENT_NODE];const parser=new DOMParser();function DIRECT_CHILDREN(node,selector){const children=[];for(const childNode of node.childNodes){if(childNode.matches?.(selector)){children.push(childNode);}} return children;} function DESCENDANTS(node,selector){return node.querySelectorAll?.(selector||"*");} function NEXT_SIBLING(node,selector){const sibling=node.nextElementSibling;return sibling?.matches?.(selector)&&sibling;} function NEXT_SIBLINGS(node,selector){const siblings=[];while((node=node.nextElementSibling)){if(node.matches?.(selector)){siblings.push(node);}} return siblings;} const globalFilterDescriptors=new Map();const selectorFilterDescriptors=new Map();const observers=new Map();const currentDimensions={width:innerWidth,height:innerHeight,};let getDefaultRoot=()=>document;let lastQueryMessage="";let shouldRegisterQueryMessage=false;let queryAllLevel=0;const customPseudoClasses=new Map();customPseudoClasses.set("contains",makePseudoClassMatcher(getInlineNodeText,false)).set("count",(strCount)=>{const count=$parseInt(strCount);if(!$isInteger(count)||count<=0){throw new HootDomError(`expected count to be a positive integer (got "${strCount}")`);} return hasNodeCount.bind(null,count);}).set("displayed",()=>isNodeDisplayed).set("empty",()=>isEmpty).set("eq",(strIndex)=>{const index=$parseInt(strIndex);if(!$isInteger(index)){throw new HootDomError(`expected index to be an integer (got "${strIndex}")`);} return index;}).set("first",()=>0).set("focusable",()=>isNodeFocusable).set("has",(selector)=>isNodeHaving.bind(null,selector)).set("hidden",()=>isNodeHidden).set("iframe",()=>getNodeIframe).set("interactive",()=>isNodeInteractive).set("last",()=>-1).set("not",(selector)=>isNodeNotMatching.bind(null,selector)).set("only",()=>isOnlyNode).set("scrollable",(axis)=>isNodeScrollable.bind(null,axis)).set("selected",()=>isNodeSelected).set("shadow",()=>getNodeShadowRoot).set("text",makePseudoClassMatcher(getInlineNodeText,true)).set("value",makePseudoClassMatcher(getRawValue,false)).set("viewPort",()=>isNodeInViewPort).set("visible",()=>isNodeVisible);const rCustomPseudoClass=compilePseudoClassRegex();__exports.cleanupDOM=cleanupDOM;function cleanupDOM(){currentDimensions.width=innerWidth;currentDimensions.height=innerHeight;const remainingObservers=observers.size;if(remainingObservers){for(const{observer}of observers.values()){observer.disconnect();} observers.clear();}} __exports.defineRootNode=defineRootNode;function defineRootNode(node){if(typeof node==="function"){getDefaultRoot=node;}else if(node){getDefaultRoot=()=>node;}else{getDefaultRoot=()=>document;}} __exports.getCurrentDimensions=getCurrentDimensions;function getCurrentDimensions(){return currentDimensions;} __exports.getDocument=getDocument;function getDocument(node){if(!node){return document;} return isDocument(node)?node:node.ownerDocument||document;} __exports.getNodeAttribute=getNodeAttribute;function getNodeAttribute(node,attribute){return node.getAttribute?.(attribute)??null;} __exports.getNodeValue=getNodeValue;function getNodeValue(node,options){if(options?.raw){return getRawValue(node);} switch(node.type){case"checkbox":case"radio":return node.checked;case"file":return[...node.files];case"number":case"range":return node.valueAsNumber;case"date":case"datetime-local":case"month":case"time":case"week":return node.valueAsDate.toISOString();default:return node.value||"";}} __exports.getNodeRect=getNodeRect;function getNodeRect(node,options){if(!isElement(node)){return new DOMRect();} const rect=node.getBoundingClientRect();const parentFrame=getParentFrame(node);if(parentFrame){const parentRect=getNodeRect(parentFrame);rect.x-=parentRect.x;rect.y-=parentRect.y;} if(!options?.trimPadding){return rect;} const style=getStyle(node);const{x,y,width,height}=rect;const[pl,pr,pt,pb]=["left","right","top","bottom"].map((side)=>pixelValueToNumber(style.getPropertyValue(`padding-${side}`)));return new DOMRect(x+pl,y+pt,width-(pl+pr),height-(pt+pb));} __exports.getNodeText=getNodeText;function getNodeText(node,options){let content;if(typeof node.innerText==="string"){content=node.innerText;}else{content=node.textContent;} if(!options?.raw){content=content.replace(R_HORIZONTAL_WHITESPACE," ").trim();} if(options?.inline){content=content.replace(R_LINEBREAK," ");} return content;} __exports.getInteractiveNode=getInteractiveNode;function getInteractiveNode(node){let currentEl=ensureElement(node);if(!currentEl){return null;} while(currentEl&&!isNodeInteractive(currentEl)){currentEl=currentEl.parentElement;} return currentEl;} __exports.getStyle=getStyle;function getStyle(node){return isElement(node)?getComputedStyle(node):null;} __exports.getWindow=getWindow;function getWindow(node){if(!node){return window;} return isWindow(node)?node:getDocument(node).defaultView;} __exports.isCheckable=isCheckable;function isCheckable(node){switch(getTag(node)){case"input":return node.type==="checkbox"||node.type==="radio";case"label":return isCheckable(node.control);default:return false;}} __exports.isEmpty=isEmpty;function isEmpty(value){if(!value){return true;} if(typeof value==="object"){if(isNode(value)){return isEmpty(getNodeContent(value));} if(!isIterable(value)){value=$keys(value);} return[...value].length===0;} return false;} __exports.isEventTarget=isEventTarget;function isEventTarget(object){return object&&typeof object.addEventListener==="function";} __exports.isNode=isNode;function isNode(object){return object&&typeof object.nodeType==="number"&&typeof object.nodeName==="string";} __exports.isNodeCssVisible=isNodeCssVisible;function isNodeCssVisible(node){const element=ensureElement(node);if(element===getDefaultRoot()||isRootElement(element)){return true;} const style=getStyle(element);if(style?.visibility==="hidden"||style?.opacity==="0"){return false;} const parent=element.parentNode;return!parent||isNodeCssVisible(isShadowRoot(parent)?parent.host:parent);} __exports.isNodeDisplayed=isNodeDisplayed;function isNodeDisplayed(node){const element=ensureElement(node);if(!isInDOM(element)){return false;} if(isRootElement(element)||element.offsetParent||element.closest("svg")){return true;} return!isFirefox()&&getStyle(element)?.position==="fixed";} __exports.isNodeFocusable=isNodeFocusable;function isNodeFocusable(node,options){return(isNodeDisplayed(node)&&node.matches?.(FOCUSABLE_SELECTOR)&&(!options?.tabbable||node.tabIndex>=0));} __exports.isNodeInViewPort=isNodeInViewPort;function isNodeInViewPort(node){const element=ensureElement(node);const{x,y}=getNodeRect(element);return y>0&&y0&&x0&&height>0;if(!visible&&getStyle(element)?.display==="contents"){for(const child of element.childNodes){if(isNodeVisible(child)){return true;}}} return visible;} __exports.parseDimensions=parseDimensions;function parseDimensions(dimensions){return parseNumberTuple(dimensions,["width","w"],["height","h"]);} __exports.parsePosition=parsePosition;function parsePosition(position){return parseNumberTuple(position,["x","left","clientX","pageX","screenX"],["y","top","clientY","pageY","screenY"]);} __exports.setDimensions=setDimensions;function setDimensions(width,height){const defaultRoot=getDefaultRoot();if(!$isNaN(width)){currentDimensions.width=width;defaultRoot.style?.setProperty("width",`${width}px`,"important");} if(!$isNaN(height)){currentDimensions.height=height;defaultRoot.style?.setProperty("height",`${height}px`,"important");}} __exports.toSelector=toSelector;function toSelector(node,options){const parts={tag:node.nodeName.toLowerCase(),};if(node.id){parts.id=`#${node.id}`;} if(node.classList?.length){parts.class=`.${[...node.classList].join(".")}`;} return options?.object?parts:$values(parts).join("");} const FOCUSABLE_SELECTOR=__exports.FOCUSABLE_SELECTOR=["a[href]","area[href]","button:enabled","details > summary:first-of-type","iframe","input:enabled","select:enabled","textarea:enabled","[tabindex]","[contenteditable=true]",].join(",");__exports.formatXml=formatXml;function formatXml(value,options){const nodes=parseXml(value,options?.type||"xml");const layers=extractLayers(nodes,0,options?.keepInlineTextNodes??false);return generateStringFromLayers(layers,options?.tabSize??4);} __exports.getActiveElement=getActiveElement;function getActiveElement(node){const doc=getDocument(node);const view=doc.defaultView;const{activeElement}=doc;const{contentDocument,shadowRoot}=activeElement;if(contentDocument&&contentDocument.activeElement!==contentDocument.body){if(contentDocument.activeElement===contentDocument.body){return contentDocument.activeElement;}else{return getActiveElement(contentDocument);}} if(shadowRoot){return shadowRoot.activeElement;} if(activeElement===doc.body&&view!==view.parent){return getActiveElement(view.parent.document);} return activeElement;} __exports.getFocusableElements=getFocusableElements;function getFocusableElements(options){const parent=_queryOne(options?.root||getDefaultRoot());if(typeof parent.querySelectorAll!=="function"){return[];} const byTabIndex={};for(const element of parent.querySelectorAll(FOCUSABLE_SELECTOR)){const{tabIndex}=element;if((options?.tabbable&&tabIndex<0)||!isNodeDisplayed(element)){continue;} if(!byTabIndex[tabIndex]){byTabIndex[tabIndex]=[];} byTabIndex[tabIndex].push(element);} const withTabIndexZero=byTabIndex[0]||[];delete byTabIndex[0];return[...$values(byTabIndex).flat(),...withTabIndexZero];} __exports.getNextFocusableElement=getNextFocusableElement;function getNextFocusableElement(options){const parent=_queryOne(options?.root||getDefaultRoot());const focusableEls=getFocusableElements({...options,parent});const index=focusableEls.indexOf(getActiveElement(parent));return focusableEls[index+1]||null;} __exports.getParentFrame=getParentFrame;function getParentFrame(node){const doc=getDocument(node);if(!doc){return null;} const view=doc.defaultView;if(view!==view.parent){for(const iframe of view.parent.document.getElementsByTagName("iframe")){if(iframe.contentWindow===view){return iframe;}}} return null;} __exports.getPreviousFocusableElement=getPreviousFocusableElement;function getPreviousFocusableElement(options){const parent=_queryOne(options?.root||getDefaultRoot());const focusableEls=getFocusableElements({...options,parent});const index=focusableEls.indexOf(getActiveElement(parent));return index<0?focusableEls.at(-1):focusableEls[index-1]||null;} __exports.isDisplayed=isDisplayed;function isDisplayed(target){return _guardedQueryAll(target,{displayed:true}).length>0;} __exports.isEditable=isEditable;function isEditable(node){return(isElement(node)&&!node.matches?.(":disabled")&&["input","textarea"].includes(getTag(node)));} __exports.isFocusable=isFocusable;function isFocusable(target){return _guardedQueryAll(target,{focusable:true}).length>0;} __exports.isInDOM=isInDOM;function isInDOM(target){return ensureElement(target)?.isConnected;} __exports.isInViewPort=isInViewPort;function isInViewPort(target){return _guardedQueryAll(target,{viewPort:true}).length>0;} __exports.isScrollable=isScrollable;function isScrollable(target,axis){return _guardedQueryAll(target,{scrollable:axis}).length>0;} __exports.isVisible=isVisible;function isVisible(target){return _guardedQueryAll(target,{visible:true}).length>0;} __exports.matches=matches;function matches(target,selector){return elementsMatch(_guardedQueryAll(target),selector);} __exports.queryAll=queryAll;function queryAll(target,options){[target,options]=parseRawArgs(arguments);return _guardedQueryAll(target,options);} __exports.queryAllAttributes=queryAllAttributes;function queryAllAttributes(target,attribute,options){return _guardedQueryAll(target,options).map((node)=>getNodeAttribute(node,attribute));} __exports.queryAllProperties=queryAllProperties;function queryAllProperties(target,property,options){return _guardedQueryAll(target,options).map((node)=>node[property]);} __exports.queryAllRects=queryAllRects;function queryAllRects(target,options){[target,options]=parseRawArgs(arguments);return _guardedQueryAll(target,options).map(getNodeRect);} __exports.queryAllTexts=queryAllTexts;function queryAllTexts(target,options){[target,options]=parseRawArgs(arguments);return _guardedQueryAll(target,options).map((node)=>getNodeText(node,options));} __exports.queryAllValues=queryAllValues;function queryAllValues(target,options){[target,options]=parseRawArgs(arguments);return _guardedQueryAll(target,options).map((node)=>getNodeValue(node,options));} __exports.queryAny=queryAny;function queryAny(target,options){[target,options]=parseRawArgs(arguments);return _queryOne(target,ensureCount(options));} __exports.queryAttribute=queryAttribute;function queryAttribute(target,attribute,options){return getNodeAttribute(_queryOne(target,options),attribute);} __exports.queryFirst=queryFirst;function queryFirst(target,options){[target,options]=parseRawArgs(arguments);return _guardedQueryAll(target,options)[0]||null;} __exports.queryOne=queryOne;function queryOne(target,options){[target,options]=parseRawArgs(arguments);if($isInteger(options?.count)){throw new HootDomError(`cannot call \`queryOne\` with 'count'=${options.count}: did you mean to use \`queryAll\`?`);} return _queryOne(target,options);} __exports.queryRect=queryRect;function queryRect(target,options){[target,options]=parseRawArgs(arguments);return getNodeRect(_queryOne(target,options),options);} __exports.queryText=queryText;function queryText(target,options){[target,options]=parseRawArgs(arguments);return getNodeText(_queryOne(target,options),options);} __exports.queryValue=queryValue;function queryValue(target,options){[target,options]=parseRawArgs(arguments);return getNodeValue(_queryOne(target,options),options);} __exports.waitFor=waitFor;function waitFor(target,options){[target,options]=parseRawArgs(arguments);return waitUntil(_waitForFirst.bind(null,target,options),{message:getWaitForMessage,...options,});} __exports.waitForNone=waitForNone;function waitForNone(target,options){[target,options]=parseRawArgs(arguments);return waitUntil(_waitForNone.bind(null,target,options),{message:getWaitForNoneMessage,...options,});} return __exports;});; /* /web/static/lib/hoot-dom/helpers/events.js */ odoo.define('@web/../lib/hoot-dom/helpers/events',['@web/../lib/hoot-dom/hoot_dom_utils','@web/../lib/hoot-dom/helpers/dom'],function(require){'use strict';let __exports={};const{getColorHex,getTag,isFirefox,isInstanceOf,isIterable}=require("@web/../lib/hoot-dom/hoot_dom_utils");const{getActiveElement,getDocument,getInteractiveNode,getNextFocusableElement,getNodeRect,getNodeValue,getParentFrame,getPreviousFocusableElement,getStyle,getWindow,isCheckable,isEditable,isEventTarget,isNode,isNodeFocusable,parseDimensions,parsePosition,queryAll,queryAny,setDimensions,toSelector,}=require("@web/../lib/hoot-dom/helpers/dom");const{AnimationEvent,ClipboardEvent,CompositionEvent,console:{dir:$dir,groupCollapsed:$groupCollapsed,groupEnd:$groupEnd,log:$log},DataTransfer,document,DragEvent,Error,ErrorEvent,Event,File,FocusEvent,HashChangeEvent,HTMLElement,KeyboardEvent,Math:{ceil:$ceil,max:$max,min:$min},MouseEvent,Number:{isInteger:$isInteger,isNaN:$isNaN,parseFloat:$parseFloat},Object:{assign:$assign,create:$create,defineProperties:$defineProperties,values:$values,},PointerEvent,PromiseRejectionEvent,String,SubmitEvent,Touch,TouchEvent,TypeError,WheelEvent,}=globalThis;const $createRange=document.createRange.bind(document);const $toString=Object.prototype.toString;const $blur=HTMLElement.prototype.blur;HTMLElement.prototype.blur=function mockBlur(){if(runTime.changeTarget&&runTime.changeTarget===this){triggerChange();} return $blur.call(this,...arguments);};const $focus=HTMLElement.prototype.focus;HTMLElement.prototype.focus=function mockFocus(){if(runTime.changeTarget&&runTime.changeTarget!==this){triggerChange();} return $focus.call(this,...arguments);};function cancelTrustedEvent(ev){if(ev.isTrusted&&runTime.eventsToIgnore.includes(ev.type)){runTime.eventsToIgnore.splice(runTime.eventsToIgnore.indexOf(ev.type),1);ev.stopPropagation();ev.stopImmediatePropagation();ev.preventDefault();}} async function changeSelection(target,start,end){if(!isNil(start)&&!isNil(target.selectionStart)){target.selectionStart=start;} if(!isNil(end)&&!isNil(target.selectionEnd)){target.selectionEnd=end;}} function constrainScrollX(target,x){let{offsetWidth,scrollWidth}=target;const document=getDocument(target);if(target===document||target===document.documentElement){const iframe=getParentFrame(target);if(iframe){({offsetWidth}=iframe);}} const maxScrollLeft=scrollWidth-offsetWidth;const{direction}=getStyle(target);const[min,max]=direction==="rtl"?[-maxScrollLeft,0]:[0,maxScrollLeft];return $min($max(x,min),max);} function constrainScrollY(target,y){let{offsetHeight,scrollHeight}=target;const document=getDocument(target);if(target===document||target===document.documentElement){const iframe=getParentFrame(target);if(iframe){({offsetHeight}=iframe);}} return $min($max(y,0),scrollHeight-offsetHeight);} function createDataTransfer(options){const dataTransfer=isInstanceOf(options?.dataTransfer,DataTransfer)?options.dataTransfer:new DataTransfer();for(const file of options?.files||[]){if(!isInstanceOf(file,File)){throw new TypeError(`'DataTransfer.files' list only accepts 'File' objects`);} dataTransfer.items.add(file);} for(const[data,type]of options?.items||[]){dataTransfer.items.add(data,type);} $defineProperties(dataTransfer,{dropEffect:{value:options?.dropEffect||"none",writable:true},effectAllowed:{value:options?.effectAllowed||"all",writable:true},});return dataTransfer;} function deleteSelection(target){const{selectionStart,selectionEnd,value}=target;return value.slice(0,selectionStart)+value.slice(selectionEnd);} async function dispatchAndIgnore({target,events,additionalEvents=[],callback,options}){for(const eventType of[...events,...additionalEvents]){runTime.eventsToIgnore.push(eventType);} callback?.();for(const eventType of events){await _dispatch(target,eventType,options);}} async function dispatchPointerEvent(target,eventType,eventInit,{mouse,touch}){const pointerEvent=await _dispatch(target,eventType,eventInit);let prevented=isPrevented(pointerEvent);if(hasTouch()){if(touch&&runTime.pointerDownTarget){const[touchEventType,touchEventInit]=touch;await _dispatch(runTime.pointerDownTarget,touchEventType,touchEventInit||eventInit);}}else{if(mouse&&!prevented){const[mouseEventType,mouseEventInit]=mouse;const mouseEvent=await _dispatch(target,mouseEventType,mouseEventInit||eventInit);prevented=isPrevented(mouseEvent);}} return prevented;} async function dispatchRelatedEvents(events,eventType,eventInit){for(const event of events){if(!event.target||isPrevented(event)){break;} await _dispatch(event.target,eventType,eventInit);}} function ensureArray(value,mapFn){if(Array.isArray(value)){return mapFn?value.map(mapFn):value;} if(isIterable(value)){return Array.from(value,mapFn);} return[mapFn?mapFn(value):value];} function getCurrentEvents(){const eventType=currentEventTypes.at(-1);if(!eventType){return[];} currentEvents[eventType]||=[];return currentEvents[eventType];} function getDefaultRunTimeValue(){return{changeTarget:null,changeTargetListeners:[],clipboardData:null,dataTransfer:null,initialValue:null,isComposing:false,key:null,canStartDrag:false,isDragging:false,lastDragOverCancelled:false,clickCount:0,pointerDownTarget:null,pointerDownTimeout:0,pointerTarget:null,position:{},previousPointerDownTarget:null,touchStartPosition:{},fileInput:null,buttons:0,modifierKeys:{},eventsToIgnore:[],};} function getDifferentParents(el1,el2){if(!el1&&!el2){return[];}else if(!el1&&el2){[el1,el2]=[el2,el1];} const parents=[el2||el1];while(parents[0].parentElement){const parent=parents[0].parentElement;if(el2&&parent.contains(el1)){break;} parents.unshift(parent);} return parents;} function getEventConstructor(eventType){switch(eventType){case"dblclick":case"mousedown":case"mouseup":case"mousemove":case"mouseover":case"mouseout":return[MouseEvent,mapMouseEvent,BUBBLES|CANCELABLE|VIEW];case"mouseenter":case"mouseleave":return[MouseEvent,mapMouseEvent,VIEW];case"auxclick":case"click":case"contextmenu":case"pointerdown":case"pointerup":case"pointermove":case"pointerover":case"pointerout":return[PointerEvent,mapPointerEvent,BUBBLES|CANCELABLE|VIEW];case"pointerenter":case"pointerleave":case"pointercancel":return[PointerEvent,mapPointerEvent,VIEW];case"blur":case"focus":return[FocusEvent,mapEvent];case"focusin":case"focusout":return[FocusEvent,mapEvent,BUBBLES];case"cut":case"copy":case"paste":return[ClipboardEvent,mapEvent,BUBBLES];case"keydown":case"keyup":return[KeyboardEvent,mapKeyboardEvent,BUBBLES|CANCELABLE|VIEW];case"drag":case"dragend":case"dragenter":case"dragstart":case"dragleave":case"dragover":case"drop":return[DragEvent,mapEvent,BUBBLES|CANCELABLE];case"beforeinput":return[InputEvent,mapInputEvent,BUBBLES|CANCELABLE|VIEW];case"input":return[InputEvent,mapInputEvent,BUBBLES|VIEW];case"compositionstart":case"compositionend":return[CompositionEvent,mapEvent,BUBBLES];case"select":case"selectionchange":return[Event,mapEvent,BUBBLES];case"touchstart":case"touchend":case"touchmove":return[TouchEvent,mapTouchEvent,BUBBLES|CANCELABLE|VIEW];case"touchcancel":return[TouchEvent,mapTouchEvent,BUBBLES|VIEW];case"resize":return[Event,mapEvent];case"submit":return[SubmitEvent,mapEvent,BUBBLES|CANCELABLE];case"wheel":return[WheelEvent,mapWheelEvent,BUBBLES|VIEW];case"animationcancel":case"animationend":case"animationiteration":case"animationstart":{return[AnimationEvent,mapEvent,BUBBLES|CANCELABLE];} case"error":return[ErrorEvent,mapEvent];case"unhandledrejection":return[PromiseRejectionEvent,mapEvent,CANCELABLE];case"beforeunload":return[Event,mapEvent,CANCELABLE];case"unload":return[Event,mapEvent];case"hashchange":return[HashChangeEvent,mapEvent];default:return[Event,mapEvent,BUBBLES];}} function getFirstCommonParent(a,b){if(!a||!b||a.ownerDocument!==b.ownerDocument){return null;} const range=document.createRange();range.setStart(a,0);range.setEnd(b,0);if(range.collapsed){range.setStart(b,0);range.setEnd(a,0);} return range.commonAncestorContainer;} function getPointerTarget(element,options,originalTarget){if(!element||options?.interactive===false){return element;} const interactiveElement=getInteractiveNode(element);if(!interactiveElement&&originalTarget){queryAny(originalTarget,{...options,interactive:true});} return interactiveElement;} function getPosition(element,options){const{position,relative}=options||{};const isString=typeof position==="string";const[posX,posY]=parsePosition(position);if(!isString&&!relative&&!$isNaN(posX)&&!$isNaN(posY)){return toEventPosition(posX,posY,position);} const{x,y,width,height}=getNodeRect(element);let clientX=x;let clientY=y;if(isString){const positions=position.split("-");if(positions.includes("left")){clientX-=1;}else if(positions.includes("right")){clientX+=$ceil(width)+1;}else{clientX+=width/2;} if(positions.includes("top")){clientY-=1;}else if(positions.includes("bottom")){clientY+=$ceil(height)+1;}else{clientY+=height/2;}}else{if($isNaN(posX)){clientX+=width/2;}else{if(relative){clientX+=posX||0;}else{clientX=posX||0;}} if($isNaN(posY)){clientY+=height/2;}else{if(relative){clientY+=posY||0;}else{clientY=posY||0;}}} return toEventPosition(clientX,clientY,position);} function getStringSelection(target){return($isInteger(target.selectionStart)&&$isInteger(target.selectionEnd)&&[target.selectionStart,target.selectionEnd].join(","));} function hasTagName(node,...tagNames){return tagNames.includes(getTag(node));} function hasTouch(){return(globalThis.ontouchstart!==undefined||globalThis.matchMedia("(pointer:coarse)").matches);} function isDifferentPosition(position){if(!runTime.position||!position){return runTime.position!==position;} for(const key in position){if(runTime.position[key]!==position[key]){return true;}} return false;} function isDictionary(object){return $toString.call(object)==="[object Object]";} function isNil(value){return value===null||value===undefined;} function isPrevented(event){return event&&event.defaultPrevented;} function parseKeyStrokes(keyStrokes,options){return ensureArray(keyStrokes,(key)=>{const lower=key.toLowerCase();return{...options,key:lower.length===1?key:KEY_ALIASES[lower]||key,};});} function redirectSubmit(ev){if(isPrevented(ev)){return;} ev.preventDefault();const form=ev.target;globalThis.fetch(form.action,{method:form.method,body:new FormData(form,ev.submitter),});} function registerButton(eventInit,toggle){let value=0;switch(eventInit.button){case btn.LEFT:{value=1;break;} case btn.MIDDLE:{value=4;break;} case btn.RIGHT:{value=2;break;} case btn.BACK:{value=8;break;} case btn.FORWARD:{value=16;break;}} runTime.buttons=$max(runTime.buttons+(toggle?value:-value),0);} function registerFileInput({target}){const actualTarget=target.shadowRoot?target.shadowRoot.activeElement:target;if(getTag(actualTarget)==="input"&&actualTarget.type==="file"){runTime.fileInput=actualTarget;}else{runTime.fileInput=null;}} async function registerForChange(target,confirmAction){confirmAction&&=confirmAction.toLowerCase();if(confirmAction==="auto"){confirmAction=getTag(target)==="input"?"enter":"blur";} const parentDocument=getDocument(target);const parentView=parentDocument.defaultView;if(confirmAction==="enter"&&getTag(target)!=="input"){throw new HootInteractionError(`"enter" confirm action is only supported on elements`);} runTime.changeTarget=target;runTime.changeTargetListeners.push(on(parentView,"focusout",triggerChange),on(parentView,"change",removeChangeTargetListeners));switch(confirmAction){case"blur":{await _hover(parentDocument.body,{position:{x:0,y:0}},{originalTarget:target});await _click();break;} case"enter":{await _press(target,{key:"Enter"});break;} case"tab":{await _press(target,{key:"Tab"});break;}}} function registerSpecialKey(eventInit,toggle){switch(eventInit.key){case"Alt":{runTime.modifierKeys.altKey=toggle;break;} case"Control":{runTime.modifierKeys.ctrlKey=toggle;break;} case"Meta":{runTime.modifierKeys.metaKey=toggle;break;} case"Shift":{runTime.modifierKeys.shiftKey=toggle;break;}}} function removeChangeTargetListeners(){for(const listener of runTime.changeTargetListeners){listener();} runTime.changeTarget=null;runTime.changeTargetListeners=[];} function resolve(resolver){return typeof resolver==="function"?resolver():resolver;} function setPointerDownTarget(target,options){if(runTime.pointerDownTarget){runTime.previousPointerDownTarget=runTime.pointerDownTarget;} runTime.pointerDownTarget=getPointerTarget(target,options);runTime.canStartDrag=false;} function setupEvents(type,options){currentEventTypes.push(type);$assign(currentEventInit,options?.eventInit);return function finalizeEvents(){for(const eventType in currentEventInit){delete currentEventInit[eventType];} const events=new EventList(getCurrentEvents());const currentType=currentEventTypes.pop();delete currentEvents[currentType];if(!allowLogs){return events;} const groupName=[`%c[${type}]%c dispatched`,`color: ${getColorHex("purple")}`,"",events.length,`events`,];$groupCollapsed(...groupName);for(const event of events){const colors=[getColorHex("text-report-html-tag")];const typeList=[event.type];if(event.key){typeList.push(event.key);}else if(event.button){typeList.push(event.button);} [...Array(typeList.length)].forEach(()=>colors.push(getColorHex("text-report-string")));const typeString=typeList.map((t)=>`%c"${t}"%c`).join(", ");let message=`%c${event.constructor.name}%c<${typeString}>`;if(event.__bubbleCount){message+=` (${event.__bubbleCount})`;} const target=event.__originalTarget||event.target;if(isNode(target)){const targetParts=toSelector(target,{object:true});colors.push(getColorHex("text-report-html-tag"));if(targetParts.id){colors.push(getColorHex("text-report-html-id"));} if(targetParts.class){colors.push(getColorHex("text-report-html-class"));} const targetString=$values(targetParts).map((part)=>`%c${part}%c`).join("");message+=` @${targetString}`;} const messageColors=colors.flatMap((color)=>[`color: ${color}; font-weight: normal`,"",]);$groupCollapsed(message,...messageColors);$dir(event);$log(target);$groupEnd();} $groupEnd();return events;};} function toEventPosition(clientX,clientY,position){clientX||=0;clientY||=0;return{clientX,clientY,pageX:position?.pageX??clientX,pageY:position?.pageY??clientY,screenX:position?.screenX??clientX,screenY:position?.screenY??clientY,};} async function triggerChange(){const target=runTime.changeTarget;const hasValueChanged=runTime.initialValue!==target.value;runTime.initialValue=null;removeChangeTargetListeners();if(target&&hasValueChanged){return _dispatch(target,"change");}} async function triggerClick(target,pointerInit){if(target.disabled){return;} const eventType=(pointerInit.button??0)===btn.LEFT?"click":"auxclick";const clickEvent=await _dispatch(target,eventType,pointerInit);if(isPrevented(clickEvent)){return;} if(isFirefox()){switch(getTag(target)){case"label":{target=target.control;if(target){await triggerClick(target,pointerInit);} break;} case"option":{const parent=target.parentElement;if(parent&&getTag(parent)==="select"){await _dispatch(parent,"change");} break;}}}} async function triggerDrag(target,eventInit){await _dispatch(target,"drag",eventInit);const dragOverEvent=await _dispatch(target,"dragover",eventInit);return isPrevented(dragOverEvent);} async function triggerFocus(target){const previous=getActiveElement(target);if(previous===target){return;} if(previous!==target.ownerDocument.body){if(runTime.changeTarget){await triggerChange();} await dispatchAndIgnore({target:previous,events:["blur","focusout"],callback:$blur.bind(previous),options:{relatedTarget:target},});} if(isNodeFocusable(target)){const previousSelection=getStringSelection(target);await dispatchAndIgnore({target,events:["focus","focusin"],additionalEvents:["select"],callback:$focus.bind(target),options:{relatedTarget:previous},});if(previousSelection&&previousSelection===getStringSelection(target)){changeSelection(target,target.value.length,target.value.length);}}} async function _clear(targetResolver,options){await _press(targetResolver,{ctrlKey:true,key:"a"});await _press(targetResolver,{key:"Backspace"},{fullClear:true});await registerForChange(resolve(targetResolver),options?.confirm);} async function _click(options){await _pointerDown(options);await _pointerUp(options);} async function _dispatch(target,type,eventInit){eventInit={...eventInit,...currentEventInit[type]};for(const key in eventInit){if(key in DEPRECATED_EVENT_PROPERTIES){throw new HootInteractionError(`cannot dispatch "${type}" event: property "${key}" is deprecated, use "${DEPRECATED_EVENT_PROPERTIES[key]}" instead`);}} const[Constructor,processParams,flags]=getEventConstructor(type);const params=processParams({composed:true,...eventInit,target,type,});if(flags&BUBBLES){params.bubbles=true;} if(flags&CANCELABLE){params.cancelable=true;} if(flags&VIEW){params.view||=getWindow(target);} const event=new Constructor(type,params);target.dispatchEvent(event);await Promise.resolve();getCurrentEvents().push(event);return event;} async function _fill(targetResolver,value,options){const initialTarget=resolve(targetResolver);if(getTag(initialTarget)==="input"){switch(initialTarget.type){case"color":case"time":{initialTarget.value=String(value);await _dispatch(initialTarget,"input");await _dispatch(initialTarget,"change");return;} case"file":{const files=ensureArray(value);if(files.length>1&&!initialTarget.multiple){throw new HootInteractionError(`input[type="file"] does not support multiple files`);} initialTarget.files=createDataTransfer({files}).files;await _dispatch(initialTarget,"change");return;} case"range":{const numberValue=$parseFloat(value);if($isNaN(numberValue)){throw new TypeError(`input[type="range"] only accept 'number' values`);} initialTarget.value=String(numberValue);await _dispatch(initialTarget,"input");await _dispatch(initialTarget,"change");return;}}} if(options?.instantly){globalThis.navigator.clipboard.writeText(value).catch();await _press(targetResolver,{ctrlKey:true,key:"v"});}else{if(options?.composition){runTime.isComposing=true;await _dispatch(initialTarget,"compositionstart");} for(const char of String(value)){const key=char.toLowerCase();await _press(targetResolver,{key,shiftKey:key!==char});} if(options?.composition){runTime.isComposing=false;await _dispatch(initialTarget,"compositionend");}} await registerForChange(resolve(targetResolver),options?.confirm);} async function _hover(target,options,hoverOptions){const pointerTarget=getPointerTarget(target,options,hoverOptions.originalTarget);const position=target&&getPosition(target,options);const previousPT=runTime.pointerTarget;const previousPosition=runTime.position;const isDifferentTarget=previousPT!==pointerTarget;if(hoverOptions?.implicit&&!isDifferentTarget&&!isDifferentPosition(position)){return;} if(runTime.canStartDrag){const dragStartEvent=await _dispatch(previousPT,"dragstart",{dataTransfer:runTime.dataTransfer,});runTime.isDragging=!isPrevented(dragStartEvent);runTime.canStartDrag=false;} runTime.pointerTarget=pointerTarget;runTime.position=position;if(isDifferentTarget&&previousPT&&(!pointerTarget||!previousPT.contains(pointerTarget))){const leaveEventInit={...previousPosition,relatedTarget:pointerTarget,button:options?.button||0,};if(runTime.isDragging){const leaveEventInitWithDT={...leaveEventInit,dataTransfer:runTime.dataTransfer};runTime.lastDragOverCancelled=await triggerDrag(previousPT,leaveEventInitWithDT);await _dispatch(previousPT,"dragleave",leaveEventInitWithDT);}else{await dispatchPointerEvent(previousPT,"pointermove",leaveEventInit,{mouse:["mousemove"],touch:["touchmove"],});await dispatchPointerEvent(previousPT,"pointerout",leaveEventInit,{mouse:["mouseout"],});const leaveEvents=await Promise.all(getDifferentParents(pointerTarget,previousPT).map((element)=>_dispatch(element,"pointerleave",leaveEventInit)));if(!hasTouch()){await dispatchRelatedEvents(leaveEvents,"mouseleave",leaveEventInit);}}} if(!pointerTarget){return;} const enterEventInit={...runTime.position,relatedTarget:previousPT,button:options?.button||0,};if(runTime.isDragging){const enterEventInitWithDT={...enterEventInit,dataTransfer:runTime.dataTransfer};runTime.lastDragOverCancelled=false;if(isDifferentTarget){const dragEnterEvent=await _dispatch(pointerTarget,"dragenter",enterEventInitWithDT);runTime.lastDragOverCancelled=isPrevented(dragEnterEvent);} runTime.lastDragOverCancelled||=await triggerDrag(pointerTarget,enterEventInitWithDT);}else{if(isDifferentTarget){await dispatchPointerEvent(pointerTarget,"pointerover",enterEventInit,{mouse:["mouseover"],});const enterEvents=await Promise.all(getDifferentParents(previousPT,pointerTarget).map((element)=>_dispatch(element,"pointerenter",enterEventInit)));if(!hasTouch()){await dispatchRelatedEvents(enterEvents,"mouseenter",enterEventInit);}} await dispatchPointerEvent(pointerTarget,"pointermove",enterEventInit,{mouse:["mousemove"],touch:["touchmove"],});}} async function _keyDown(targetResolver,eventInit,options){eventInit={...eventInit,...currentEventInit.keydown};registerSpecialKey(eventInit,true);const keyDownTarget=resolve(targetResolver);const repeat=typeof eventInit.repeat==="boolean"?eventInit.repeat:runTime.key===eventInit.key;runTime.key=eventInit.key;const keyDownEvent=await _dispatch(keyDownTarget,"keydown",{...eventInit,repeat,});if(isPrevented(keyDownEvent)){return;} function insertValue(toInsert,type){const{selectionStart,selectionEnd,value}=inputTarget;inputData=toInsert;inputType=type;if(isNil(selectionStart)&&isNil(selectionEnd)){nextValue||=inputTarget.value;nextValue+=toInsert;}else{nextValue=value.slice(0,selectionStart)+toInsert+value.slice(selectionEnd);if(selectionStart===selectionEnd){nextSelectionStart=nextSelectionEnd=selectionStart+1;}}} const{ctrlKey,key,shiftKey}=keyDownEvent;const inputTarget=resolve(targetResolver);let inputData=null;let inputType=null;let nextSelectionEnd=null;let nextSelectionStart=null;let nextValue=null;let triggerSelect=false;if(runTime.initialValue===null||keyDownTarget!==inputTarget){runTime.initialValue=inputTarget.value;} if(isEditable(inputTarget)){switch(key){case"ArrowDown":case"ArrowLeft":case"ArrowUp":case"ArrowRight":{const{selectionStart,selectionEnd,value}=inputTarget;if(isNil(selectionStart)||isNil(selectionEnd)){break;} const start=key==="ArrowLeft"||key==="ArrowUp";let selectionTarget;if(ctrlKey){selectionTarget=start?0:value.length;}else{selectionTarget=start?selectionStart-1:selectionEnd+1;} nextSelectionStart=nextSelectionEnd=$max($min(selectionTarget,value.length),0);triggerSelect=shiftKey;break;} case"Backspace":{const{selectionStart,selectionEnd,value}=inputTarget;if(options?.fullClear){nextValue="";}else if(isNil(selectionStart)||isNil(selectionEnd)){nextValue=value.slice(0,-1);}else if(selectionStart===selectionEnd){nextValue=value.slice(0,selectionStart-1)+value.slice(selectionEnd);}else{nextValue=deleteSelection(inputTarget);} inputType="deleteContentBackward";break;} case"Delete":{const{selectionStart,selectionEnd,value}=inputTarget;if(isNil(selectionStart)||isNil(selectionEnd)){nextValue=value.slice(1);}else if(selectionStart===selectionEnd){nextValue=value.slice(0,selectionStart)+value.slice(selectionEnd+1);}else{nextValue=deleteSelection(inputTarget);} inputType="deleteContentForward";break;} default:{if(key.length===1&&!ctrlKey){insertValue(shiftKey?key.toUpperCase():key.toLowerCase(),runTime.isComposing?"insertCompositionText":"insertText");}}}} switch(key){case"a":{if(ctrlKey){if(isEditable(inputTarget)){nextSelectionStart=0;nextSelectionEnd=inputTarget.value.length;triggerSelect=true;}else{const selection=globalThis.getSelection();const range=$createRange();range.selectNodeContents(inputTarget);selection.removeAllRanges();selection.addRange(range);}} break;} case"c":{if(ctrlKey){const text=globalThis.getSelection().toString();globalThis.navigator.clipboard.writeText(text).catch();runTime.clipboardData=createDataTransfer(eventInit);await _dispatch(inputTarget,"copy",{clipboardData:runTime.clipboardData});} break;} case"Enter":{if(runTime.changeTarget){await triggerChange();} if(inputTarget.tagName==="TEXTAREA"&&isEditable(inputTarget)){insertValue("\n","insertLineBreak");} const tag=getTag(inputTarget);const parentForm=inputTarget.closest("form");if(parentForm&&inputTarget.type!=="button"){await _dispatch(parentForm,"submit");}else if(!keyDownEvent.repeat&&(tag==="a"||tag==="button"||(tag==="input"&&inputTarget.type==="button"))){await _dispatch(inputTarget,"click",{button:btn.LEFT});} break;} case"Escape":{runTime.dataTransfer=null;runTime.isDragging=false;break;} case"Tab":{const next=shiftKey?getPreviousFocusableElement({tabbable:true}):getNextFocusableElement({tabbable:true});if(next){await triggerFocus(next);} break;} case"v":{if(ctrlKey&&isEditable(inputTarget)){try{nextValue=await globalThis.navigator.clipboard.readText();}catch{} inputType="insertFromPaste";await _dispatch(inputTarget,"paste",{clipboardData:runTime.clipboardData||createDataTransfer(eventInit),});runTime.clipboardData=null;} break;} case"x":{if(ctrlKey&&isEditable(inputTarget)){const text=globalThis.getSelection().toString();globalThis.navigator.clipboard.writeText(text).catch();nextValue=deleteSelection(inputTarget);inputType="deleteByCut";runTime.clipboardData=createDataTransfer(eventInit);await _dispatch(inputTarget,"cut",{clipboardData:runTime.clipboardData});} break;}} if(nextValue!==null){inputTarget.value=nextValue;const inputEventInit={data:inputData,inputType,};const beforeInputEvent=await _dispatch(inputTarget,"beforeinput",inputEventInit);if(!isPrevented(beforeInputEvent)){await _dispatch(inputTarget,"input",inputEventInit);}} changeSelection(inputTarget,nextSelectionStart,nextSelectionEnd);if(triggerSelect){await dispatchAndIgnore({target:inputTarget,events:["select"],});}} async function _keyUp(targetResolver,eventInit){eventInit={...eventInit,...currentEventInit.keyup};await _dispatch(resolve(targetResolver),"keyup",eventInit);runTime.key=null;registerSpecialKey(eventInit,false);const finalTarget=resolve(targetResolver);if(eventInit.key===" "&&getTag(finalTarget)==="input"&&finalTarget.type==="checkbox"){await triggerClick(finalTarget,{button:btn.LEFT});}} async function _pointerDown(options){setPointerDownTarget(runTime.pointerTarget,options);if(options?.dataTransfer||options?.files||options?.items){runTime.dataTransfer=createDataTransfer(options);} const pointerDownTarget=runTime.pointerDownTarget;const eventInit={...runTime.position,...currentEventInit.pointerdown,button:options?.button||btn.LEFT,};registerButton(eventInit,true);if(pointerDownTarget!==runTime.previousPointerDownTarget){runTime.clickCount=0;} runTime.touchStartPosition={...runTime.position};runTime.touchStartTimeOffset=globalThis.Date.now();const prevented=await dispatchPointerEvent(pointerDownTarget,"pointerdown",eventInit,{mouse:!pointerDownTarget.disabled&&["mousedown",{...eventInit,detail:runTime.clickCount+1},],touch:["touchstart"],});if(prevented){return;} await triggerFocus(pointerDownTarget);if(eventInit.button===btn.LEFT&&!hasTouch()&&(pointerDownTarget.draggable||runTime.dataTransfer)){runTime.canStartDrag=true;}else if(eventInit.button===btn.RIGHT){await _dispatch(pointerDownTarget,"contextmenu",eventInit);}} async function _pointerUp(options){const target=runTime.pointerTarget;const isLongTap=globalThis.Date.now()-runTime.touchStartTimeOffset>LONG_TAP_DELAY;const pointerDownTarget=runTime.pointerDownTarget;const pointerUpTarget=getPointerTarget(target,options);const eventInit={...runTime.position,...currentEventInit.pointerup,button:options?.button||btn.LEFT,};registerButton(eventInit,false);if(runTime.isDragging){const eventInitWithDT={...eventInit,dataTransfer:runTime.dataTransfer};runTime.dataTransfer=null;runTime.isDragging=false;if(runTime.lastDragOverCancelled){await _dispatch(pointerUpTarget,"drop",eventInitWithDT);} await _dispatch(pointerUpTarget,"dragend",eventInitWithDT);return;} const mouseEventInit={...eventInit,detail:runTime.clickCount+1,};await dispatchPointerEvent(pointerUpTarget,"pointerup",eventInit,{mouse:!pointerUpTarget.disabled&&["mouseup",mouseEventInit],touch:["touchend"],});const touchStartPosition=runTime.touchStartPosition;runTime.touchStartPosition={};if(hasTouch()&&(isDifferentPosition(touchStartPosition)||isLongTap)){return;} let clickTarget;if(hasTouch()){clickTarget=pointerDownTarget===pointerUpTarget&&pointerUpTarget;}else{clickTarget=getFirstCommonParent(pointerUpTarget,pointerDownTarget);} if(clickTarget){await triggerClick(clickTarget,mouseEventInit);if(mouseEventInit.button===btn.LEFT){runTime.clickCount++;if(!hasTouch()&&runTime.clickCount%2===0){await _dispatch(clickTarget,"dblclick",mouseEventInit);}}} setPointerDownTarget(null,options);if(runTime.pointerDownTimeout){globalThis.clearTimeout(runTime.pointerDownTimeout);} runTime.pointerDownTimeout=globalThis.setTimeout(()=>{runTime.clickCount=0;runTime.pointerDownTimeout=0;},DOUBLE_CLICK_DELAY);} async function _press(targetResolver,eventInit,options){await _keyDown(targetResolver,eventInit,options);await _keyUp(targetResolver,eventInit);} async function _select(target,value){const values=ensureArray(value,String);let found=false;for(const option of target.options){option.selected=values.includes(option.value);found||=option.selected;} if(!value){target.selectedIndex=-1;}else if(!found){throw new HootInteractionError(`error when calling \`select()\`: no option found with value "${values.join(", ")}"`);} await _dispatch(target,"change");} class HootInteractionError extends Error{name="HootInteractionError";} const btn={LEFT:0,MIDDLE:1,RIGHT:2,BACK:3,FORWARD:4,};const CAPTURE={capture:true};const DEPRECATED_EVENT_PROPERTIES={keyCode:"key",which:"key",};const DEPRECATED_EVENTS={keypress:"keydown",mousewheel:"wheel",};const DOUBLE_CLICK_DELAY=500;const GLOBAL_TRUSTED_EVENTS_CANCELERS=[["blur",cancelTrustedEvent,CAPTURE],["focus",cancelTrustedEvent,CAPTURE],["focusin",cancelTrustedEvent,CAPTURE],["focusout",cancelTrustedEvent,CAPTURE],["scroll",cancelTrustedEvent,CAPTURE],["scrollend",cancelTrustedEvent,CAPTURE],["select",cancelTrustedEvent,CAPTURE],];const GLOBAL_FILE_INPUT_REGISTERERS=[["click",registerFileInput,CAPTURE],["focus",registerFileInput,CAPTURE],];const GLOBAL_SUBMIT_FORWARDERS=[["submit",redirectSubmit]];const KEY_ALIASES={alt:"Alt",arrowdown:"ArrowDown",arrowleft:"ArrowLeft",arrowright:"ArrowRight",arrowup:"ArrowUp",backspace:"Backspace",control:"Control",delete:"Delete",enter:"Enter",escape:"Escape",meta:"Meta",shift:"Shift",tab:"Tab",caps:"Shift",cmd:"Meta",command:"Meta",ctrl:"Control",del:"Delete",down:"ArrowDown",esc:"Escape",left:"ArrowLeft",right:"ArrowRight",space:" ",up:"ArrowUp",win:"Meta",};const LONG_TAP_DELAY=500;const currentEvents=$create(null);const currentEventInit=$create(null);const currentEventTypes=[];let allowLogs=false;const runTime=getDefaultRunTimeValue();const BUBBLES=0b1;const CANCELABLE=0b10;const VIEW=0b100;function mapEvent(eventInit){return eventInit;} function mapMouseEvent(eventInit){return{button:-1,buttons:runTime.buttons,clientX:eventInit.clientX??eventInit.pageX??eventInit.screenX??0,clientY:eventInit.clientY??eventInit.pageY??eventInit.screenY??0,...runTime.modifierKeys,...eventInit,};} function mapPointerEvent(eventInit){return{...mapMouseEvent(eventInit),button:btn.LEFT,isPrimary:eventInit?.btn?eventInit.btn===btn.LEFT:true,pointerId:1,pointerType:hasTouch()?"touch":"mouse",...eventInit,};} function mapWheelEvent(eventInit){return{...mapMouseEvent(eventInit),button:btn.LEFT,...eventInit,};} function mapTouchEvent(eventInit){const touches=eventInit.targetTouches||eventInit.touches||[new Touch({identifier:0,...eventInit})];return{...eventInit,changedTouches:eventInit.changedTouches||touches,target:eventInit.target,targetTouches:eventInit.targetTouches||touches,touches:eventInit.touches||(eventInit.type==="touchend"?[]:touches),};} function mapInputEvent(eventInit){return{data:null,isComposing:!!runTime.isComposing,...eventInit,};} function mapKeyboardEvent(eventInit){return{isComposing:!!runTime.isComposing,...runTime.modifierKeys,...eventInit,};} __exports.check=check;async function check(target,options){const finalizeEvents=setupEvents("check",options);const element=queryAny(await target,options);if(!isCheckable(element)){throw new HootInteractionError(`cannot call \`check()\`: target should be a checkbox or radio input`);} const checkTarget=getTag(element)==="label"?element.control:element;if(!checkTarget.checked){await _hover(element,options,{implicit:true,originalTarget:target});await _click(options);if(!checkTarget.checked){throw new HootInteractionError(`error when calling \`check()\`: target is not checked after interaction`);}} return finalizeEvents();} __exports.cleanupEvents=cleanupEvents;function cleanupEvents(){if(runTime.pointerDownTimeout){globalThis.clearTimeout(runTime.pointerDownTimeout);} removeChangeTargetListeners();$assign(runTime,getDefaultRunTimeValue());} __exports.clear=clear;async function clear(options){const finalizeEvents=setupEvents("clear",options);const activeElement=getActiveElement();if(!hasTagName(activeElement,"select")&&!isEditable(activeElement)){throw new HootInteractionError(`cannot call \`clear()\`: target should be editable or a element`);} if(manualTarget){await _hover(element,null,{implicit:true,originalTarget:manualTarget});await _pointerDown();} await _select(element,value);if(manualTarget){await _pointerUp();} return finalizeEvents();} __exports.setInputFiles=setInputFiles;async function setInputFiles(files,options){if(!runTime.fileInput){throw new HootInteractionError(`cannot call \`setInputFiles()\`: no file input has been interacted with`);} const finalizeEvents=setupEvents("setInputFiles",options);await _fill(runTime.fileInput,files,options);runTime.fileInput=null;return finalizeEvents();} __exports.setInputRange=setInputRange;async function setInputRange(target,value,options){const finalizeEvents=setupEvents("setInputRange",options);const element=queryAny(await target,options);await _hover(element,options,{implicit:true,originalTarget:target});await _pointerDown(options);await _fill(element,value,options);await _pointerUp(options);return finalizeEvents();} __exports.setupEventActions=setupEventActions;function setupEventActions(target,options){const eventHandlers=[];if(!options?.allowTrustedEvents){eventHandlers.push(...GLOBAL_TRUSTED_EVENTS_CANCELERS);} if(!options?.noFileInputRegistration){eventHandlers.push(...GLOBAL_FILE_INPUT_REGISTERERS);} if(!options?.allowSubmit){eventHandlers.push(...GLOBAL_SUBMIT_FORWARDERS);} const view=getWindow(target);for(const[eventType,handler,options]of eventHandlers){view.addEventListener(eventType,handler,options);} return function cleanupEventActions(){for(const[eventType,handler,options]of eventHandlers){view.removeEventListener(eventType,handler,options);}};} __exports.uncheck=uncheck;async function uncheck(target,options){const finalizeEvents=setupEvents("uncheck",options);const element=queryAny(await target,options);if(!isCheckable(element)){throw new HootInteractionError(`cannot call \`uncheck()\`: target should be a checkbox or radio input`);} const checkTarget=getTag(element)==="label"?element.control:element;if(checkTarget.checked){await _hover(element,options,{implicit:true,originalTarget:target});await _click(options);if(checkTarget.checked){throw new HootInteractionError(`error when calling \`uncheck()\`: target is still checked after interaction`);}} return finalizeEvents();} __exports.unload=unload;async function unload(options){const finalizeEvents=setupEvents("unload",options);await _dispatch(getWindow(),"beforeunload");return finalizeEvents();} const EventList=__exports.EventList=class EventList extends Array{constructor(...args){super(...args.flat());} get(predicate){return this.getAll(predicate)[0]||null;} getAll(predicate){if(typeof predicate!=="function"){const type=predicate;predicate=function isSameType(ev){return ev.type===type;};} return this.filter(predicate);}} return __exports;});; /* /web/static/lib/hoot-dom/helpers/time.js */ odoo.define('@web/../lib/hoot-dom/helpers/time',['@web/../lib/hoot-dom/hoot_dom_utils'],function(require){'use strict';let __exports={};const{isInstanceOf}=require("@web/../lib/hoot-dom/hoot_dom_utils");const{cancelAnimationFrame,clearInterval,clearTimeout,Error,Math:{ceil:$ceil,floor:$floor,max:$max,min:$min},Number,performance,Promise,requestAnimationFrame,setInterval,setTimeout,}=globalThis;const $performanceNow=performance.now.bind(performance);function animationToId(id){return ID_PREFIX.animation+String(id);} function getNextTimerValues(){let timerValues=null;for(const[internalId,[callback,init,delay]]of timers.entries()){const timeout=init+delay;if(!timerValues||timeout0){timeOffset+=$min(remaining,diff);remaining=$max(remaining-diff,0);} if(timers.has(id)){handler(timeout);}} if(remaining>0){timeOffset+=remaining;} if(options?.animationFrame??true){await animationFrame();} allowTimers=true;return ms;} __exports.animationFrame=animationFrame;function animationFrame(){return new Promise((resolve)=>requestAnimationFrame(()=>setTimeout(resolve)));} __exports.cancelAllTimers=cancelAllTimers;function cancelAllTimers(){for(const id of timers.keys()){if(id.startsWith(ID_PREFIX.animation)){globalThis.cancelAnimationFrame(idToAnimation(id));}else if(id.startsWith(ID_PREFIX.interval)){globalThis.clearInterval(idToInterval(id));}else if(id.startsWith(ID_PREFIX.timeout)){globalThis.clearTimeout(idToTimeout(id));}}} __exports.cleanupTime=cleanupTime;function cleanupTime(){allowTimers=false;frozen=false;cancelAllTimers();return delay();} __exports.delay=delay;function delay(duration){return new Promise((resolve)=>setTimeout(resolve,duration));} __exports.freezeTime=freezeTime;function freezeTime(){frozen=true;} __exports.unfreezeTime=unfreezeTime;function unfreezeTime(){frozen=false;} __exports.getTimeOffset=getTimeOffset;function getTimeOffset(){return timeOffset;} __exports.isTimeFrozen=isTimeFrozen;function isTimeFrozen(){return frozen;} __exports.microTick=microTick;function microTick(){return new Promise(queueMicrotask);} __exports.mockedCancelAnimationFrame=mockedCancelAnimationFrame;function mockedCancelAnimationFrame(handle){if(!frozen){cancelAnimationFrame(handle);} timers.delete(animationToId(handle));} __exports.mockedClearInterval=mockedClearInterval;function mockedClearInterval(intervalId){if(!frozen){clearInterval(intervalId);} timers.delete(intervalToId(intervalId));} __exports.mockedClearTimeout=mockedClearTimeout;function mockedClearTimeout(timeoutId){if(!frozen){clearTimeout(timeoutId);} timers.delete(timeoutToId(timeoutId));} __exports.mockedRequestAnimationFrame=mockedRequestAnimationFrame;function mockedRequestAnimationFrame(callback){if(!allowTimers){return 0;} function handler(){mockedCancelAnimationFrame(handle);return callback(now());} const animationValues=[handler,now(),frameDelay];const handle=frozen?nextDummyId++:requestAnimationFrame(handler);const internalId=animationToId(handle);timers.set(internalId,animationValues);return handle;} __exports.mockedSetInterval=mockedSetInterval;function mockedSetInterval(callback,ms,...args){if(!allowTimers){return 0;} ms=parseNat(ms);function handler(){if(allowTimers){intervalValues[1]=$max(now(),intervalValues[1]+ms);}else{mockedClearInterval(intervalId);} return callback(...args);} const intervalValues=[handler,now(),ms];const intervalId=frozen?nextDummyId++:setInterval(handler,ms);const internalId=intervalToId(intervalId);timers.set(internalId,intervalValues);return intervalId;} __exports.mockedSetTimeout=mockedSetTimeout;function mockedSetTimeout(callback,ms,...args){if(!allowTimers){return 0;} ms=parseNat(ms);function handler(){mockedClearTimeout(timeoutId);return callback(...args);} const timeoutValues=[handler,now(),ms];const timeoutId=frozen?nextDummyId++:setTimeout(handler,ms);const internalId=timeoutToId(timeoutId);timers.set(internalId,timeoutValues);return timeoutId;} __exports.resetTimeOffset=resetTimeOffset;function resetTimeOffset(){timeOffset=0;} __exports.runAllTimers=runAllTimers;function runAllTimers(options){if(!timers.size){return 0;} const endts=$max(...[...timers.values()].map(([,init,delay])=>init+delay));return advanceTime($ceil(endts-now()),options);} __exports.setFrameRate=setFrameRate;function setFrameRate(frameRate){frameRate=parseNat(frameRate);if(frameRate<1||frameRate>1000){throw new HootTimingError("frame rate must be an number between 1 and 1000");} frameDelay=1000/frameRate;} __exports.setupTime=setupTime;function setupTime(){allowTimers=true;} __exports.tick=tick;function tick(){return delay();} __exports.waitUntil=waitUntil;async function waitUntil(predicate,options){await Promise.resolve();const result=predicate(false);if(result){return result;} const timeout=$floor(options?.timeout??200);const maxFrameCount=$ceil(timeout/frameDelay);let frameCount=0;let handle;return new Promise((resolve,reject)=>{function runCheck(){const isLast=++frameCount>=maxFrameCount;const result=predicate(isLast);if(result){resolve(result);}else if(!isLast){handle=requestAnimationFrame(runCheck);}else{let message=options?.message||`'waitUntil' timed out after %timeout% milliseconds`;if(typeof message==="function"){message=message();} if(isInstanceOf(message,Error)){reject(message);}else{reject(new HootTimingError(message.replace("%timeout%",String(timeout))));}}} handle=requestAnimationFrame(runCheck);}).finally(()=>{cancelAnimationFrame(handle);});} const Deferred=__exports.Deferred=class Deferred extends Promise{_resolve;_reject;constructor(executor){let _resolve,_reject;super(function deferredResolver(resolve,reject){_resolve=resolve;_reject=reject;executor?.(_resolve,_reject);});this._resolve=_resolve;this._reject=_reject;} async reject(reason){return this._reject(reason);} async resolve(value){return this._resolve(value);}} return __exports;});; /* /web/static/lib/hoot-dom/hoot-dom.js */ odoo.define('@web/../lib/hoot-dom/hoot-dom',['@web/../lib/hoot-dom/helpers/dom','@web/../lib/hoot-dom/helpers/events','@web/../lib/hoot-dom/helpers/time','@web/../lib/hoot-dom/hoot_dom_utils'],function(require){'use strict';let __exports={};const dom=require("@web/../lib/hoot-dom/helpers/dom");const events=require("@web/../lib/hoot-dom/helpers/events");const time=require("@web/../lib/hoot-dom/helpers/time");const{interactor}=require("@web/../lib/hoot-dom/hoot_dom_utils");{const{formatXml,getActiveElement,getFocusableElements,getNextFocusableElement,getParentFrame,getPreviousFocusableElement,isDisplayed,isEditable,isFocusable,isInDOM,isInViewPort,isScrollable,isVisible,matches,queryAll,queryAllAttributes,queryAllProperties,queryAllRects,queryAllTexts,queryAllValues,queryAny,queryAttribute,queryFirst,queryOne,queryRect,queryText,queryValue,}=require("@web/../lib/hoot-dom/helpers/dom");Object.assign(__exports,{formatXml,getActiveElement,getFocusableElements,getNextFocusableElement,getParentFrame,getPreviousFocusableElement,isDisplayed,isEditable,isFocusable,isInDOM,isInViewPort,isScrollable,isVisible,matches,queryAll,queryAllAttributes,queryAllProperties,queryAllRects,queryAllTexts,queryAllValues,queryAny,queryAttribute,queryFirst,queryOne,queryRect,queryText,queryValue,})};{const{on}=require("@web/../lib/hoot-dom/helpers/events");Object.assign(__exports,{on})};{const{animationFrame,cancelAllTimers,Deferred,delay,freezeTime,unfreezeTime,microTick,setFrameRate,tick,waitUntil,}=require("@web/../lib/hoot-dom/helpers/time");Object.assign(__exports,{animationFrame,cancelAllTimers,Deferred,delay,freezeTime,unfreezeTime,microTick,setFrameRate,tick,waitUntil,})};const waitFor=__exports.waitFor=interactor("query",dom.waitFor);const waitForNone=__exports.waitForNone=interactor("query",dom.waitForNone);const check=__exports.check=interactor("interaction",events.check);const clear=__exports.clear=interactor("interaction",events.clear);const click=__exports.click=interactor("interaction",events.click);const dblclick=__exports.dblclick=interactor("interaction",events.dblclick);const drag=__exports.drag=interactor("interaction",events.drag);const edit=__exports.edit=interactor("interaction",events.edit);const fill=__exports.fill=interactor("interaction",events.fill);const hover=__exports.hover=interactor("interaction",events.hover);const keyDown=__exports.keyDown=interactor("interaction",events.keyDown);const keyUp=__exports.keyUp=interactor("interaction",events.keyUp);const leave=__exports.leave=interactor("interaction",events.leave);const manuallyDispatchProgrammaticEvent=__exports.manuallyDispatchProgrammaticEvent=interactor("interaction",events.dispatch);const middleClick=__exports.middleClick=interactor("interaction",events.middleClick);const pointerDown=__exports.pointerDown=interactor("interaction",events.pointerDown);const pointerUp=__exports.pointerUp=interactor("interaction",events.pointerUp);const press=__exports.press=interactor("interaction",events.press);const resize=__exports.resize=interactor("interaction",events.resize);const rightClick=__exports.rightClick=interactor("interaction",events.rightClick);const scroll=__exports.scroll=interactor("interaction",events.scroll);const select=__exports.select=interactor("interaction",events.select);const setInputFiles=__exports.setInputFiles=interactor("interaction",events.setInputFiles);const setInputRange=__exports.setInputRange=interactor("interaction",events.setInputRange);const uncheck=__exports.uncheck=interactor("interaction",events.uncheck);const unload=__exports.unload=interactor("interaction",events.unload);const advanceFrame=__exports.advanceFrame=interactor("time",time.advanceFrame);const advanceTime=__exports.advanceTime=interactor("time",time.advanceTime);const runAllTimers=__exports.runAllTimers=interactor("time",time.runAllTimers);{const{exposeHelpers}=require("@web/../lib/hoot-dom/hoot_dom_utils");Object.assign(__exports,{exposeHelpers})};return __exports;});odoo.define(`@odoo/hoot-dom`,['@web/../lib/hoot-dom/hoot-dom'],function(require){return require('@web/../lib/hoot-dom/hoot-dom');});; /* /web/static/lib/hoot-dom/hoot_dom_utils.js */ odoo.define('@web/../lib/hoot-dom/hoot_dom_utils',[],function(require){'use strict';let __exports={};const{Array:{isArray:$isArray},matchMedia,navigator:{userAgent:$userAgent},Object:{assign:$assign,getPrototypeOf:$getPrototypeOf},RegExp,SyntaxError,}=globalThis;const $toString=Object.prototype.toString;function makeInteractorFn(type,fn,name,alias){return{[alias||name](...args){const result=fn(...args);if(isPromise(result)){for(let i=0;i(args[i]=result));}} return result.then((promiseResult)=>dispatchInteraction(type,name,alias,args,promiseResult));}else{return dispatchInteraction(type,name,alias,args,result);}},}[alias||name];} function polyfillIsError(value){return $toString.call(value)==="[object Error]";} const GRAYS={100:"#f1f5f9",200:"#e2e8f0",300:"#cbd5e1",400:"#94a3b8",500:"#64748b",600:"#475569",700:"#334155",800:"#1e293b",900:"#0f172a",};const COLORS={default:{black:"#000000",white:"#ffffff","gray-100":GRAYS[100],"gray-200":GRAYS[200],"gray-300":GRAYS[300],"gray-400":GRAYS[400],"gray-500":GRAYS[500],"gray-600":GRAYS[600],"gray-700":GRAYS[700],"gray-800":GRAYS[800],"gray-900":GRAYS[900],},light:{primary:"#714b67",secondary:"#74b4b9",amber:"#f59e0b","amber-900":"#fef3c7",blue:"#3b82f6","blue-900":"#dbeafe",cyan:"#0891b2","cyan-900":"#e0f2fe",emerald:"#047857","emerald-900":"#ecfdf5",gray:GRAYS[400],lime:"#84cc16","lime-900":"#f7fee7",orange:"#ea580c","orange-900":"#ffedd5",purple:"#581c87","purple-900":"#f3e8ff",rose:"#9f1239","rose-900":"#fecdd3",bg:GRAYS[100],text:GRAYS[900],"status-bg":GRAYS[300],"link-text-hover":"var(--primary)","btn-bg":"#714b67","btn-bg-hover":"#624159","btn-text":"#ffffff","bg-result":"rgba(255, 255, 255, 0.6)","border-result":GRAYS[300],"border-search":"#d8dadd","shadow-opacity":0.1,"bg-report":"#ffffff","text-report":"#202124","border-report":"#f0f0f0","bg-report-error":"#fff0f0","text-report-error":"#ff0000","border-report-error":"#ffd6d6","text-report-number":"#1a1aa6","text-report-string":"#c80000","text-report-key":"#881280","text-report-html-tag":"#881280","text-report-html-id":"#1a1aa8","text-report-html-class":"#994500",},dark:{primary:"#14b8a6",amber:"#fbbf24","amber-900":"#422006",blue:"#60a5fa","blue-900":"#172554",cyan:"#22d3ee","cyan-900":"#083344",emerald:"#34d399","emerald-900":"#064e3b",gray:GRAYS[500],lime:"#bef264","lime-900":"#365314",orange:"#fb923c","orange-900":"#431407",purple:"#a855f7","purple-900":"#3b0764",rose:"#fb7185","rose-900":"#4c0519",bg:GRAYS[900],text:GRAYS[100],"status-bg":GRAYS[700],"btn-bg":"#00dac5","btn-bg-hover":"#00c1ae","btn-text":"#000000","bg-result":"rgba(0, 0, 0, 0.5)","border-result":GRAYS[600],"border-search":"#3c3f4c","shadow-opacity":0.4,"bg-report":"#202124","text-report":"#e8eaed","border-report":"#3a3a3a","bg-report-error":"#290000","text-report-error":"#ff8080","border-report-error":"#5c0000","text-report-number":"#9980ff","text-report-string":"#f28b54","text-report-key":"#5db0d7","text-report-html-tag":"#5db0d7","text-report-html-id":"#f29364","text-report-html-class":"#9bbbdc",},};const DEBUG_NAMESPACE="hoot";const isError=typeof Error.isError==="function"?Error.isError:polyfillIsError;const interactionBus=new EventTarget();const preferredColorScheme=matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";__exports.addInteractionListener=addInteractionListener;function addInteractionListener(types,callback){for(const type of types){interactionBus.addEventListener(type,callback);} return function removeInteractionListener(){for(const type of types){interactionBus.removeEventListener(type,callback);}};} __exports.dispatchInteraction=dispatchInteraction;function dispatchInteraction(type,name,alias,args,returnValue){interactionBus.dispatchEvent(new CustomEvent(type,{detail:[name,alias,args,returnValue],}));return returnValue;} __exports.exposeHelpers=exposeHelpers;function exposeHelpers(...helpers){let nameSpaceIndex=1;let nameSpace=DEBUG_NAMESPACE;while(nameSpace in globalThis){nameSpace=`${DEBUG_NAMESPACE}${nameSpaceIndex++}`;} globalThis[nameSpace]=new HootDebugHelpers(...helpers);return nameSpace;} __exports.getAllColors=getAllColors;function getAllColors(scheme){return scheme?COLORS[scheme]:COLORS;} __exports.getColorHex=getColorHex;function getColorHex(varName){return COLORS[preferredColorScheme][varName];} __exports.getPreferredColorScheme=getPreferredColorScheme;function getPreferredColorScheme(){return preferredColorScheme;} __exports.getTag=getTag;function getTag(node){return node?.nodeName?.toLowerCase()||"";} __exports.interactor=interactor;function interactor(type,fn){return $assign(makeInteractorFn(type,fn,fn.name),{as(alias){return makeInteractorFn(type,fn,fn.name,alias);},get silent(){return fn;},});} __exports.isFirefox=isFirefox;function isFirefox(){return/firefox/i.test($userAgent);} Array.isArray;__exports.isPromise=isPromise;function isPromise(instance){return instance&&typeof instance.then==="function";} __exports.isInstanceOf=isInstanceOf;function isInstanceOf(instance,...classes){if(!classes.length){return instance instanceof classes[0];} if(!instance||Object(instance)!==instance){return false;} for(const cls of classes){if(instance instanceof cls){return true;} const targetName=cls.name;if(!targetName){return false;} if(targetName==="Array"){return $isArray(instance);} if(targetName==="Error"){return isError(instance);} if($toString.call(instance)===`[object ${targetName}]`){return true;} let{constructor}=instance;while(constructor){if(constructor.name===targetName){return true;} constructor=$getPrototypeOf(constructor);}} return false;} __exports.isIterable=isIterable;function isIterable(object){return!!(object&&typeof object==="object"&&object[Symbol.iterator]);} __exports.parseRegExp=parseRegExp;function parseRegExp(value,options){const regexParams=value.match(R_REGEX);if(regexParams){const unified=regexParams[1].replace(R_WHITE_SPACE,"\\s+");const flag=regexParams[2];try{return new RegExp(unified,flag);}catch(error){if(isInstanceOf(error,SyntaxError)&&options?.safe){return value;}else{throw error;}}} return value;} __exports.toSelector=toSelector;function toSelector(node,options){const tagName=getTag(node);const id=node.id?`#${node.id}`:"";const classNames=node.classList?[...node.classList].map((className)=>`.${className}`):[];if(options?.raw){return{tagName,id,classNames};}else{return[tagName,id,...classNames].join("");}} const HootDebugHelpers=__exports.HootDebugHelpers=class HootDebugHelpers{constructor(...helpers){$assign(this,...helpers);}} const REGEX_MARKER=__exports.REGEX_MARKER="/";const R_REGEX=__exports.R_REGEX=new RegExp(`^${REGEX_MARKER}(.*)${REGEX_MARKER}([dgimsuvy]+)?$`);const R_WHITE_SPACE=__exports.R_WHITE_SPACE=/\s+/g;return __exports;});; /* /web_tour/static/src/js/tour_step.js */ odoo.define('@web_tour/js/tour_step',['@web/session','@web/core/ui/ui_service','@odoo/hoot-dom','@web/core/utils/objects'],function(require){'use strict';let __exports={};const{session}=require("@web/session");const{utils}=require("@web/core/ui/ui_service");const hoot=require("@odoo/hoot-dom");const{pick}=require("@web/core/utils/objects");const TourStep=__exports.TourStep=class TourStep{constructor(data,tour){Object.assign(this,data);this.tour=tour;} get active(){this.checkHasTour();const mode=this.tour.mode;const isSmall=utils.isSmall();const standardKeyWords=["enterprise","community","mobile","desktop","auto","manual"];const isActiveArray=Array.isArray(this.isActive)?this.isActive:[];if(isActiveArray.length===0){return true;} const selectors=isActiveArray.filter((key)=>!standardKeyWords.includes(key));if(selectors.length){for(const selector of selectors){const el=hoot.queryFirst(selector);if(!el){return false;}}} const checkMode=isActiveArray.includes(mode)||(!isActiveArray.includes("manual")&&!isActiveArray.includes("auto"));const edition=(session.server_version_info||"").at(-1)==="e"?"enterprise":"community";const checkEdition=isActiveArray.includes(edition)||(!isActiveArray.includes("enterprise")&&!isActiveArray.includes("community"));const onlyForMobile=isActiveArray.includes("mobile")&&isSmall;const onlyForDesktop=isActiveArray.includes("desktop")&&!isSmall;const checkDevice=onlyForMobile||onlyForDesktop||(!isActiveArray.includes("mobile")&&!isActiveArray.includes("desktop"));return checkEdition&&checkDevice&&checkMode;} checkHasTour(){if(!this.tour){throw new Error(`TourStep instance must have a tour`);}} get describeMe(){this.checkHasTour();return(`[${this.index + 1}/${this.tour.steps.length}] Tour ${this.tour.name} → Step `+ (this.content?`${this.content} (trigger: ${this.trigger})`:this.trigger));} get stringify(){return(JSON.stringify(pick(this,"isActive","content","trigger","run","tooltipPosition","timeout","expectUnloadPage"),(_key,value)=>{if(typeof value==="function"){return"[function]";}else{return value;}},2)+",");}} return __exports;});; /* /web_tour/static/src/js/tour_interactive/tour_interactive.js */ odoo.define('@web_tour/js/tour_interactive/tour_interactive',['@web_tour/js/tour_state','@web/core/utils/timing','@odoo/hoot-dom','@web/core/ui/ui_service','@web_tour/js/tour_step','@web/core/macro','@web_tour/js/utils/tour_utils'],function(require){'use strict';let __exports={};const{tourState}=require("@web_tour/js/tour_state");const{debounce}=require("@web/core/utils/timing");const hoot=require("@odoo/hoot-dom");const{utils}=require("@web/core/ui/ui_service");const{TourStep}=require("@web_tour/js/tour_step");const{MacroMutationObserver}=require("@web/core/macro");const{getScrollParent}=require("@web_tour/js/utils/tour_utils");const TourInteractive=__exports.TourInteractive=class TourInteractive{mode="manual";currentAction;currentActionIndex;anchorEls=[];removeListeners=()=>{};constructor(data){Object.assign(this,data);this.steps=this.steps.map((step)=>new TourStep(step,this));this.actions=this.steps.flatMap((s)=>this.getSubActions(s));this.isBusy=false;} start(env,pointer,onTourEnd){env.bus.addEventListener("ACTION_MANAGER:UPDATE",()=>(this.isBusy=true));env.bus.addEventListener("ACTION_MANAGER:UI-UPDATED",()=>(this.isBusy=false));this.pointer=pointer;this.debouncedToggleOpen=debounce(this.pointer.showContent,50,true);this.onTourEnd=onTourEnd;this.observer=new MacroMutationObserver(()=>this._onMutation());this.observer.observe(document.body);this.currentActionIndex=tourState.getCurrentIndex();this.play();} backward(){let tempIndex=this.currentActionIndex;let tempAction,tempAnchors=[];while(!tempAnchors.length&&tempIndex>=0){tempIndex--;tempAction=this.actions.at(tempIndex);if(!tempAction.step.active||tempAction.event==="warn"){continue;} tempAnchors=tempAction&&this.findTriggers(tempAction.anchor);} if(tempIndex>=0){this.currentActionIndex=tempIndex;this.play();}} findTriggers(anchor){if(!anchor){anchor=this.currentAction.anchor;} return anchor.split(/,\s*(?![^(]*\))/).map((part)=>hoot.queryFirst(part,{visible:true})).filter((el)=>!!el).map((el)=>this.getAnchorEl(el,this.currentAction.event)).filter((el)=>!!el);} play(){this.removeListeners();if(this.currentActionIndex===this.actions.length){this.observer.disconnect();this.onTourEnd();return;} this.currentAction=this.actions.at(this.currentActionIndex);if(!this.currentAction.step.active||this.currentAction.event==="warn"){if(this.currentAction.event==="warn"){console.warn(`Step '${this.currentAction.anchor}' ignored.`);} this.currentActionIndex++;this.play();return;} console.log(this.currentAction.event,this.currentAction.anchor);tourState.setCurrentIndex(this.currentActionIndex);this.anchorEls=this.findTriggers();this.setActionListeners();this.updatePointer();} updatePointer(){if(this.anchorEls.length){this.pointer.pointTo(this.anchorEls[0],this.currentAction.pointerInfo,this.currentAction.event==="drop");this.pointer.setState({onMouseEnter:()=>this.debouncedToggleOpen(true),onMouseLeave:()=>this.debouncedToggleOpen(false),});}} setActionListeners(){const cleanups=this.anchorEls.flatMap((anchorEl,index)=>{const toListen={anchorEl,consumeEvents:this.getConsumeEventType(anchorEl,this.currentAction.event),onConsume:()=>{this.pointer.hide();this.currentActionIndex++;this.play();},onError:()=>{if(this.currentAction.event==="drop"){this.pointer.hide();this.currentActionIndex--;this.play();}},};if(index===0){return this.setupListeners({...toListen,onMouseEnter:()=>this.pointer.showContent(true),onMouseLeave:()=>this.pointer.showContent(false),onScroll:()=>this.updatePointer(),});}else{return this.setupListeners({...toListen,onScroll:()=>{},});}});this.removeListeners=()=>{this.anchorEls=[];while(cleanups.length){cleanups.pop()();}};} setupListeners({anchorEl,consumeEvents,onMouseEnter,onMouseLeave,onScroll,onConsume,onError=()=>{},}){consumeEvents=consumeEvents.map((c)=>({target:c.target,type:c.name,listener:function(ev){if(!c.conditional||c.conditional(ev)){onConsume();}else{onError();}},}));for(const consume of consumeEvents){consume.target.addEventListener(consume.type,consume.listener,true);} anchorEl.addEventListener("mouseenter",onMouseEnter);anchorEl.addEventListener("mouseleave",onMouseLeave);const cleanups=[()=>{for(const consume of consumeEvents){consume.target.removeEventListener(consume.type,consume.listener,true);} anchorEl.removeEventListener("mouseenter",onMouseEnter);anchorEl.removeEventListener("mouseleave",onMouseLeave);},];const scrollEl=getScrollParent(anchorEl);if(scrollEl){const debouncedOnScroll=debounce(onScroll,50);scrollEl.addEventListener("scroll",debouncedOnScroll);cleanups.push(()=>scrollEl.removeEventListener("scroll",debouncedOnScroll));} return cleanups;} getSubActions(step){const actions=[];if(!step.run||typeof step.run==="function"){actions.push({step,event:"warn",anchor:step.trigger,});return actions;} for(const todo of step.run.split("&&")){const m=String(todo).trim().match(/^(?\w*) *\(? *(?.*?)\)?$/);let action=m.groups?.action;const anchor=m.groups?.arguments||step.trigger;const pointerInfo={content:step.content,tooltipPosition:step.tooltipPosition,};if(action==="drag_and_drop"){actions.push({step,event:"drag",anchor:step.trigger,pointerInfo,});action="drop";} actions.push({step,event:action,anchor:action==="edit"?step.trigger:anchor,pointerInfo,});} return actions;} getConsumeEventType(element,runCommand){const consumeEvents=[];if(runCommand==="click"){consumeEvents.push({name:"click",target:element,});if(element.querySelector(".o-autocomplete--input")){consumeEvents.push({name:"keydown",target:element.querySelector(".o-autocomplete--input"),conditional:(ev)=>["Tab","Enter"].includes(ev.key)&&ev.target.parentElement.querySelector(".o-autocomplete--dropdown-item .ui-state-active"),});} if(element.closest(".o-autocomplete--dropdown-menu")){consumeEvents.push({name:"keydown",target:element.closest(".o-autocomplete").querySelector("input"),conditional:(ev)=>["Tab","Enter"].includes(ev.key),});} if(element.tagName==="BUTTON"){consumeEvents.push({name:"keydown",target:element,conditional:(ev)=>ev.key==="Enter",});if(element.closest(".input-group")){for(const inputEl of element.parentElement.querySelectorAll("input")){consumeEvents.push({name:"keydown",target:inputEl,conditional:(ev)=>ev.key==="Enter",});}}}} if(["fill","edit"].includes(runCommand)){if(utils.isSmall()&&element.closest(".o_field_widget")?.matches(".o_field_many2one, .o_field_many2many")){consumeEvents.push({name:"click",target:element,});}else{consumeEvents.push({name:"input",target:element,});if(element.classList.contains("o-autocomplete--input")){consumeEvents.push({name:"keydown",target:element,conditional:(ev)=>{if(["Tab","Enter"].includes(ev.key)&&ev.target.parentElement.querySelector(".o-autocomplete--dropdown-item .ui-state-active")){const nextStep=this.actions.at(this.currentActionIndex+1);if(this.findTriggers(nextStep.anchor).at(0)?.closest(".o-autocomplete--dropdown-item")){this.currentActionIndex++;} return true;}},});consumeEvents.push({name:"click",target:element.ownerDocument,conditional:(ev)=>{if(ev.target.closest(".o-autocomplete--dropdown-item")){const nextStep=this.actions.at(this.currentActionIndex+1);if(this.findTriggers(nextStep.anchor).at(0)?.closest(".o-autocomplete--dropdown-item")){this.currentActionIndex++;} return true;}},});}}} if(runCommand==="drag"){consumeEvents.push({name:"pointerdown",target:element,});} if(runCommand==="drop"){consumeEvents.push({name:"pointerup",target:element.ownerDocument,conditional:(ev)=>element.ownerDocument.elementsFromPoint(ev.clientX,ev.clientY).includes(element),});consumeEvents.push({name:"drop",target:element.ownerDocument,conditional:(ev)=>element.ownerDocument.elementsFromPoint(ev.clientX,ev.clientY).includes(element),});} return consumeEvents;} getAnchorEl(el,consumeEvent){if(consumeEvent==="drag"){return el.closest(".ui-draggable, .o_draggable, .o_we_draggable, .o-draggable, [draggable='true']");} if(consumeEvent==="input"&&!["textarea","input"].includes(el.tagName.toLowerCase())){return el.closest("[contenteditable='true']");} if(consumeEvent==="sort"){return el.closest(".ui-sortable, .o_sortable");} return el;} _onMutation(){if(this.currentAction){const tempAnchors=this.findTriggers();if(tempAnchors.length&&(tempAnchors.some((a)=>!this.anchorEls.includes(a))||this.anchorEls.some((a)=>!tempAnchors.includes(a)))){this.removeListeners();this.anchorEls=tempAnchors;this.setActionListeners();}else if(!tempAnchors.length&&this.anchorEls.length){this.pointer.hide();if(!hoot.queryFirst(".o_home_menu",{visible:true})&&!hoot.queryFirst(".dropdown-item.o_loading",{visible:true})&&!this.isBusy){this.backward();} return;} this.updatePointer();}}} return __exports;});