1import{Controller}from"@hotwired/stimulus";export default class extends Controller{static classes=["activeTab","inactiveTab","pastTab","futureTab"];static targets=["tab","panel","select","tabList","progressBar","template"];static values={stylesheetId:String,index:0,updateAnchor:Boolean,scrollToAnchor:Boolean,scrollActiveTabIntoView:Boolean,autoSwitch:Boolean,autoSwitchInterval:{type:Number,default:5e3},pauseOnHover:{type:Boolean,default:!0},showProgressBar:Boolean,lazyLoad:{type:Boolean,default:!1},turboFrameSrc:{type:String,default:""},arrowFocusOnly:{type:Boolean,default:!1}};get ownTabTargets(){return this.tabTargets.filter(t=>this.#t(t))}get ownPanelTargets(){return this.panelTargets.filter(t=>this.#t(t))}initialize(){this.initialLoad=!0,this.hadInitialAnchor=!!this.anchor,this.updateAnchorValue&&this.anchor&&(this.indexValue=this.ownTabTargets.findIndex(t=>t.id===this.anchor)),this.autoSwitchTimer=null,this.startTime=null,this.isPaused=!1,this.remainingTime=0,this.currentProgress=0,this.loadedPanels=new Set,this.focusedTabIndex=this.indexValue}async connect(){this.connected=!0,0!==this.tabsCount&&(this.indexValue=this.normalizedEnabledIndex(this.indexValue),this.focusedTabIndex=this.indexValue,await this.showTab(),this.connected&&(this.setInitialFocus(),this.revealTabs(),this.addKeyboardEventListeners(),this.autoSwitchValue&&(this.startAutoSwitch(),this.addHoverEventListeners()),this.initialLoad=!1))}disconnect(){this.connected=!1,this.removeKeyboardEventListeners(),this.removeHoverEventListeners(),this.stopAutoSwitch(),null!=this.lazyLoadFrame&&(cancelAnimationFrame(this.lazyLoadFrame),this.lazyLoadFrame=null)}addKeyboardEventListeners(){this.keydownHandler=this.handleKeydown.bind(this),this.tabFocusHandler=this.handleFocus.bind(this),this.ownTabTargets.forEach(t=>{t.addEventListener("keydown",this.keydownHandler),t.addEventListener("focus",this.tabFocusHandler)})}removeKeyboardEventListeners(){this.keydownHandler&&this.ownTabTargets.forEach(t=>{t.removeEventListener("keydown",this.keydownHandler),t.removeEventListener("focus",this.tabFocusHandler)}),this.keydownHandler=null,this.tabFocusHandler=null}addHoverEventListeners(){this.pauseOnHoverValue&&(this.pointerInside=!1,this.mouseEnterHandler=()=>{this.pointerInside=!0,this.pauseAutoSwitch()},this.mouseLeaveHandler=()=>{this.pointerInside=!1,this.resumeAutoSwitchIfIdle()},this.hoverFocusHandler=()=>this.pauseAutoSwitch(),this.blurHandler=t=>{t.relatedTarget&&this.element.contains(t.relatedTarget)||this.resumeAutoSwitchIfIdle()},this.element.addEventListener("mouseenter",this.mouseEnterHandler),this.element.addEventListener("mouseleave",this.mouseLeaveHandler),this.element.addEventListener("focusin",this.hoverFocusHandler),this.element.addEventListener("focusout",this.blurHandler))}removeHoverEventListeners(){this.mouseEnterHandler&&(this.element.removeEventListener("mouseenter",this.mouseEnterHandler),this.element.removeEventListener("mouseleave",this.mouseLeaveHandler),this.element.removeEventListener("focusin",this.hoverFocusHandler),this.element.removeEventListener("focusout",this.blurHandler)),this.mouseEnterHandler=null,this.mouseLeaveHandler=null,this.hoverFocusHandler=null,this.blurHandler=null}handleFocus(t){const e=t.target.closest('[data-tabs-target="tab"]');if(e&&!this.isTabDisabled(e)){const t=this.ownTabTargets.indexOf(e);-1!==t&&(this.focusedTabIndex=t)}}handleKeydown(t){const e=t.target.closest('[data-tabs-target="tab"]');if(!this.ownTabTargets.includes(t.target)&&!this.ownTabTargets.includes(e))return;const s=this.getOrientation();switch(t.key){case"ArrowLeft":if("vertical"===s)return;t.preventDefault(),this.arrowFocusOnlyValue?this.previousTabFocusOnly():this.previousTab();break;case"ArrowRight":if("vertical"===s)return;t.preventDefault(),this.arrowFocusOnlyValue?this.nextTabFocusOnly():this.nextTab();break;case"ArrowUp":if("horizontal"===s)return;t.preventDefault(),this.arrowFocusOnlyValue?this.previousTabFocusOnly():this.previousTab();break;case"ArrowDown":if("horizontal"===s)return;t.preventDefault(),this.arrowFocusOnlyValue?this.nextTabFocusOnl
1y():this.nextTab();break;case"Home":t.preventDefault(),this.arrowFocusOnlyValue?this.firstTabFocusOnly():this.firstTab();break;case"End":t.preventDefault(),this.arrowFocusOnlyValue?this.lastTabFocusOnly():this.lastTab()}}change(t){let e;const s="SELECT"===t.currentTarget.tagName;if(!s&&!this.#t(t.currentTarget))return;if(s)e=this.#e(t.currentTarget);else if(t.currentTarget.dataset.index)e=parseInt(t.currentTarget.dataset.index);else if(t.currentTarget.dataset.id)e=this.ownTabTargets.findIndex(e=>e.id===t.currentTarget.dataset.id);else{if(this.isTabDisabled(t.currentTarget))return;e=this.ownTabTargets.indexOf(t.currentTarget)}if(!Number.isInteger(e)||e<0||e>=this.tabsCount)return;const a=this.normalizedEnabledIndex(e);-1!==a&&a!==this.indexValue&&(this.indexValue=a,this.focusedTabIndex=this.indexValue,s||this.setFocusToActiveTab(),this.autoSwitchValue&&this.restartAutoSwitch())}nextTab(t=!0){const e=this.nextEnabledTabIndex(this.indexValue);-1!==e&&(this.indexValue=e,this.focusedTabIndex=this.indexValue,t&&(this.setFocusToActiveTab(),this.autoSwitchValue&&this.restartAutoSwitch()))}previousTab(){const t=this.previousEnabledTabIndex(this.indexValue);-1!==t&&(this.indexValue=t,this.focusedTabIndex=this.indexValue,this.setFocusToActiveTab(),this.autoSwitchValue&&this.restartAutoSwitch())}firstTab(){const t=this.firstEnabledTabIndex();-1!==t&&(this.indexValue=t,this.focusedTabIndex=this.indexValue,this.setFocusToActiveTab(),this.autoSwitchValue&&this.restartAutoSwitch())}lastTab(){const t=this.lastEnabledTabIndex();-1!==t&&(this.indexValue=t,this.focusedTabIndex=this.indexValue,this.setFocusToActiveTab(),this.autoSwitchValue&&this.restartAutoSwitch())}nextTabFocusOnly(){const t=this.nextEnabledTabIndex(this.focusedTabIndex);-1!==t&&(this.focusedTabIndex=t,this.setFocusToTab(this.focusedTabIndex))}previousTabFocusOnly(){const t=this.previousEnabledTabIndex(this.focusedTabIndex);-1!==t&&(this.focusedTabIndex=t,this.setFocusToTab(this.focusedTabIndex))}firstTabFocusOnly(){const t=this.firstEnabledTabIndex();-1!==t&&(this.focusedTabIndex=t,this.setFocusToTab(this.focusedTabIndex))}lastTabFocusOnly(){const t=this.lastEnabledTabIndex();-1!==t&&(this.focusedTabIndex=t,this.setFocusToTab(this.focusedTabIndex))}startAutoSwitch(){!this.autoSwitchValue||this.tabsCount<=1||(this.stopAutoSwitch(),this.startTime=Date.now(),this.remainingTime=this.autoSwitchIntervalValue,this.currentProgress=0,this.isPaused=!1,this.autoSwitchTimer=setTimeout(()=>{this.nextTab(!1),this.startAutoSwitch()},this.autoSwitchIntervalValue),this.showProgressBarValue&&this.startProgressBar())}stopAutoSwitch(){this.autoSwitchTimer&&(clearTimeout(this.autoSwitchTimer),this.autoSwitchTimer=null),this.stopProgressBar(),this.resetProgressBar()}stopProgressBar(){if(this.hasProgressBarTarget){if(this.startTime&&this.autoSwitchIntervalValue>0){const t=Date.now()-this.startTime;this.currentProgress=Math.min(100,Math.max(0,t/this.autoSwitchIntervalValue*100))}else{const t=this.progressBarTargets.find(t=>{const e=t.parentElement;return e&&e.getBoundingClientRect().width>0})||this.progressBarTarget,e=t.getBoundingClientRect().width,s=t.parentElement?.getBoundingClientRect().width||0;this.currentProgress=s>0?e/s*100:0}this.setProgress(this.currentProgress)}}pauseAutoSwitch(){if(!this.autoSwitchValue||this.isPaused)return;this.isPaused=!0;const t=Date.now()-this.startTime;this.remainingTime=Math.max(0,this.autoSwitchIntervalValue-t),this.showProgressBarValue&&this.stopProgressBar(),this.autoSwitchTimer&&(clearTimeout(this.autoSwitchTimer),this.autoSwitchTimer=null)}resumeAutoSwitchIfIdle(){this.pointerInside||this.element.contains(document.activeElement)||this.resumeAutoSwitch()}resumeAutoSwitch(){this.autoSwitchValue&&this.isPaused&&(this.isPaused=!1,this.startTime=Date.now()-(this.autoSwitchIntervalValue-this.remainingTime),this.autoSwitchTimer=setTimeout(()=>{this.nextTab(!1),this.startAutoSwitch()},this.remainingTime),this.showProgressBarValue&&this.resumeProgressBar())}restartAutoSwitch(){if(!this.autoSwitchValue)return;const t=this.isPaused;this.stopAutoSwitch(),this.currentProgress=0,t?(this.isPaused=!0,this.remainingTime=this.autoSwitchIntervalValue,this.showProgressBarValue&&this.resetProgressBar()):(this.isPaused=!1,this.startAutoSwitch())}startProgressBar(){this.animateProgress(0,this.autoSwitchIntervalValue)}resumeProgressBar(){this.animateProgress(this.currentProgress||0,this.remainingTime)}animateProgress(t,e){this.setProgress(t),window.matchMedia("(prefers-reduced-motion: reduce)").matches||(this.progressAnimations=this.progressBarTargets.map(s=>s.animate([{transform:`scaleX(${t/100})`},{transform:"scaleX(1)"}],{duration:e,easing:"linear",fill:"forwards"})))}setProgress(t){this.progressAnimations?.forEach(t=>t.cancel()),this.progressAnimations=[],this.progressBarTargets.forEac
1h(e=>{e.style.transition="none",e.style.width="100%",e.style.transformOrigin="left",e.style.transform=`scaleX(${t/100})`})}updateProgressBar(t){"number"==typeof t&&this.setProgress(t)}resetProgressBar(){this.setProgress(0),this.currentProgress=0}async indexValueChanged(){if(0===this.tabsCount)return;const t=this.normalizedEnabledIndex(this.indexValue);if(-1===t)return;if(t!==this.indexValue)return void(this.indexValue=t);const e=this.ownTabTargets[this.indexValue];if(e&&(await this.showTab(),this.dispatch("tab-change",{target:e,detail:{activeIndex:this.indexValue}}),this.updateAnchorValue&&(!this.initialLoad||this.hadInitialAnchor))){const t=e.id;if(t)if(this.scrollToAnchorValue)location.hash=t;else{const e=window.location.href.split("#")[0]+"#"+t;"undefined"!=typeof Turbo?Turbo.navigator.history.replace(new URL(e)):history.replaceState({},document.title,e)}}}async showTab(){if(this.hasStylesheetIdValue&&this.indexValue>0){const t=document.getElementById(this.stylesheetIdValue);if(t&&(t.media="all"),t&&!t.sheet&&"error"!==t.dataset.stylesheetStatus&&(await new Promise(e=>{const s=()=>{t.removeEventListener("load",s),t.removeEventListener("error",s),clearTimeout(a),e()},a=setTimeout(s,3e3);t.addEventListener("load",s),t.addEventListener("error",s),t.media="all"}),!this.connected))return}if(this.lazyLoadValue&&!this.loadedPanels.has(this.indexValue)){const t=this.ownPanelTargets[this.indexValue];t?.querySelector(":scope > template")?this.#s(this.indexValue):t&&!this.turboFrameSrcValue&&this.loadedPanels.add(this.indexValue)}this.ownPanelTargets.forEach((t,e)=>{const s=this.ownTabTargets[e];if(!s)return;if(this.isTabDisabled(s)||e!==this.indexValue){t.classList.add("hidden"),s.setAttribute("aria-selected","false"),s.setAttribute("tabindex","-1"),delete s.dataset.active,this.hasActiveTabClass&&s.classList.remove(...this.activeTabClasses);const a=e<this.indexValue;a?(s.dataset.past="true",delete s.dataset.future):(s.dataset.future="true",delete s.dataset.past),this.hasPastTabClass||this.hasFutureTabClass?(this.hasInactiveTabClass&&s.classList.remove(...this.inactiveTabClasses),a?(this.hasPastTabClass&&s.classList.add(...this.pastTabClasses),this.hasFutureTabClass&&s.classList.remove(...this.futureTabClasses),!this.hasPastTabClass&&this.hasInactiveTabClass&&s.classList.add(...this.inactiveTabClasses)):(this.hasFutureTabClass&&s.classList.add(...this.futureTabClasses),this.hasPastTabClass&&s.classList.remove(...this.pastTabClasses),!this.hasFutureTabClass&&this.hasInactiveTabClass&&s.classList.add(...this.inactiveTabClasses))):this.hasInactiveTabClass&&s.classList.add(...this.inactiveTabClasses)}else t.classList.remove("hidden"),s.setAttribute("aria-selected","true"),s.setAttribute("tabindex","0"),s.dataset.active="true",delete s.dataset.past,delete s.dataset.future,this.hasInactiveTabClass&&s.classList.remove(...this.inactiveTabClasses),this.hasPastTabClass&&s.classList.remove(...this.pastTabClasses),this.hasFutureTabClass&&s.classList.remove(...this.futureTabClasses),this.hasActiveTabClass&&s.classList.add(...this.activeTabClasses)}),this.hasSelectTarget&&this.#a(this.indexValue),this.scrollActiveTabIntoViewValue&&this.scrollToActiveTab(),this.lazyLoadValue&&!this.loadedPanels.has(this.indexValue)&&(null!=this.lazyLoadFrame&&cancelAnimationFrame(this.lazyLoadFrame),this.lazyLoadFrame=requestAnimationFrame(()=>{this.lazyLoadFrame=null,this.connected&&this.#s(this.indexValue)}))}setInitialFocus(){if(0===this.tabsCount)return;const t=this.normalizedEnabledIndex(this.indexValue);if(-1===t)return this.ownTabTargets.forEach(t=>{t.setAttribute("tabindex","-1"),t.setAttribute("aria-selected","false")}),void(this.focusedTabIndex=-1);t===this.indexValue?(this.ownTabTargets.forEach((t,e)=>{this.isTabDisabled(t)||e!==this.indexValue?(t.setAttribute("tabindex","-1"),t.setAttribute("aria-selected","false")):(t.setAttribute("tabindex","0"),t.setAttribute("aria-selected","true"))}),this.focusedTabIndex=this.indexValue):this.indexValue=t}setFocusToActiveTab(){const t=this.ownTabTargets[this.indexValue];if(t&&!this.isTabDisabled(t)){(t.querySelector("a")||t).focus()}}setFocusToTab(t){const e=this.ownTabTargets[t];if(e&&!this.isTabDisabled(e)){(e.querySelector("a")||e).focus()}}scrollToActiveTab(){const t=this.ownTabTargets[this.indexValue];t&&t.scrollIntoView({inline:"center",behavior:"smooth"})}revealTabs(){this.hasTabListTarget&&this.tabListTarget.classList.remove("opacity-0")}#e(t){const e=t.value;if(""!==e&&/^\d+$/.test(e)){const t=Number.parseInt(e,10);if(t>=0&&t<this.tabsCount)return t}return t.selectedIndex}#a(t){const e=this.selectTarget,s=String(t);if(Array.from(e.options).some(t=>t.value===s))return e.value=s,void e.tomselect?.setValue(s,!0);e.options[t]&&(e.selectedIndex=t,e.tomselect?.setValue(e.options[t].value,!0))}get tabsCount(){return this.ownTabTargets.length}isTabDisabled(t){return!t||(t.disabled||"true"===t.getAttribute("aria-disabled"))}isIndexDisabled(t){return this.isTabDisabled(this.ownTabTargets[t])}firstEnabledTabIndex(){return this.ownTabTargets.findIndex(t=>!this.isTabDisabled(t))}lastEnabledTabIndex(){for(let t=this.tabsCount-1;t>=0;t-=1)if(!this.isIndexDisabled(t))return t;return-1}nextEnabledTabIndex(t){if(0===this.tabsCount)return-1;for(let e=1;e<=this.tabsCount;e+=1){const s=(t+e+this.tabsCount)%this.tabsCount;if(!this.isIndexDisabled(s))return s}return-1}previousEnabledTabIndex(t){if(0===this.tabsCount)return-1;for(let e=1;e<=this.tabsCount;e+=1){const s=(t-e+this.tabsCount)%this.tabsCount;if(!this.isIndexDisabled(s))return s}return-1}normalizedEnabledIndex(t){if(0===this.tabsCount)return-1;const e=Number.isFinite(t)?t:parseInt(t,10),s=Number.isFinite(e)?Math.max(0,Math.min(e,this.tabsCount-1)):0;if(!this.isIndexDisabled(s))return s;const a=this.nextEnabledTabIndex(s);if(-1!==a)return a;const i=this.previousEnabledTabIndex(s);return-1!==i?i:s}get anchor(){return document.URL.split("#").length>1?document.URL.split("#")[1]:null}getOrientation(){if(this.hasTabListTarget){const t=this.tabListTarget.getAttribute("aria-orientation");if("vertical"===t)return"vertical";if("horizontal"===t)return"horizontal"}return"both"}#t(t){return t.closest("[data-controller~='tabs']")===this.element}#s(t){const e=this.ownPanelTargets[t];if(!e)return;this.loadedPanels.add(t);const s=e.querySelector(":scope > template");if(s){const t=s.content.cloneNode(!0);return s.remove(),void e.appendChild(t)}if(this.turboFrameSrcValue){const s=e.querySelector("turbo-frame");
1if(s&&(!s.src||""===s.src||"about:blank"===s.src)){const e=this.turboFrameSrcValue,a=e.includes("?")?"&":"?";s.src=`${e}${a}tab=${t}`}}else if(this.hasTemplateTarget){const s=this.templateTargets[t];if(s){const t=s.content.cloneNode(!0);e.innerHTML="",e.appendChild(t)}}}}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.