js.foresight-devtools 0.0.3 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +42 -4
  2. package/dist/index.d.mts +587 -0
  3. package/dist/index.d.ts +532 -123
  4. package/dist/index.js +1724 -18
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +1724 -18
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +8 -14
  9. package/dist/Debugger/DebuggerControlPanel.d.ts +0 -81
  10. package/dist/Debugger/DebuggerControlPanel.js +0 -751
  11. package/dist/Debugger/ForesightDebugger.d.ts +0 -53
  12. package/dist/Debugger/ForesightDebugger.js +0 -341
  13. package/dist/Debugger/helpers/createAndAppend.d.ts +0 -8
  14. package/dist/Debugger/helpers/createAndAppend.js +0 -16
  15. package/dist/Debugger/helpers/getIntersectingIcon.d.ts +0 -1
  16. package/dist/Debugger/helpers/getIntersectingIcon.js +0 -3
  17. package/dist/Debugger/helpers/objectToMethodCall.d.ts +0 -13
  18. package/dist/Debugger/helpers/objectToMethodCall.js +0 -65
  19. package/dist/Debugger/helpers/removeOldDebuggers.d.ts +0 -4
  20. package/dist/Debugger/helpers/removeOldDebuggers.js +0 -7
  21. package/dist/Debugger/helpers/updateElementOverlays.d.ts +0 -3
  22. package/dist/Debugger/helpers/updateElementOverlays.js +0 -18
  23. package/dist/devtools.test.d.ts +0 -1
  24. package/dist/src/Debugger/DebuggerControlPanel.d.ts +0 -82
  25. package/dist/src/Debugger/DebuggerControlPanel.d.ts.map +0 -1
  26. package/dist/src/Debugger/ForesightDebugger.d.ts +0 -50
  27. package/dist/src/Debugger/ForesightDebugger.d.ts.map +0 -1
  28. package/dist/src/Debugger/constants.d.ts +0 -17
  29. package/dist/src/Debugger/constants.d.ts.map +0 -1
  30. package/dist/src/Debugger/helpers/createAndAppend.d.ts +0 -9
  31. package/dist/src/Debugger/helpers/createAndAppend.d.ts.map +0 -1
  32. package/dist/src/Debugger/helpers/evaluateRegistrationConditions.d.ts +0 -4
  33. package/dist/src/Debugger/helpers/evaluateRegistrationConditions.d.ts.map +0 -1
  34. package/dist/src/Debugger/helpers/getIntersectingIcon.d.ts +0 -2
  35. package/dist/src/Debugger/helpers/getIntersectingIcon.d.ts.map +0 -1
  36. package/dist/src/Debugger/helpers/objectToMethodCall.d.ts +0 -14
  37. package/dist/src/Debugger/helpers/objectToMethodCall.d.ts.map +0 -1
  38. package/dist/src/Debugger/helpers/removeOldDebuggers.d.ts +0 -5
  39. package/dist/src/Debugger/helpers/removeOldDebuggers.d.ts.map +0 -1
  40. package/dist/src/Debugger/helpers/shouldUpdateSetting.d.ts +0 -2
  41. package/dist/src/Debugger/helpers/shouldUpdateSetting.d.ts.map +0 -1
  42. package/dist/src/Debugger/helpers/updateElementOverlays.d.ts +0 -4
  43. package/dist/src/Debugger/helpers/updateElementOverlays.d.ts.map +0 -1
  44. package/dist/src/devtools.test.d.ts +0 -2
  45. package/dist/src/devtools.test.d.ts.map +0 -1
  46. package/dist/src/index.d.ts +0 -4
  47. package/dist/src/index.d.ts.map +0 -1
  48. package/dist/src/types.d.ts +0 -70
  49. package/dist/src/types.d.ts.map +0 -1
  50. package/dist/tsconfig.tsbuildinfo +0 -1
  51. package/dist/types.d.ts +0 -47
  52. package/dist/types.js +0 -1
package/dist/index.mjs CHANGED
@@ -1,18 +1,1724 @@
1
- const e=e=>(e=>(e=>null!=e&&"object"==typeof e||!1)(e)&&"number"==typeof e.nodeType&&[1,2,3,4,5,6,7,8,9,10,11].some(t=>e.nodeType===t)||!1)(e)&&1===e.nodeType||!1;const t=["all","intersecting","update"],n="PositionObserver Error";var i=class{entries;static version="1.1.0";_t;_r;_cm;_w;_h;_rm;_th;_c;constructor(i,s){if("function"!=typeof i)throw new Error(`${n}: ${i} is not a function.`);this.entries=new Map,this._c=i,this._t=0;const o=e(s?.root)?s.root:document?.documentElement;this._r=o,this._rm=s?.rootMargin,this._th=s?.threshold,
2
- /* istanbul ignore next @preserve */
3
- this._cm=t.indexOf(s?.callbackMode||"intersecting"),this._w=o.clientWidth,this._h=o.clientHeight}observe=t=>{if(!e(t))throw new Error(`${n}: ${t} is not an instance of Element.`);
4
- /* istanbul ignore else @preserve - a guard must be set */this._r.contains(t)&&this._n(t).then(e=>{
5
- /* istanbul ignore else @preserve - don't allow duplicate entries */
6
- e.boundingClientRect&&!this.getEntry(t)&&this.entries.set(t,e)
7
- /* istanbul ignore else @preserve */,this._t||(this._t=requestAnimationFrame(this._rc))})};unobserve=e=>{
8
- /* istanbul ignore else @preserve */
9
- this.entries.has(e)&&this.entries.delete(e)};_rc=()=>{
10
- /* istanbul ignore if @preserve - a guard must be set */
11
- if(!this.entries.size)return void(this._t=0);const{clientWidth:e,clientHeight:t}=this._r,n=new Promise(n=>{const i=[];this.entries.forEach(({target:n,boundingClientRect:s,isIntersecting:o})=>{
12
- /* istanbul ignore if @preserve - a guard must be set when target has been removed */
13
- this._r.contains(n)&&this._n(n).then(r=>{
14
- /* istanbul ignore if @preserve - make sure to only count visible entries */
15
- if(!r.isIntersecting){if(1===this._cm)return;if(2===this._cm)return void(o&&(this.entries.set(n,r),i.push(r)))}const{left:a,top:l}=r.boundingClientRect;
16
- /* istanbul ignore else @preserve - only schedule entries that changed position */s.top===l&&s.left===a&&this._w===e&&this._h===t||(this.entries.set(n,r),i.push(r))})}),this._w=e,this._h=t,n(i)});this._t=requestAnimationFrame(async()=>{const e=await n;
17
- /* istanbul ignore else @preserve */e.length&&this._c(e,this),this._rc()})};_n=e=>new Promise(t=>{new IntersectionObserver(([e],n)=>{n.disconnect(),t(e)},{threshold:this._th,rootMargin:this._rm}).observe(e)});getEntry=e=>this.entries.get(e);disconnect=()=>{cancelAnimationFrame(this._t),this.entries.clear(),this._t=0}};const s=(e,t=2)=>{const n=" ".repeat(t);if("object"==typeof e&&null!==e&&!Array.isArray(e)){const i=Object.entries(e);if(0===i.length)return"{}";return`{\n${i.map(([e,i])=>`${n} ${e}: ${s(i,t+2)}`).join(",\n")}\n${n}}`}return"string"==typeof e?`'${e}'`:"boolean"==typeof e||"number"==typeof e?String(e):null===e?"null":void 0===e?"undefined":Array.isArray(e)?JSON.stringify(e):String(e)};function o(e,t,n){const i=document.createElement(e);return n.id&&(i.id=n.id),n.className&&(i.className=n.className),n.data&&i.setAttribute("data-value",n.data),t.appendChild(i)}function r(e,t,n){const i=document.createElement("style");return i.textContent=e,i.id=n,t.appendChild(i)}const a=e=>e?"👁️":"🚫",l=!0,c="points",d="tabs",h="ms",g='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>',p="<em>No elements registered.</em>";class u{constructor(e,t){this.elementListItemsContainer=null,this.elementCountSpan=null,this.callbackCountSpan=null,this.elementListItems=new Map,this.trajectoryEnabledCheckbox=null,this.tabEnabledCheckbox=null,this.scrollEnabledCheckbox=null,this.historySizeSlider=null,this.historyValueSpan=null,this.predictionTimeSlider=null,this.predictionValueSpan=null,this.tabOffsetSlider=null,this.tabOffsetValueSpan=null,this.scrollMarginSlider=null,this.scrollMarginValueSpan=null,this.showNameTagsCheckbox=null,this.sortOptionsPopup=null,this.sortButton=null,this.containerMinimizeButton=null,this.allSettingsSectionsContainer=null,this.debuggerElementsSection=null,this.isContainerMinimized=!1,this.isMouseSettingsMinimized=!0,this.isKeyboardSettingsMinimized=!0,this.isScrollSettingsMinimized=!0,this.isGeneralSettingsMinimized=!0,this.SESSION_STORAGE_KEY="jsforesightDebuggerSectionStates",this.copySettingsButton=null,this.minimizedElementCount=null,this.copyTimeoutId=null,this.closeSortDropdownHandler=null,this.foresightManagerInstance=e,this.debuggerInstance=t}static initialize(e,t,n,i){u.isInitiated||(u.debuggerControlPanelInstance=new u(e,t));const s=u.debuggerControlPanelInstance;return s._setupDOMAndListeners(n,i),s}_setupDOMAndListeners(e,t){this.controlsContainer||(this.shadowRoot=e,this.isContainerMinimized=t.isControlPanelDefaultMinimized,this.controlsContainer=this.createControlContainer(),this.shadowRoot.appendChild(this.controlsContainer),this.controlPanelStyleElement=r(this.getStyles(),this.shadowRoot,"debug-control-panel"),this.queryDOMElements(),this.originalSectionStates(),this.setupEventListeners(),this.updateContainerVisibilityState(),this.updateControlsState(this.foresightManagerInstance.getManagerData.globalSettings,t))}static get isInitiated(){return!!u.debuggerControlPanelInstance}loadSectionStatesFromSessionStorage(){const e=sessionStorage.getItem(this.SESSION_STORAGE_KEY);let t={};return e&&(t=JSON.parse(e)),this.isMouseSettingsMinimized=t.mouse??!0,this.isKeyboardSettingsMinimized=t.keyboard??!0,this.isScrollSettingsMinimized=t.scroll??!0,this.isGeneralSettingsMinimized=t.general??!0,t}saveSectionStatesToSessionStorage(){const e={mouse:this.isMouseSettingsMinimized,keyboard:this.isKeyboardSettingsMinimized,scroll:this.isScrollSettingsMinimized,general:this.isGeneralSettingsMinimized};try{sessionStorage.setItem(this.SESSION_STORAGE_KEY,JSON.stringify(e))}catch(e){console.error("Foresight Debugger: Could not save section states to session storage.",e)}}queryDOMElements(){this.trajectoryEnabledCheckbox=this.controlsContainer.querySelector("#trajectory-enabled"),this.tabEnabledCheckbox=this.controlsContainer.querySelector("#tab-enabled"),this.scrollEnabledCheckbox=this.controlsContainer.querySelector("#scroll-enabled"),this.historySizeSlider=this.controlsContainer.querySelector("#history-size"),this.historyValueSpan=this.controlsContainer.querySelector("#history-value"),this.predictionTimeSlider=this.controlsContainer.querySelector("#prediction-time"),this.predictionValueSpan=this.controlsContainer.querySelector("#prediction-value"),this.tabOffsetSlider=this.controlsContainer.querySelector("#tab-offset"),this.tabOffsetValueSpan=this.controlsContainer.querySelector("#tab-offset-value"),this.scrollMarginSlider=this.controlsContainer.querySelector("#scroll-margin"),this.scrollMarginValueSpan=this.controlsContainer.querySelector("#scroll-margin-value"),this.elementListItemsContainer=this.controlsContainer.querySelector("#element-list-items-container"),this.showNameTagsCheckbox=this.controlsContainer.querySelector("#toggle-name-tags"),this.sortOptionsPopup=this.controlsContainer.querySelector("#sort-options-popup"),this.sortButton=this.controlsContainer.querySelector(".sort-button"),this.elementCountSpan=this.controlsContainer.querySelector("#element-count"),this.callbackCountSpan=this.controlsContainer.querySelector("#callback-count"),this.containerMinimizeButton=this.controlsContainer.querySelector(".minimize-button"),this.allSettingsSectionsContainer=this.controlsContainer.querySelector(".all-settings-sections-container"),this.debuggerElementsSection=this.controlsContainer.querySelector(".debugger-elements"),this.copySettingsButton=this.controlsContainer.querySelector(".copy-settings-button"),this.minimizedElementCount=this.controlsContainer.querySelector(".minimized-element-count")}handleCopySettings(){var e,t;this.copySettingsButton&&navigator.clipboard.writeText((e=this.foresightManagerInstance.getManagerData.globalSettings,t="ForesightManager.initialize",`${t}({\n${Object.entries(e).filter(([e])=>"resizeScrollThrottleDelay"!==String(e)).map(([e,t])=>` ${String(e)}: ${s(t)}`).join(",\n")}\n})`)).then(()=>{this.copySettingsButton.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"></polyline></svg>',this.copyTimeoutId&&clearTimeout(this.copyTimeoutId),this.copyTimeoutId=setTimeout(()=>{this.copySettingsButton&&(this.copySettingsButton.innerHTML=g),this.copyTimeoutId=null},3e3)}).catch(e=>{console.error("Foresight Debugger: Could not copy settings to clipboard",e)})}createInputEventListener(e,t,n,i){e&&t&&e.addEventListener("input",e=>{const s=parseInt(e.target.value,10);t.textContent=`${s} ${n}`,this.foresightManagerInstance.alterGlobalSettings({[i]:s})})}createChangeEventListener(e,t){if(!e)return;const n=this.debuggerInstance.getDebuggerData.settings;e.addEventListener("change",e=>{const i=e.target.checked;t in n?this.debuggerInstance.alterDebuggerSettings({[t]:i}):this.foresightManagerInstance.alterGlobalSettings({[t]:i})})}createSectionVisibilityToggleEventListener(e,t){const n=e?.querySelector(".debugger-section-header");n?.addEventListener("click",n=>{n.stopPropagation(),this.toggleMinimizeSection(e,this[t]=!this[t])})}setupEventListeners(){this.createChangeEventListener(this.trajectoryEnabledCheckbox,"enableMousePrediction"),this.createChangeEventListener(this.tabEnabledCheckbox,"enableTabPrediction"),this.createChangeEventListener(this.scrollEnabledCheckbox,"enableScrollPrediction"),this.createChangeEventListener(this.showNameTagsCheckbox,"showNameTags"),this.createInputEventListener(this.historySizeSlider,this.historyValueSpan,c,"positionHistorySize"),this.createInputEventListener(this.predictionTimeSlider,this.predictionValueSpan,h,"trajectoryPredictionTime"),this.createInputEventListener(this.tabOffsetSlider,this.tabOffsetValueSpan,d,"tabOffset"),this.createInputEventListener(this.scrollMarginSlider,this.scrollMarginValueSpan,"px","scrollMargin"),this.sortButton?.addEventListener("click",e=>{e.stopPropagation(),this.sortOptionsPopup?.classList.toggle("active")}),this.sortOptionsPopup?.addEventListener("click",e=>{const t=e.target.closest("[data-sort]");if(!t)return;const n=t.dataset.sort;this.debuggerInstance.alterDebuggerSettings({sortElementList:n}),this.sortAndReorderElements(),this.updateSortOptionUI(n),this.sortOptionsPopup?.classList.remove("active")}),this.closeSortDropdownHandler=e=>{this.sortOptionsPopup?.classList.contains("active")&&!this.sortButton?.contains(e.target)&&this.sortOptionsPopup.classList.remove("active")},document.addEventListener("click",this.closeSortDropdownHandler),this.containerMinimizeButton?.addEventListener("click",()=>{this.isContainerMinimized=!this.isContainerMinimized,this.updateContainerVisibilityState()}),this.copySettingsButton?.addEventListener("click",this.handleCopySettings.bind(this)),this.createSectionVisibilityToggleEventListener(this.controlsContainer.querySelector(".mouse-settings-section"),"isMouseSettingsMinimized"),this.createSectionVisibilityToggleEventListener(this.controlsContainer.querySelector(".keyboard-settings-section"),"isKeyboardSettingsMinimized"),this.createSectionVisibilityToggleEventListener(this.controlsContainer.querySelector(".scroll-settings-section"),"isScrollSettingsMinimized"),this.createSectionVisibilityToggleEventListener(this.controlsContainer.querySelector(".general-settings-section"),"isGeneralSettingsMinimized")}toggleMinimizeSection(e,t){if(!e)return;const n=e.querySelector(".debugger-section-content"),i=e.querySelector(".section-minimize-button");n&&i&&(t?(n.style.display="none",i.textContent="+"):(n.style.display="flex",i.textContent="-")),this.saveSectionStatesToSessionStorage()}originalSectionStates(){const e=this.loadSectionStatesFromSessionStorage();this.toggleMinimizeSection(this.controlsContainer.querySelector(".mouse-settings-section"),e.mouse??!0),this.toggleMinimizeSection(this.controlsContainer.querySelector(".keyboard-settings-section"),e.keyboard??!0),this.toggleMinimizeSection(this.controlsContainer.querySelector(".scroll-settings-section"),e.scroll??!0),this.toggleMinimizeSection(this.controlsContainer.querySelector(".general-settings-section"),e.general??!0);const t=this.debuggerElementsSection?.querySelector(".debugger-section-content");t&&(t.style.display="flex")}updateContainerVisibilityState(){this.containerMinimizeButton&&(this.isContainerMinimized?(this.controlsContainer.classList.add("minimized"),this.containerMinimizeButton.textContent="+",this.allSettingsSectionsContainer&&(this.allSettingsSectionsContainer.style.display="none"),this.debuggerElementsSection&&(this.debuggerElementsSection.style.display="none"),this.copySettingsButton&&(this.copySettingsButton.style.display="none"),this.minimizedElementCount&&(this.minimizedElementCount.style.display="")):(this.controlsContainer.classList.remove("minimized"),this.containerMinimizeButton.textContent="-",this.allSettingsSectionsContainer&&(this.allSettingsSectionsContainer.style.display=""),this.debuggerElementsSection&&(this.debuggerElementsSection.style.display=""),this.copySettingsButton&&(this.copySettingsButton.style.display=""),this.minimizedElementCount&&(this.minimizedElementCount.style.display="none")))}updateSortOptionUI(e){this.sortOptionsPopup?.querySelectorAll("[data-sort]").forEach(t=>{const n=t;n.dataset.sort===e?n.classList.add("active-sort-option"):n.classList.remove("active-sort-option")})}updateControlsState(e,t){this.trajectoryEnabledCheckbox&&(this.trajectoryEnabledCheckbox.checked=e.enableMousePrediction),this.tabEnabledCheckbox&&(this.tabEnabledCheckbox.checked=e.enableTabPrediction),this.scrollEnabledCheckbox&&(this.scrollEnabledCheckbox.checked=e.enableScrollPrediction),this.showNameTagsCheckbox&&(this.showNameTagsCheckbox.checked=t.showNameTags),this.updateSortOptionUI(t.sortElementList??"visibility"),this.historySizeSlider&&this.historyValueSpan&&(this.historySizeSlider.value=e.positionHistorySize.toString(),this.historyValueSpan.textContent=`${e.positionHistorySize} ${c}`),this.predictionTimeSlider&&this.predictionValueSpan&&(this.predictionTimeSlider.value=e.trajectoryPredictionTime.toString(),this.predictionValueSpan.textContent=`${e.trajectoryPredictionTime} ${h}`),this.tabOffsetSlider&&this.tabOffsetValueSpan&&(this.tabOffsetSlider.value=e.tabOffset.toString(),this.tabOffsetValueSpan.textContent=`${e.tabOffset} ${d}`),this.scrollMarginSlider&&this.scrollMarginValueSpan&&(this.scrollMarginSlider.value=e.scrollMargin.toString(),this.scrollMarginValueSpan.textContent=`${e.scrollMargin} px`)}refreshRegisteredElementCountDisplay(e){if(!this.elementCountSpan||!this.callbackCountSpan)return;let t=0;e.forEach(e=>{e.isIntersectingWithViewport&&t++});const n=e.size,{tab:i,mouse:s,scroll:o,total:r}=this.foresightManagerInstance.getManagerData.globalCallbackHits,a=["Element Visibility Status","━━━━━━━━━━━━━━━━━━━━━━━━━━━━",`Visible in Viewport: ${t}`,"Not in Viewport: "+(n-t),`Total Registered Elements: ${n}`,"","Note: Only elements visible in the viewport","are actively tracked by intersection observers."];this.minimizedElementCount&&(this.minimizedElementCount.textContent=`${t}/${n}`,this.minimizedElementCount.title=a.join("\n")),this.elementCountSpan.textContent=`Visible: ${t}/${n} ~ `,this.elementCountSpan.title=a.join("\n"),this.callbackCountSpan.textContent=`Mouse: ${s.hover+s.trajectory} Tab: ${i.forwards+i.reverse} Scroll: ${o.down+o.left+o.right+o.up}`,this.callbackCountSpan.title=["Callback Execution Stats","━━━━━━━━━━━━━━━━━━━━━━━━","Mouse Callbacks",` • Trajectory: ${s.trajectory}`,` • Hover: ${s.hover}`,` • Subtotal: ${s.hover+s.trajectory}`,"","Keyboard Callbacks:",` • Tab Forward: ${i.forwards}`,` • Tab Reverse: ${i.reverse}`,` • Subtotal: ${i.forwards+i.reverse}`,"","Scroll Callbacks:",` • Up: ${o.up} | Down: ${o.down}`,` • Left: ${o.left} | Right: ${o.right}`,` • Subtotal: ${o.up+o.down+o.left+o.right}`,"","Total Callbacks: "+r].join("\n")}removeElementFromList(e){if(!this.elementListItemsContainer)return;const t=this.elementListItems.get(e.element);if(t){t.remove(),this.elementListItems.delete(e.element);const n=this.foresightManagerInstance.registeredElements;this.refreshRegisteredElementCountDisplay(n),0===this.elementListItems.size&&(this.elementListItemsContainer.innerHTML=p)}}updateElementVisibilityStatus(e){if(!this.elementListItemsContainer)return;const t=this.elementListItems.get(e.element);if(!t)return void this.addElementToList(e);t.classList.toggle("not-in-viewport",!e.isIntersectingWithViewport);const n=t.querySelector(".intersecting-indicator");if(n){const t=a(e.isIntersectingWithViewport);n.textContent=t}this.refreshRegisteredElementCountDisplay(this.foresightManagerInstance.registeredElements),this.sortAndReorderElements()}sortAndReorderElements(){if(!this.elementListItemsContainer)return;const e=this.debuggerInstance.getDebuggerData.settings.sortElementList??"visibility",t=Array.from(this.foresightManagerInstance.registeredElements.values());if("insertionOrder"!==e){const n=(e,t)=>{const n=e.element.compareDocumentPosition(t.element);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0};"visibility"===e?t.sort((e,t)=>e.isIntersectingWithViewport!==t.isIntersectingWithViewport?e.isIntersectingWithViewport?-1:1:n(e,t)):"documentOrder"===e&&t.sort(n)}const n=document.createDocumentFragment();t.length&&(t.forEach(e=>{const t=this.elementListItems.get(e.element);t&&n.appendChild(t)}),this.elementListItemsContainer.innerHTML="",this.elementListItemsContainer.appendChild(n))}addElementToList(e,t=!0){if(!this.elementListItemsContainer)return;if(this.elementListItemsContainer.innerHTML===p&&(this.elementListItemsContainer.innerHTML=""),this.elementListItems.has(e.element))return;const n=document.createElement("div");n.className="element-list-item",this.updateListItemContent(n,e),this.elementListItemsContainer.appendChild(n),this.elementListItems.set(e.element,n),this.refreshRegisteredElementCountDisplay(this.foresightManagerInstance.registeredElements)}updateListItemContent(e,t){const n=a(t.isIntersectingWithViewport);e.classList.toggle("not-in-viewport",!t.isIntersectingWithViewport);let i="N/A";if(t.elementBounds.hitSlop){const{top:e,right:n,bottom:s,left:o}=t.elementBounds.hitSlop;i=`T:${e} R:${n} B:${s} L:${o}`}const s=[`${t.name||"Unnamed Element"}`,"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Viewport Status:",t.isIntersectingWithViewport?" ✓ In viewport - actively tracked by observers":" ✗ Not in viewport - not being tracked","","Hit Slop:",t.elementBounds.hitSlop?[` Top: ${t.elementBounds.hitSlop.top}px, Bottom: ${t.elementBounds.hitSlop.bottom}px `,` Right: ${t.elementBounds.hitSlop.right}px, Left: ${t.elementBounds.hitSlop.left}px`].join("\n"):" • Not defined - using element's natural boundaries",""].join("\n");e.title=s,e.innerHTML=`\n <span class="intersecting-indicator">${n}</span>\n <span class="element-name">${t.name||"Unnamed Element"}</span>\n <span class="hit-slop">${i}</span>\n `}cleanup(){this.controlsContainer?.remove(),this.controlPanelStyleElement?.remove(),this.copyTimeoutId&&(clearTimeout(this.copyTimeoutId),this.copyTimeoutId=null),this.closeSortDropdownHandler&&(document.removeEventListener("click",this.closeSortDropdownHandler),this.closeSortDropdownHandler=null),this.controlsContainer=null,this.controlPanelStyleElement=null,this.elementListItemsContainer=null,this.elementCountSpan=null,this.callbackCountSpan=null,this.elementListItems.clear(),this.containerMinimizeButton=null,this.allSettingsSectionsContainer=null,this.debuggerElementsSection=null,this.trajectoryEnabledCheckbox=null,this.tabEnabledCheckbox=null,this.scrollEnabledCheckbox=null,this.historySizeSlider=null,this.historyValueSpan=null,this.predictionTimeSlider=null,this.predictionValueSpan=null,this.tabOffsetSlider=null,this.tabOffsetValueSpan=null,this.scrollMarginSlider=null,this.scrollMarginValueSpan=null,this.showNameTagsCheckbox=null,this.sortOptionsPopup=null,this.sortButton=null,this.copySettingsButton=null}createControlContainer(){const e=document.createElement("div");return e.id="debug-controls",e.innerHTML=`\n <div class="debugger-title-container">\n <button class="minimize-button">-</button>\n <div class="title-group">\n <h2>Foresight Debugger</h2>\n <span class="info-icon" title="${["Foresight Debugger Information","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Session-Only Changes:","All adjustments made here apply only to the","current browser session and won't persist.","","Permanent Configuration:","To make lasting changes, update the initial","values in your ForesightManager.initialize().","","You can copy the current debugger settings","with the button on the right"].join("\n")}">i</span>\n </div>\n <button class="copy-settings-button" title="${["Copy Settings to Clipboard","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Copies the current configuration as a","formatted method call that you can paste","directly into your code."].join("\n")}">\n ${g}\n </button>\n <span class="minimized-element-count">\n </span>\n </div>\n\n <div class="all-settings-sections-container">\n <div class="debugger-section mouse-settings-section">\n <div class="debugger-section-header collapsible">\n <h3>Mouse Settings</h3>\n <button class="section-minimize-button">-</button>\n </div>\n <div class="debugger-section-content mouse-settings-content">\n <div class="control-row">\n <label for="trajectory-enabled">\n Enable Mouse Prediction\n <span class="info-icon" title="${["Mouse Prediction Control","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","When enabled: Predicts mouse movement","trajectory and triggers callbacks before","the cursor reaches the target element.","","When disabled: Only direct hover events","trigger actions (next to tab/scroll).","","Property: enableMousePrediction"].join("\n")}">i</span>\n </label>\n <input type="checkbox" id="trajectory-enabled">\n </div>\n <div class="control-row">\n <label for="history-size">\n History Size\n <span class="info-icon" title="${["Position History","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Controls how many past mouse positions","are stored for velocity calculations.","","Higher values:"," • More accurate trajectory predictions"," • Smoother movement detection"," • Slightly increased processing overhead","","Lower values:"," • Faster response to direction changes"," • Less memory usage"," • May be less accurate for fast movements","","Property: positionHistorySize"].join("\n")}">i</span>\n </label>\n <input type="range" id="history-size" min="2" max="30">\n <span id="history-value"></span>\n </div>\n <div class="control-row">\n <label for="prediction-time">\n Prediction Time\n <span class="info-icon" title="${["Trajectory Prediction Time","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━",`How far into the future (in ${h})`,"to calculate the mouse trajectory path.","","Larger values:"," • Elements are detected sooner"," • More time for preloading/preparation"," • May trigger false positives for curved paths","","Smaller values:"," • More precise targeting"," • Reduced false positive rate"," • Less time for preparation","","Property: trajectoryPredictionTime"].join("\n")}">i</span>\n </label>\n <input type="range" id="prediction-time" min="10" max="200" step="10">\n <span id="prediction-value"></span>\n </div>\n </div>\n </div>\n\n <div class="debugger-section keyboard-settings-section">\n <div class="debugger-section-header collapsible">\n <h3>Keyboard Settings</h3>\n <button class="section-minimize-button">-</button>\n </div>\n <div class="debugger-section-content keyboard-settings-content">\n <div class="control-row">\n <label for="tab-enabled">\n Enable Tab Prediction\n <span class="info-icon" title="${["Tab Navigation Prediction","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","When enabled: Callbacks are executed when",`the user is ${this.foresightManagerInstance.getManagerData.globalSettings.tabOffset} (tabOffset) ${d} away from`,"a registered element during tab navigation.","","(works with Shift+Tab too).","","Property: enableTabPrediction"].join("\n")}">i</span>\n </label>\n <input type="checkbox" id="tab-enabled">\n </div>\n <div class="control-row">\n <label for="tab-offset">\n Tab Offset\n <span class="info-icon" title="${["Tab Offset","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Number of tabbable elements to look ahead","when predicting tab navigation targets.","","How it works:"," • Tracks the current focused element"," • Looks ahead by the specified offset"," • Triggers callbacks for registered elements"," within that range","","Property: tabOffset"].join("\n")}">i</span>\n </label>\n <input type="range" id="tab-offset" min="0" max="20" step="1">\n <span id="tab-offset-value"></span>\n </div>\n </div>\n </div>\n\n <div class="debugger-section scroll-settings-section">\n <div class="debugger-section-header collapsible">\n <h3>Scroll Settings</h3>\n <button class="section-minimize-button">-</button>\n </div>\n <div class="debugger-section-content scroll-settings-content">\n <div class="control-row">\n <label for="scroll-enabled">\n Enable Scroll Prediction\n <span class="info-icon" title="${["Scroll Prediction","━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Enables predictive scrolling based on mouse","position and scroll direction.","","When enabled, calculates scroll direction from","mouse movement and triggers callbacks for","elements that intersect the predicted path.","","Property: enableScrollPrediction"].join("\n")}">i</span>\n </label>\n <input type="checkbox" id="scroll-enabled">\n </div>\n <div class="control-row">\n <label for="scroll-margin">\n Scroll Margin\n <span class="info-icon" title="${["Scroll Margin","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Sets the pixel distance to check from the","mouse position in the scroll direction.","","Higher values check further ahead, allowing","earlier detection of elements that will come","into view during scrolling.","","Property: scrollMargin"].join("\n")}">i</span>\n </label>\n <input type="range" id="scroll-margin" min="30" max="300" step="10">\n <span id="scroll-margin-value"></span>\n </div>\n </div>\n\n <div class="debugger-section general-settings-section">\n <div class="debugger-section-header collapsible">\n <h3>General Settings</h3>\n <button class="section-minimize-button">-</button>\n </div>\n <div class="debugger-section-content general-settings-content">\n <div class="control-row">\n <label for="toggle-name-tags">\n Show Name Tags\n <span class="info-icon" title="${["Visual Debug Name Tags","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","When enabled: Displays name tags over","each registered element in debug mode.","","Property: debuggerSettings.showNameTags"].join("\n")}">i</span>\n </label>\n <input type="checkbox" id="toggle-name-tags">\n </div>\n </div>\n </div>\n </div>\n\n <div class="debugger-section debugger-elements">\n <div class="debugger-section-header elements-list-header">\n <h3>Elements <span id="element-count"></span> <span id="callback-count"></span></h3>\n <div class="header-controls">\n <div class="sort-control-container">\n <button class="sort-button" title="Change element list sort order">\n <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon></svg>\n </button>\n <div id="sort-options-popup">\n <button\n data-sort="visibility"\n title="${["Sort by Visibility","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Sorts elements by their viewport visibility","(visible elements first), with a secondary","sort by their order in the document.","","Property: debuggerSettings.sortElementList","Value: 'visibility'"].join("\n")}">\n Visibility\n </button>\n <button\n data-sort="documentOrder"\n title="${["Sort by Document Order","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Sorts elements based on their order of","appearance in the document's structure","(matching the HTML source).","","Property: debuggerSettings.sortElementList","Value: 'documentOrder'"].join("\n")}"\n >\n Document Order\n </button>\n <button\n data-sort="insertionOrder"\n title="${["Sort by Insertion Order","━━━━━━━━━━━━━━━━━━━━━━━━━━━━━","Sorts elements based on the order they","were registered with the ForesightManager.","","Property: debuggerSettings.sortElementList","Value: 'insertionOrder'"].join("\n")}"\n >\n Insertion Order\n </button>\n </div>\n </div>\n </div>\n </div>\n <div class="debugger-section-content element-list">\n <div id="element-list-items-container">\n </div>\n </div>\n </div>\n `,e}getStyles(){return'\n #debug-controls {\n position: fixed; bottom: 10px; right: 10px;\n background-color: rgba(0, 0, 0, 0.90); color: white; padding: 12px;\n border-radius: 5px; font-family: Arial, sans-serif; font-size: 13px;\n z-index: 10001; pointer-events: auto; display: flex; flex-direction: column; gap: 8px;\n width: 400px;\n transition: width 0.3s ease, height 0.3s ease;\n }\n #debug-controls.minimized {\n width: 250px;\n overflow: hidden;\n padding: 12px 0; \n }\n #debug-controls.minimized .debugger-title-container {\n padding-left: 10px; \n padding-right: 10px;\n gap: 10px; \n }\n #debug-controls.minimized .debugger-title-container h2 {\n display: inline;\n font-size: 14px;\n margin: 0;\n white-space: nowrap;\n }\n #debug-controls.minimized .info-icon {\n display: none;\n }\n\n #element-count,#callback-count {\n font-size: 12px;\n color: #9e9e9e;\n }\n\n .debugger-title-container {\n display: flex;\n align-items: center;\n justify-content: space-between; \n padding: 0 0px; \n }\n .title-group { \n display: flex;\n align-items: center;\n gap: 8px; \n\n }\n .minimize-button {\n background: none; border: none; color: white;\n font-size: 22px; cursor: pointer;\n line-height: 1;\n padding-inline: 0px;\n }\n .debugger-title-container h2 { margin: 0; font-size: 15px; }\n\n .copy-settings-button {\n background: none; border: none; color: white;\n cursor: pointer; padding: 0;\n display: flex; align-items: center; justify-content: center;\n }\n\n .copy-settings-button svg {\n width: 16px; height: 16px;\n stroke: white;\n }\n\n .minimized-element-count {\n font-size: 14px;\n min-width: 30px;\n text-align: right;\n }\n\n .all-settings-sections-container {\n display: flex;\n flex-direction: column;\n gap: 8px;\n }\n\n .debugger-section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-top: 5px;\n margin-bottom: 2px;\n padding-bottom: 2px;\n border-bottom: 1px solid #444;\n }\n .debugger-section-header.collapsible {\n cursor: pointer;\n }\n .debugger-section-header h3 {\n margin: 0;\n font-size: 14px;\n font-weight: bold;\n color: #b0c4de;\n flex-grow: 1;\n }\n\n .section-minimize-button {\n background: none;\n border: none;\n color: white;\n font-size: 18px;\n cursor: pointer;\n padding: 0px;\n line-height: 1;\n }\n\n #debug-controls .control-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n }\n #debug-controls label {\n display: flex;\n align-items: center;\n gap: 5px;\n cursor: pointer;\n }\n #debug-controls .control-row:has(input[type="checkbox"]) label {\n flex-grow: 1;\n }\n #debug-controls .control-row input[type="checkbox"] {\n appearance: none; -webkit-appearance: none; -moz-appearance: none;\n position: relative; width: 40px; height: 18px;\n background-color: #555; border-radius: 10px; cursor: pointer;\n outline: none; transition: background-color 0.2s ease;\n vertical-align: middle; flex-shrink: 0; margin: 0;\n }\n #debug-controls .control-row input[type="checkbox"]::before {\n content: ""; position: absolute; width: 14px; height: 14px;\n border-radius: 50%; background-color: white; top: 2px; left: 2px;\n transition: transform 0.2s ease; box-shadow: 0 1px 3px rgba(0,0,0,0.4);\n }\n #debug-controls .control-row input[type="checkbox"]:checked {\n background-color: #b0c4de;\n }\n #debug-controls .control-row input[type="checkbox"]:checked::before {\n transform: translateX(22px);\n }\n #debug-controls .control-row:has(input[type="range"]) label {\n flex-basis: 170px; flex-shrink: 0;\n }\n #debug-controls input[type="range"] {\n flex-grow: 1; margin: 0; cursor: pointer; -webkit-appearance: none;\n appearance: none; background: transparent; height: 18px; vertical-align: middle;\n }\n #debug-controls input[type="range"]::-webkit-slider-runnable-track {\n height: 6px; background: #555; border-radius: 3px;\n }\n #debug-controls input[type="range"]::-moz-range-track {\n height: 6px; background: #555; border-radius: 3px;\n }\n #debug-controls input[type="range"]::-webkit-slider-thumb {\n -webkit-appearance: none; appearance: none; margin-top: -5px;\n background: #b0c4de; height: 16px; width: 16px;\n border-radius: 50%; border: 1px solid #333;\n }\n #debug-controls input[type="range"]::-moz-range-thumb {\n background: #b0c4de; height: 16px; width: 16px;\n border-radius: 50%; border: 1px solid #333; border: none;\n }\n #debug-controls .control-row:has(input[type="range"]) span:not(.info-icon) {\n width: 55px; min-width: 55px; text-align: right; flex-shrink: 0;\n }\n .info-icon {\n display: inline-flex; align-items: center; justify-content: center;\n width: 16px; height: 16px; border-radius: 50%;\n background-color: #555; color: white; font-size: 10px;\n font-style: italic; font-weight: bold; font-family: \'Georgia\', serif;\n cursor: help; user-select: none; flex-shrink: 0;\n }\n .debugger-section {\n display: flex; flex-direction: column; gap: 6px;\n }\n .debugger-section-content {\n display: none; flex-direction: column; gap: 8px;\n }\n\n /* Element List Styles */\n .elements-list-header { cursor: default; }\n .header-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .sort-control-container {\n position: relative;\n }\n .sort-button {\n background: none; border: none; color: white; cursor: pointer;\n padding: 0; display: flex; align-items: center; justify-content: center;\n }\n .sort-button svg {\n width: 16px; height: 16px; stroke: #b0c4de; transition: stroke 0.2s;\n }\n .sort-button:hover svg { stroke: white; }\n \n #sort-options-popup {\n position: absolute;\n bottom: calc(100% + 5px);\n right: -5px;\n z-index: 10;\n display: none;\n flex-direction: column;\n gap: 4px;\n background-color: #3a3a3a;\n border: 1px solid #555;\n border-radius: 4px;\n padding: 3px;\n width: 200px;\n box-shadow: 0 4px 8px rgba(0,0,0,0.3);\n }\n #sort-options-popup.active {\n display: flex;\n }\n #sort-options-popup button {\n background: none; border: none; color: #ccc;\n font-size: 12px; text-align: left; padding: 5px 8px;\n cursor: pointer; border-radius: 3px;\n transition: background-color 0.2s, color 0.2s;\n display: flex;\n align-items: center;\n height: 26px;\n }\n #sort-options-popup button:hover {\n background-color: #555;\n color: white;\n }\n #sort-options-popup button.active-sort-option {\n color: #b0c4de;\n font-weight: bold;\n }\n #sort-options-popup button.active-sort-option::before {\n content: \'✓\';\n margin-right: 6px;\n width: 10px;\n }\n #sort-options-popup button::before {\n content: \'\';\n margin-right: 6px;\n width: 10px;\n }\n\n .element-list { /* Scroll container */\n min-height: 237px;\n max-height: 237px; \n overflow-y: auto;\n background-color: rgba(20, 20, 20, 0.5);\n border-radius: 3px;\n padding: 0;\n display: flex;\n }\n\n /* Modern Scrollbar Styling */\n .element-list::-webkit-scrollbar { width: 8px; }\n .element-list::-webkit-scrollbar-track { background: rgba(30, 30, 30, 0.5); border-radius: 4px; }\n .element-list::-webkit-scrollbar-thumb { background-color: rgba(176, 196, 222, 0.5); border-radius: 4px; border: 2px solid rgba(0, 0, 0, 0.2); }\n .element-list::-webkit-scrollbar-thumb:hover { background-color: rgba(176, 196, 222, 0.7); }\n .element-list { scrollbar-width: thin; scrollbar-color: rgba(176, 196, 222, 0.5) rgba(30, 30, 30, 0.5); }\n\n #element-list-items-container { \n display: flex;\n flex-wrap: wrap;\n gap: 3px;\n padding: 6px;\n min-height: 225px;\n box-sizing: border-box;\n align-content: flex-start;\n }\n #element-list-items-container > em {\n flex-basis: 100%;\n text-align: center;\n padding: 10px 0;\n font-style: italic;\n color: #ccc;\n font-size: 12px;\n }\n .element-list-item {\n flex-basis: calc((100% - (0 * 3px)) / 1);\n flex-grow: 0;\n flex-shrink: 0;\n height: 35px;\n box-sizing: border-box;\n padding: 3px 5px;\n border-radius: 2px;\n display: flex;\n align-items: center;\n gap: 5px;\n background-color: rgba(50,50,50,0.7);\n transition: background-color 0.2s ease, opacity 0.2s ease;\n font-size: 11px; \n overflow: hidden;\n }\n \n /* Viewport intersection styling */\n .element-list-item.not-in-viewport { opacity: 0.4; }\n \n .element-list-item .element-name {\n flex-grow: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 12px; \n font-weight: bold;\n }\n .element-list-item .intersecting-indicator {\n font-size: 12px;\n flex-shrink: 0;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n }\n .element-list-item .hit-behavior,\n .element-list-item .hit-slop {\n font-size: 10px; \n color: #b0b0b0;\n padding: 2px 5px; \n border-radius: 3px; \n background-color: rgba(0,0,0,0.2);\n flex-shrink: 0;\n }\n '}}function b(e,t,n){const{expandedOverlay:i,nameLabel:s}=e,{expandedRect:o}=t.elementBounds,r=o.right-o.left,a=o.bottom-o.top;i.style.width=`${r}px`,i.style.height=`${a}px`,i.style.transform=`translate3d(${o.left}px, ${o.top}px, 0)`,i.style.display="block",s.textContent=t.name,""!==t.name&&n?(s.style.display="block",s.style.transform=`translate3d(${o.left}px, ${o.top-25}px, 0)`):s.style.display="none"}function m(e,t){return void 0!==e&&e!==t}class y{constructor(e){this.callbackAnimations=new Map,this._debuggerSettings={showDebugger:true,isControlPanelDefaultMinimized:false,showNameTags:l,sortElementList:"visibility"},this.debugElementOverlays=new Map,this.predictedMouseIndicator=null,this.mouseTrajectoryLine=null,this.scrollTrajectoryLine=null,this.managerSubscriptionsController=null,this.animationPositionObserver=null,this.handleAnimationPositionChange=e=>{for(const t of e){const e=this.callbackAnimations.get(t.target);if(e){const n=t.boundingClientRect,{hitSlop:i,overlay:s}=e,o=n.left-i.left,r=n.top-i.top,a=n.width+i.left+i.right,l=n.height+i.top+i.bottom;s.style.transform=`translate3d(${o}px, ${r}px, 0)`,s.style.width=`${a}px`,s.style.height=`${l}px`}}},this.handleElementDataUpdated=e=>{switch(e.updatedProp){case"bounds":this.createOrUpdateElementOverlay(e.elementData);break;case"visibility":e.elementData.isIntersectingWithViewport||this.removeElementOverlay(e.elementData),this.controlPanel?.updateElementVisibilityStatus(e.elementData)}},this.handleUnregisterElement=e=>{this.controlPanel?.removeElementFromList(e.elementData),this.removeElementOverlay(e.elementData)},this.handleCallbackFired=e=>{this.showCallbackAnimation(e.elementData)},this.handleRegisterElement=e=>{this.createOrUpdateElementOverlay(e.elementData),this.controlPanel.addElementToList(e.elementData)},this.handleMouseTrajectoryUpdate=e=>{if(!this.shadowRoot||!this.debugContainer)return;if(!this.predictedMouseIndicator||!this.mouseTrajectoryLine)return;this.scrollTrajectoryLine&&(this.scrollTrajectoryLine.style.display="none");const{predictedPoint:t,currentPoint:n}=e.trajectoryPositions;if(this.predictedMouseIndicator.style.transform=`translate3d(${t.x}px, ${t.y}px, 0) translate3d(-50%, -50%, 0)`,this.predictedMouseIndicator.style.display=e.predictionEnabled?"block":"none",0===t.x&&0===t.y)return void(this.predictedMouseIndicator.style.display="none");if(!e.predictionEnabled)return void(this.mouseTrajectoryLine.style.display="none");const i=t.x-n.x,s=t.y-n.y,o=Math.sqrt(i*i+s*s),r=180*Math.atan2(s,i)/Math.PI;this.mouseTrajectoryLine.style.transform=`translate3d(${n.x}px, ${n.y}px, 0) rotate(${r}deg)`,this.mouseTrajectoryLine.style.width=`${o}px`,this.mouseTrajectoryLine.style.display="block"},this.handleScrollTrajectoryUpdate=e=>{if(!this.scrollTrajectoryLine)return;const t=e.predictedPoint.x-e.currentPoint.x,n=e.predictedPoint.y-e.currentPoint.y,i=Math.sqrt(t*t+n*n),s=180*Math.atan2(n,t)/Math.PI;this.scrollTrajectoryLine.style.transform=`translate3d(${e.currentPoint.x}px, ${e.currentPoint.y}px, 0) rotate(${s}deg)`,this.scrollTrajectoryLine.style.width=`${i}px`,this.scrollTrajectoryLine.style.display="block"},this.handleSettingsChanged=e=>{this.controlPanel?.updateControlsState(e.managerData.globalSettings,this._debuggerSettings)},this.foresightManagerInstance=e}get getDebuggerData(){return{settings:this._debuggerSettings}}static initialize(e,t){if("undefined"==typeof window||"undefined"==typeof window||"ontouchstart"in window)return null;y.isInitiated||(y.debuggerInstance=new y(e));const n=y.debuggerInstance;return n.subscribeToManagerEvents(),n.alterDebuggerSettings(t),n.shadowHost||n._setupDOM(),n}static get instance(){if(!y.debuggerInstance)throw new Error("ForesightDebugger has not been initialized. Call ForesightDebugger.initialize() first.");return y.debuggerInstance}_setupDOM(){this.shadowHost||(this.shadowHost=o("div",document.body,{id:"jsforesight-debugger-shadow-host"}),this.shadowRoot=this.shadowHost.attachShadow({mode:"open"}),this.debugContainer=o("div",this.shadowRoot,{id:"jsforesight-debug-container"}),this.predictedMouseIndicator=o("div",this.debugContainer,{className:"jsforesight-mouse-predicted"}),this.mouseTrajectoryLine=o("div",this.debugContainer,{className:"jsforesight-trajectory-line"}),this.scrollTrajectoryLine=o("div",this.debugContainer,{className:"jsforesight-scroll-trajectory-line"}),this.controlPanel=u.initialize(this.foresightManagerInstance,y.debuggerInstance,this.shadowRoot,this._debuggerSettings),r(f,this.shadowRoot,"screen-visuals"),this.animationPositionObserver=new i(this.handleAnimationPositionChange))}static get isInitiated(){return!!y.debuggerInstance}alterDebuggerSettings(e){m(e?.showNameTags,this._debuggerSettings.showNameTags)&&(this._debuggerSettings.showNameTags=e.showNameTags,this.toggleNameTagVisibility()),m(e?.isControlPanelDefaultMinimized,this._debuggerSettings.isControlPanelDefaultMinimized)&&(this._debuggerSettings.isControlPanelDefaultMinimized=e.isControlPanelDefaultMinimized),m(e?.sortElementList,this._debuggerSettings.sortElementList)&&(this._debuggerSettings.sortElementList=e.sortElementList),m(e?.showDebugger,this._debuggerSettings.showDebugger)&&(this._debuggerSettings.showDebugger=e.showDebugger,this._debuggerSettings.showDebugger?y.initialize(this.foresightManagerInstance):this.cleanup())}subscribeToManagerEvents(){this.managerSubscriptionsController=new AbortController;const e=this.managerSubscriptionsController.signal,t=this.foresightManagerInstance;t.addEventListener("elementRegistered",this.handleRegisterElement,{signal:e}),t.addEventListener("elementUnregistered",this.handleUnregisterElement,{signal:e}),t.addEventListener("elementDataUpdated",this.handleElementDataUpdated,{signal:e}),t.addEventListener("mouseTrajectoryUpdate",this.handleMouseTrajectoryUpdate,{signal:e}),t.addEventListener("scrollTrajectoryUpdate",this.handleScrollTrajectoryUpdate,{signal:e}),t.addEventListener("managerSettingsChanged",this.handleSettingsChanged,{signal:e}),t.addEventListener("callbackFired",this.handleCallbackFired,{signal:e})}createElementOverlays(e){const t={expandedOverlay:o("div",this.debugContainer,{className:"jsforesight-expanded-overlay",data:e.name}),nameLabel:o("div",this.debugContainer,{className:"jsforesight-name-label"})};return this.debugElementOverlays.set(e.element,t),t}createOrUpdateElementOverlay(e){if(!this.debugContainer||!this.shadowRoot)return;let t=this.debugElementOverlays.get(e.element);t||(t=this.createElementOverlays(e)),b(t,e,this._debuggerSettings.showNameTags??l)}toggleNameTagVisibility(){this.foresightManagerInstance.registeredElements.forEach(e=>{const t=this.debugElementOverlays.get(e.element);t&&b(t,e,this._debuggerSettings.showNameTags??l)})}removeElementOverlay(e){const t=this.debugElementOverlays.get(e.element);t&&(t.expandedOverlay.remove(),t.nameLabel.remove(),this.debugElementOverlays.delete(e.element))}showCallbackAnimation(e){const{element:t,elementBounds:n}=e,i=this.callbackAnimations.get(t);i&&(clearTimeout(i.timeoutId),i.overlay.remove(),this.animationPositionObserver?.unobserve(t),this.callbackAnimations.delete(t));const s=o("div",this.debugContainer,{className:"jsforesight-callback-indicator"}),{left:r,top:a,right:l,bottom:c}=n.expandedRect,d=l-r,h=c-a;s.style.display="block",s.style.transform=`translate3d(${r}px, ${a}px, 0)`,s.style.width=`${d}px`,s.style.height=`${h}px`,s.classList.add("animate");const g=setTimeout(()=>{s.remove(),this.callbackAnimations.delete(t),this.animationPositionObserver?.unobserve(t)},500);this.callbackAnimations.set(t,{hitSlop:e.elementBounds.hitSlop,overlay:s,timeoutId:g}),this.animationPositionObserver?.observe(t)}cleanup(){this.managerSubscriptionsController?.abort(),this.controlPanel?.cleanup(),this.shadowHost?.remove(),this.debugElementOverlays.clear(),this.shadowHost=null,this.shadowRoot=null,this.debugContainer=null,this.predictedMouseIndicator=null,this.mouseTrajectoryLine=null,this.scrollTrajectoryLine=null,this.controlPanel=null}}const f='\n #jsforesight-debug-container { \n position: fixed; top: 0; left: 0; width: 100%; height: 100%;\n pointer-events: none; z-index: 9999;\n }\n\n .jsforesight-expanded-overlay, \n .jsforesight-name-label, \n .jsforesight-callback-indicator,\n .jsforesight-mouse-predicted,\n .jsforesight-scroll-trajectory-line,\n .jsforesight-trajectory-line {\n position: absolute;\n top: 0;\n left: 0;\n will-change: transform; \n }\n .jsforesight-trajectory-line{\n display: none;\n }\n .jsforesight-expanded-overlay {\n border: 1px dashed rgba(100, 116, 139, 0.4);\n background-color: rgba(100, 116, 139, 0.05);\n box-sizing: border-box;\n border-radius: 8px;\n }\n .jsforesight-mouse-predicted {\n display: none !important;\n /* transform is now set dynamically via JS for performance */\n }\n .jsforesight-trajectory-line {\n height: 4px;\n background: linear-gradient(90deg, #3b82f6, rgba(59, 130, 246, 0.4));\n transform-origin: left center;\n z-index: 9999;\n border-radius: 2px;\n box-shadow: 0 0 12px rgba(59, 130, 246, 0.4);\n position: relative;\n /* width and transform are set dynamically via JS for performance */\n }\n .jsforesight-trajectory-line::after {\n content: \'\';\n position: absolute;\n right: -6px;\n top: 50%;\n transform: translateY(-50%);\n width: 0;\n height: 0;\n border-left: 8px solid #3b82f6;\n border-top: 4px solid transparent;\n border-bottom: 4px solid transparent;\n filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.6));\n }\n .jsforesight-name-label {\n background-color: rgba(27, 31, 35, 0.85);\n backdrop-filter: blur(4px);\n color: white;\n padding: 4px 8px;\n font-size: 11px;\n font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";\n border-radius: 4px;\n z-index: 10001;\n white-space: nowrap;\n pointer-events: none;\n }\n .jsforesight-callback-indicator {\n border: 4px solid oklch(65% 0.22 280); \n border-radius: 8px;\n box-sizing: border-box;\n pointer-events: none;\n opacity: 0;\n z-index: 10002;\n display: none; \n }\n .jsforesight-callback-indicator.animate {\n animation: jsforesight-callback-pulse 0.5s ease-out forwards;\n }\n \n .jsforesight-scroll-trajectory-line {\n height: 4px;\n background: repeating-linear-gradient(\n 90deg,\n #22c55e 0px,\n #22c55e 8px,\n transparent 8px,\n transparent 16px\n );\n transform-origin: left center;\n z-index: 9999;\n border-radius: 2px;\n display: none;\n animation: scroll-dash-flow 1.5s linear infinite;\n position: relative;\n box-shadow: 0 0 12px rgba(34, 197, 94, 0.4);\n }\n\n .jsforesight-scroll-trajectory-line::after {\n content: \'\';\n position: absolute;\n right: -6px;\n top: 50%;\n transform: translateY(-50%);\n width: 0;\n height: 0;\n border-left: 8px solid #22c55e;\n border-top: 4px solid transparent;\n border-bottom: 4px solid transparent;\n filter: drop-shadow(0 0 6px rgba(34, 197, 94, 0.6));\n animation: scroll-arrow-pulse 1.5s ease-in-out infinite;\n }\n\n @keyframes scroll-dash-flow {\n 0% { background-position: 0px 0px; }\n 100% { background-position: 16px 0px; }\n }\n\n @keyframes scroll-arrow-pulse {\n 0%, 100% { \n transform: translateY(-50%) scale(1);\n filter: drop-shadow(0 0 6px rgba(34, 197, 94, 0.6));\n }\n 50% {\n transform: translateY(-50%) scale(1.2);\n filter: drop-shadow(0 0 12px rgba(34, 197, 94, 0.8));\n }\n }\n\n\n \n @keyframes jsforesight-callback-pulse {\n 0% {\n opacity: 1;\n box-shadow: 0 0 15px oklch(65% 0.22 280 / 0.7);\n }\n 100% {\n opacity: 0;\n box-shadow: 0 0 25px oklch(65% 0.22 280 / 0);\n }\n }\n ';export{u as DebuggerControlPanel,y as ForesightDebugger};
18
- //# sourceMappingURL=index.mjs.map
1
+ var $e=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var i=(n,s,e,t)=>{for(var o=t>1?void 0:t?Ie(s,e):s,a=n.length-1,r;a>=0;a--)(r=n[a])&&(o=(t?r(s,e,o):r(o))||o);return t&&o&&$e(s,e,o),o};import{LitElement as Si,css as Ti,html as Oe}from"lit";import{customElement as Mi,state as _i}from"lit/decorators.js";import{LitElement as ii,css as oi,html as ni}from"lit";import{customElement as si,state as W}from"lit/decorators.js";import{classMap as Q}from"lit/directives/class-map.js";import{css as dt,html as ye,LitElement as ct}from"lit";import{customElement as pt,state as y}from"lit/decorators.js";import{map as gt}from"lit/directives/map.js";import{LitElement as Pe,html as Ue,css as Ne}from"lit";import{customElement as je}from"lit/decorators.js";var j=class extends Pe{render(){return Ue`
2
+ <div class="tab-bar-elements">
3
+ <div class="tab-bar-info">
4
+ <div class="stats-chips">
5
+ <slot name="chips"></slot>
6
+ </div>
7
+ </div>
8
+ <div class="tab-bar-actions">
9
+ <slot name="actions"></slot>
10
+ </div>
11
+ </div>
12
+ `}};j.styles=[Ne`
13
+ :host {
14
+ }
15
+ .tab-bar-info {
16
+ display: flex;
17
+ gap: 12px;
18
+ align-items: center;
19
+ flex: 1;
20
+ }
21
+
22
+ .stats-chips {
23
+ display: flex;
24
+ gap: 8px;
25
+ align-items: center;
26
+ }
27
+
28
+ .chip {
29
+ font-size: 11px;
30
+ font-weight: 500;
31
+ padding: 4px 8px;
32
+ border: 1px solid #555;
33
+ white-space: nowrap;
34
+ letter-spacing: 0.3px;
35
+ background: rgba(40, 40, 40, 0.7);
36
+ color: #b0c4de;
37
+ }
38
+
39
+ .tab-bar-actions {
40
+ display: flex;
41
+ gap: 6px;
42
+ align-items: center;
43
+ position: relative;
44
+ flex-direction: row;
45
+ }
46
+ .tab-bar-elements {
47
+ display: flex;
48
+ justify-content: space-between;
49
+ padding: 4px 0 4px 0;
50
+ border-bottom: 1px solid #444;
51
+ position: sticky;
52
+ top: 0;
53
+ z-index: 5;
54
+ min-height: 36px;
55
+ }
56
+ `],j=i([je("tab-header")],j);import{LitElement as Fe,html as K,css as Ve}from"lit";import{customElement as ze,property as ie}from"lit/decorators.js";var T=class extends Fe{constructor(){super(...arguments);this.noContentMessage="No content available.";this.hasContent=!0}render(){return K`
57
+ <div class="content-container">
58
+ ${this.hasContent?K`<slot></slot>`:K`<div class="no-content-message">${this.noContentMessage}</div>`}
59
+ </div>
60
+ `}};T.styles=[Ve`
61
+ :host {
62
+ overflow: hidden;
63
+ }
64
+
65
+ .content-container::-webkit-scrollbar {
66
+ width: 8px;
67
+ }
68
+
69
+ .content-container::-webkit-scrollbar-track {
70
+ background: rgba(30, 30, 30, 0.5);
71
+ }
72
+
73
+ .content-container::-webkit-scrollbar-thumb {
74
+ background-color: rgba(176, 196, 222, 0.5);
75
+ border: 2px solid rgba(0, 0, 0, 0.2);
76
+ }
77
+
78
+ .content-container::-webkit-scrollbar-thumb:hover {
79
+ background-color: rgba(176, 196, 222, 0.7);
80
+ }
81
+
82
+ .content-container {
83
+ height: 100%;
84
+ min-height: 150px;
85
+ overflow-y: auto;
86
+ scrollbar-width: thin;
87
+ scrollbar-color: rgba(176, 196, 222, 0.5) rgba(30, 30, 30, 0.5);
88
+ }
89
+
90
+ .no-content-message {
91
+ display: flex;
92
+ justify-content: center;
93
+ align-items: center;
94
+ height: 100%;
95
+ color: #afafaf;
96
+ font-style: italic;
97
+ font-family: "Courier New", monospace;
98
+ }
99
+ `],i([ie({type:String,attribute:"no-content-message"})],T.prototype,"noContentMessage",2),i([ie({type:Boolean})],T.prototype,"hasContent",2),T=i([ze("tab-content")],T);import{html as Ge}from"lit";import{customElement as We,property as ne}from"lit/decorators.js";import{LitElement as Re,html as oe,css as Ae}from"lit";import{property as He,state as Be}from"lit/decorators.js";var d=class d extends Re{constructor(){super(...arguments);this.isDropdownOpen=!1;this.dropdownOptions=[];this._toggleDropdown=e=>{e.stopPropagation(),this.isDropdownOpen?this._closeDropdown():(d.currentlyOpen&&d.currentlyOpen!==this&&d.currentlyOpen._closeDropdown(),this.isDropdownOpen=!0,d.currentlyOpen=this,requestAnimationFrame(()=>{this._positionDropdown()}))};this._handleOutsideClick=e=>{this.isDropdownOpen&&(e.composedPath().includes(this)||this._closeDropdown())}}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this._handleOutsideClick)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this._handleOutsideClick),d.currentlyOpen===this&&(d.currentlyOpen=null)}_closeDropdown(){this.isDropdownOpen=!1,d.currentlyOpen===this&&(d.currentlyOpen=null)}_positionDropdown(){let e=this.shadowRoot?.querySelector(".trigger-button"),t=this.shadowRoot?.querySelector(".dropdown-menu");if(e&&t){let o=e.getBoundingClientRect(),a=t.offsetHeight||200,r=o.bottom+5,N=window.innerWidth-o.right;window.innerHeight-o.bottom<a&&o.top>a?t.style.top=`${o.top-a-5}px`:t.style.top=`${r}px`,t.style.right=`${N}px`}}render(){let e=`trigger-button ${this.isDropdownOpen?"active":""}`,t=`dropdown-menu ${this.isDropdownOpen?"active":""}`;return oe`
100
+ <div class="dropdown-container">
101
+ <button
102
+ class="${e}"
103
+ title="${this._getTriggerTitle()}"
104
+ @click="${this._toggleDropdown}"
105
+ aria-haspopup="true"
106
+ aria-expanded="${this.isDropdownOpen}"
107
+ aria-controls="dropdown-menu"
108
+ aria-label="${this._getTriggerLabel()}"
109
+ >
110
+ ${this._getTriggerIcon()}
111
+ <svg
112
+ class="arrow-icon"
113
+ xmlns="http://www.w3.org/2000/svg"
114
+ viewBox="0 0 24 24"
115
+ stroke="currentColor"
116
+ stroke-width="2"
117
+ stroke-linecap="round"
118
+ stroke-linejoin="round"
119
+ >
120
+ <polyline points="6 9 12 15 18 9"></polyline>
121
+ </svg>
122
+ </button>
123
+
124
+ <div class="${t}" id="dropdown-menu" role="menu">
125
+ ${this.dropdownOptions.map(o=>oe`
126
+ <button
127
+ value="${o.value}"
128
+ title="${o.title}"
129
+ class="${this._isOptionSelected(o)?"active":""}"
130
+ @click="${()=>this._handleOptionClick(o)}"
131
+ role="menuitem"
132
+ >
133
+ ${o.label}
134
+ </button>
135
+ `)}
136
+ </div>
137
+ </div>
138
+ `}};d.currentlyOpen=null,d.styles=[Ae`
139
+ :host {
140
+ display: inline-block;
141
+ }
142
+
143
+ .dropdown-container {
144
+ position: relative;
145
+ display: inline-block;
146
+ }
147
+
148
+ .trigger-button {
149
+ background: none;
150
+ border: none;
151
+ color: white;
152
+ cursor: pointer;
153
+ padding: 6px;
154
+ display: flex;
155
+ align-items: center;
156
+ justify-content: center;
157
+ gap: 4px;
158
+ transition: all 0.2s ease;
159
+ }
160
+
161
+ .trigger-button svg {
162
+ width: 16px;
163
+ height: 16px;
164
+ stroke: white;
165
+ transition: stroke 0.2s;
166
+ }
167
+
168
+ .trigger-button .arrow-icon {
169
+ width: 10px;
170
+ height: 10px;
171
+ stroke: white;
172
+ fill: none;
173
+ stroke-width: 2;
174
+ transition: transform 0.2s ease, stroke 0.2s;
175
+ }
176
+
177
+ .trigger-button:hover {
178
+ background-color: rgba(176, 196, 222, 0.1);
179
+ }
180
+
181
+ .trigger-button:hover svg,
182
+ .trigger-button:hover .arrow-icon {
183
+ stroke: #b0c4de;
184
+ }
185
+
186
+ .trigger-button.active {
187
+ background-color: rgba(176, 196, 222, 0.2);
188
+ }
189
+
190
+ .trigger-button.active svg {
191
+ stroke: #b0c4de;
192
+ }
193
+
194
+ .trigger-button.active .arrow-icon {
195
+ transform: rotate(180deg);
196
+ stroke: #b0c4de;
197
+ }
198
+
199
+ .dropdown-menu {
200
+ position: fixed;
201
+ z-index: 9999;
202
+ display: none;
203
+ flex-direction: column;
204
+ background-color: #3a3a3a;
205
+ border: 1px solid #555;
206
+ min-width: 200px;
207
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
208
+ overflow: hidden;
209
+ }
210
+
211
+ .dropdown-menu.active {
212
+ display: flex;
213
+ }
214
+
215
+ .dropdown-menu button {
216
+ background: none;
217
+ border: none;
218
+ color: #ccc;
219
+ font-size: 12px;
220
+ text-align: left;
221
+ padding: 8px 12px;
222
+ cursor: pointer;
223
+ transition: all 0.2s ease;
224
+ display: flex;
225
+ align-items: center;
226
+ position: relative;
227
+ width: 100%;
228
+ box-sizing: border-box;
229
+ }
230
+
231
+ .dropdown-menu button:hover {
232
+ background-color: #555;
233
+ color: white;
234
+ }
235
+
236
+ .dropdown-menu button.active {
237
+ color: #b0c4de;
238
+ font-weight: bold;
239
+ background-color: rgba(176, 196, 222, 0.1);
240
+ }
241
+
242
+ .dropdown-menu button.active::after {
243
+ content: "✓";
244
+ position: absolute;
245
+ right: 8px;
246
+ top: 50%;
247
+ transform: translateY(-50%);
248
+ color: #b0c4de;
249
+ font-weight: bold;
250
+ }
251
+ `],i([Be()],d.prototype,"isDropdownOpen",2),i([He({type:Array})],d.prototype,"dropdownOptions",2);var M=d;var O=class extends M{constructor(){super(...arguments);this.selectedOptionValue=""}connectedCallback(){super.connectedCallback(),this.dropdownOptions.length>0&&!this.selectedOptionValue&&(this.selectedOptionValue=this.dropdownOptions[0].value)}willUpdate(e){e.has("dropdownOptions")&&this.dropdownOptions.length>0&&!this.selectedOptionValue&&(this.selectedOptionValue=this.dropdownOptions[0].value)}_handleOptionClick(e){e.value!==this.selectedOptionValue&&(this.selectedOptionValue=e.value,this.onSelectionChange?.(e.value)),this._closeDropdown()}_getTriggerIcon(){let e=this._getSelectedOption();return e?e.icon:Ge``}_isOptionSelected(e){return e.value===this.selectedOptionValue}_getTriggerTitle(){let e=this._getSelectedOption();return e?e.title:"Change selection"}_getTriggerLabel(){let e=this._getSelectedOption();return e?`Current selection: ${e.label}`:"No selection"}_getSelectedOption(){return this.dropdownOptions.find(e=>e.value===this.selectedOptionValue)}};i([ne({type:String})],O.prototype,"selectedOptionValue",2),i([ne({type:Function})],O.prototype,"onSelectionChange",2),O=i([We("single-select-dropdown")],O);import{LitElement as Ye,html as qe,css as Ke}from"lit";import{customElement as Je,property as Xe}from"lit/decorators.js";var $=class extends Ye{constructor(){super(...arguments);this.title=""}render(){return qe`
252
+ <span class="chip" title="${this.title}">
253
+ <slot></slot>
254
+ </span>
255
+ `}};$.styles=[Ke`
256
+ :host {
257
+ display: inline-block;
258
+ }
259
+
260
+ .chip {
261
+ display: inline-flex;
262
+ align-items: center;
263
+ padding: 3px 8px;
264
+ background-color: rgba(255, 255, 255, 0.05);
265
+ color: #e8e8e8;
266
+ font-size: 10px;
267
+ font-weight: 500;
268
+ white-space: nowrap;
269
+ border: 1px solid rgba(255, 255, 255, 0.1);
270
+ font-family: "SF Mono", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;
271
+ letter-spacing: 0.02em;
272
+ line-height: 1.2;
273
+ transition: all 0.2s ease;
274
+ }
275
+ `],i([Xe({type:String})],$.prototype,"title",2),$=i([Je("chip-element")],$);import{LitElement as st,html as at,css as rt}from"lit";import{customElement as lt,property as A}from"lit/decorators.js";import{LitElement as it,html as fe,css as ot}from"lit";import{customElement as nt,property as F}from"lit/decorators.js";import{LitElement as Ze,html as Qe,css as et}from"lit";import{customElement as tt,property as be,state as ve}from"lit/decorators.js";import{html as g}from"lit";var se=g`
276
+ <svg
277
+ xmlns="http://www.w3.org/2000/svg"
278
+ width="16"
279
+ height="16"
280
+ viewBox="0 0 24 24"
281
+ fill="none"
282
+ stroke="currentColor"
283
+ stroke-width="2"
284
+ stroke-linecap="round"
285
+ stroke-linejoin="round"
286
+ >
287
+ <rect x="2" y="2" width="20" height="15" rx="2" ry="2"></rect>
288
+ <line x1="2" y1="17" x2="22" y2="17"></line>
289
+ <line x1="7" y1="21" x2="17" y2="21"></line>
290
+ <line x1="12" y1="17" x2="12" y2="21"></line>
291
+ </svg>
292
+ `,ae=g`
293
+ <svg
294
+ xmlns="http://www.w3.org/2000/svg"
295
+ width="16"
296
+ height="16"
297
+ viewBox="0 0 24 24"
298
+ fill="none"
299
+ stroke="currentColor"
300
+ stroke-width="2"
301
+ stroke-linecap="round"
302
+ stroke-linejoin="round"
303
+ >
304
+ <polyline points="4 17 10 11 4 5"></polyline>
305
+ <line x1="12" y1="19" x2="20" y2="19"></line>
306
+ </svg>
307
+ `,re=g`
308
+ <svg
309
+ xmlns="http://www.w3.org/2000/svg"
310
+ width="16"
311
+ height="16"
312
+ viewBox="0 0 24 24"
313
+ fill="none"
314
+ stroke="currentColor"
315
+ stroke-width="2"
316
+ stroke-linecap="round"
317
+ stroke-linejoin="round"
318
+ >
319
+ <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path>
320
+ <path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
321
+ <line x1="1" y1="1" x2="23" y2="23"></line>
322
+ </svg>
323
+ `,le=g`
324
+ <svg
325
+ xmlns="http://www.w3.org/2000/svg"
326
+ width="16"
327
+ height="16"
328
+ viewBox="0 0 24 24"
329
+ fill="none"
330
+ stroke="currentColor"
331
+ stroke-width="2"
332
+ stroke-linecap="round"
333
+ stroke-linejoin="round"
334
+ >
335
+ <path d="M12 2v8" />
336
+ <path d="M12 10l-6 6" />
337
+ <path d="M12 10l6 6" />
338
+ <circle cx="6" cy="18" r="2" />
339
+ <circle cx="18" cy="18" r="2" />
340
+ </svg>
341
+ `,de=g`
342
+ <svg
343
+ xmlns="http://www.w3.org/2000/svg"
344
+ width="16"
345
+ height="16"
346
+ viewBox="0 0 24 24"
347
+ fill="none"
348
+ stroke="currentColor"
349
+ stroke-width="2"
350
+ stroke-linecap="round"
351
+ stroke-linejoin="round"
352
+ >
353
+ <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
354
+ <circle cx="12" cy="12" r="3" />
355
+ </svg>
356
+ `,ce=g`
357
+ <svg
358
+ xmlns="http://www.w3.org/2000/svg"
359
+ width="16"
360
+ height="16"
361
+ viewBox="0 0 24 24"
362
+ fill="none"
363
+ stroke="currentColor"
364
+ stroke-width="2"
365
+ stroke-linecap="round"
366
+ stroke-linejoin="round"
367
+ >
368
+ <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" />
369
+ <polyline points="14 2 14 8 20 8" />
370
+ <line x1="16" y1="13" x2="8" y2="13" />
371
+ <line x1="16" y1="17" x2="8" y2="17" />
372
+ <line x1="10" y1="9" x2="8" y2="9" />
373
+ </svg>
374
+ `,pe=g`
375
+ <svg
376
+ xmlns="http://www.w3.org/2000/svg"
377
+ width="16"
378
+ height="16"
379
+ viewBox="0 0 24 24"
380
+ fill="none"
381
+ stroke="currentColor"
382
+ stroke-width="2"
383
+ stroke-linecap="round"
384
+ stroke-linejoin="round"
385
+ >
386
+ <path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" />
387
+ </svg>
388
+ `,m=g`
389
+ <svg
390
+ xmlns="http://www.w3.org/2000/svg"
391
+ width="16"
392
+ height="16"
393
+ viewBox="0 0 24 24"
394
+ fill="none"
395
+ stroke="currentColor"
396
+ stroke-width="2"
397
+ stroke-linecap="round"
398
+ stroke-linejoin="round"
399
+ >
400
+ <polygon points="22,3 2,3 10,12.46 10,19 14,21 14,12.46" />
401
+ </svg>
402
+ `,ge=g`
403
+ <svg
404
+ xmlns="http://www.w3.org/2000/svg"
405
+ width="16"
406
+ height="16"
407
+ viewBox="0 0 24 24"
408
+ fill="none"
409
+ stroke="currentColor"
410
+ stroke-width="2"
411
+ stroke-linecap="round"
412
+ stroke-linejoin="round"
413
+ >
414
+ <circle cx="12" cy="12" r="10" />
415
+ <line x1="4.93" y1="4.93" x2="19.07" y2="19.07" />
416
+ </svg>
417
+ `,he=g`
418
+ <svg
419
+ xmlns="http://www.w3.org/2000/svg"
420
+ width="24"
421
+ height="24"
422
+ viewBox="0 0 24 24"
423
+ fill="none"
424
+ stroke="currentColor"
425
+ stroke-width="2"
426
+ stroke-linecap="round"
427
+ stroke-linejoin="round"
428
+ >
429
+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
430
+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
431
+ </svg>
432
+ `,me=g`
433
+ <svg
434
+ xmlns="http://www.w3.org/2000/svg"
435
+ width="24"
436
+ height="24"
437
+ viewBox="0 0 24 24"
438
+ fill="none"
439
+ stroke="currentColor"
440
+ stroke-width="2"
441
+ stroke-linecap="round"
442
+ stroke-linejoin="round"
443
+ >
444
+ <polyline points="20 6 9 17 4 12"></polyline>
445
+ </svg>
446
+ `,ue=g`
447
+ <svg
448
+ xmlns="http://www.w3.org/2000/svg"
449
+ width="16"
450
+ height="16"
451
+ viewBox="0 0 24 24"
452
+ fill="none"
453
+ stroke="currentColor"
454
+ stroke-width="2"
455
+ stroke-linecap="round"
456
+ stroke-linejoin="round"
457
+ >
458
+ <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
459
+ <line x1="12" y1="9" x2="12" y2="13"></line>
460
+ <line x1="12" y1="17" x2="12.01" y2="17"></line>
461
+ </svg>
462
+ `;var v=class extends Ze{constructor(){super(...arguments);this.title="Copy to clipboard";this.isCopied=!1;this.copyTimeout=null}async handleClick(e){if(!this.isCopied){if(this.onCopy)try{await this.onCopy(e)}catch(t){console.error("Error in onCopy function:",t)}this.isCopied=!0,this.copyTimeout&&clearTimeout(this.copyTimeout),this.copyTimeout=setTimeout(()=>{this.isCopied=!1,this.copyTimeout=null},2e3)}}disconnectedCallback(){super.disconnectedCallback(),this.copyTimeout&&(clearTimeout(this.copyTimeout),this.copyTimeout=null)}render(){return Qe`
463
+ <button
464
+ class="copy-button ${this.isCopied?"copied":""}"
465
+ title="${this.title}"
466
+ @click=${this.handleClick}
467
+ >
468
+ ${this.isCopied?me:he}
469
+ </button>
470
+ `}};v.styles=et`
471
+ .copy-button {
472
+ background: transparent;
473
+ border: 0px;
474
+ cursor: pointer;
475
+ padding: 6px;
476
+ display: flex;
477
+ align-items: center;
478
+ justify-content: center;
479
+ opacity: 0.6;
480
+ transition: opacity 0.2s ease, background-color 0.2s ease;
481
+ }
482
+
483
+ :host([positioned]) .copy-button {
484
+ position: absolute;
485
+ top: 10px;
486
+ right: 1px;
487
+ }
488
+
489
+ .copy-button:hover {
490
+ background-color: rgba(176, 196, 222, 0.1);
491
+ }
492
+
493
+ .copy-button:hover svg {
494
+ stroke: #b0c4de;
495
+ }
496
+
497
+ .copy-button svg {
498
+ width: 14px;
499
+ height: 14px;
500
+ stroke: #ddd;
501
+ stroke-width: 2.5;
502
+ }
503
+
504
+ .copy-button.copied svg {
505
+ stroke: #4caf50;
506
+ }
507
+ `,i([be({type:String})],v.prototype,"title",2),i([be({type:Function})],v.prototype,"onCopy",2),i([ve()],v.prototype,"isCopied",2),i([ve()],v.prototype,"copyTimeout",2),v=i([tt("copy-icon")],v);var u=class extends it{constructor(){super(...arguments);this.borderColor="#555";this.showCopyButton=!1;this.itemId="";this.isExpanded=!1}toggleExpand(){this.onToggle&&this.onToggle(this.itemId)}async handleCopy(e){e.stopPropagation();let t=this.shadowRoot?.querySelector('slot[name="details"]');if(t){let a=t.assignedNodes().map(r=>r.textContent).join("");try{await navigator.clipboard.writeText(a)}catch(r){console.error("Failed to copy text: ",r)}}}render(){return this.style.setProperty("--border-color",this.borderColor),fe`
508
+ <div class="item-entry ${this.isExpanded?"expanded":""}">
509
+ <div class="item-header ${this.isExpanded?"expanded":""}" @click="${this.toggleExpand}">
510
+ <div class="item-content">
511
+ <slot name="content"></slot>
512
+ </div>
513
+ <span class="item-toggle ${this.isExpanded?"expanded":""}">
514
+ <svg viewBox="0 0 24 24">
515
+ <polyline points="9,18 15,12 9,6"></polyline>
516
+ </svg>
517
+ </span>
518
+ </div>
519
+ ${this.isExpanded?fe`
520
+ <div class="item-details">
521
+ <copy-icon
522
+ positioned
523
+ title="Copy Details"
524
+ .onCopy=${e=>this.handleCopy(e)}
525
+ ></copy-icon>
526
+ <pre class="item-data">
527
+ <slot name="details"></slot>
528
+ </pre>
529
+ </div>
530
+ `:""}
531
+ </div>
532
+ `}};u.styles=[ot`
533
+ :host {
534
+ display: block;
535
+ }
536
+
537
+ .item-entry {
538
+ margin-bottom: 2px;
539
+ font-size: 11px;
540
+ line-height: 1.3;
541
+ overflow: hidden;
542
+ transition: all 0.2s ease;
543
+ border-left: 2px solid var(--border-color, #555);
544
+ padding-left: 6px;
545
+ }
546
+
547
+ .item-entry:hover:not(.expanded) {
548
+ background-color: rgba(255, 255, 255, 0.02);
549
+ }
550
+
551
+ .item-entry.expanded {
552
+ background-color: rgba(255, 255, 255, 0.03);
553
+ }
554
+
555
+ .item-header {
556
+ display: flex;
557
+ align-items: center;
558
+ padding: 3px 4px;
559
+ cursor: pointer;
560
+ transition: background-color 0.2s ease;
561
+ gap: 8px;
562
+ min-height: 20px;
563
+ }
564
+
565
+ .item-header:hover:not(.expanded) {
566
+ background-color: rgba(255, 255, 255, 0.03);
567
+ }
568
+
569
+ .item-details {
570
+ position: relative;
571
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
572
+ }
573
+
574
+ .item-toggle {
575
+ display: flex;
576
+ align-items: center;
577
+ justify-content: center;
578
+ width: 16px;
579
+ height: 16px;
580
+ margin-left: 4px;
581
+ user-select: none;
582
+ cursor: pointer;
583
+ transition: all 0.2s ease;
584
+ border-radius: 2px;
585
+ }
586
+
587
+ .item-toggle:hover {
588
+ background-color: rgba(255, 255, 255, 0.1);
589
+ }
590
+
591
+ .item-toggle svg {
592
+ width: 12px;
593
+ height: 12px;
594
+ fill: none;
595
+ stroke: #b0c4de;
596
+ stroke-width: 2;
597
+ stroke-linecap: round;
598
+ stroke-linejoin: round;
599
+ transition: all 0.2s ease;
600
+ }
601
+
602
+ .item-toggle:hover svg {
603
+ stroke: #d4e4f4;
604
+ }
605
+
606
+ .item-toggle.expanded svg {
607
+ transform: rotate(90deg);
608
+ }
609
+
610
+ .item-content {
611
+ flex: 1;
612
+ display: flex;
613
+ align-items: center;
614
+ gap: 8px;
615
+ min-width: 0;
616
+ overflow: hidden;
617
+ }
618
+
619
+ .item-data {
620
+ color: #e0e0e0;
621
+ white-space: pre;
622
+ font-size: 11px;
623
+ margin: 0;
624
+ padding: 0;
625
+ font-family: "Courier New", monospace;
626
+ line-height: 1.3;
627
+ display: block;
628
+ overflow-x: auto;
629
+ }
630
+ `],i([F()],u.prototype,"borderColor",2),i([F()],u.prototype,"showCopyButton",2),i([F()],u.prototype,"itemId",2),i([F()],u.prototype,"isExpanded",2),i([F()],u.prototype,"onToggle",2),u=i([nt("expandable-item")],u);var f=class extends st{constructor(){super(...arguments);this.isActive=!1;this.isExpanded=!1}getBorderColor(){return this.isActive?"#ffeb3b":this.elementData.isIntersectingWithViewport?"#4caf50":"#666"}getStatusIndicatorClass(){return this.isActive?"prefetching":this.elementData.isIntersectingWithViewport?"visible":"hidden"}formatElementDetails(){let e={tagName:this.elementData.element.tagName.toLowerCase(),isIntersecting:this.elementData.isIntersectingWithViewport,registerCount:this.elementData.registerCount,hitSlop:{top:this.elementData.elementBounds.hitSlop.top,right:this.elementData.elementBounds.hitSlop.right,bottom:this.elementData.elementBounds.hitSlop.bottom,left:this.elementData.elementBounds.hitSlop.left}};return JSON.stringify(e,null,2)}render(){return at`
631
+ <expandable-item
632
+ .borderColor=${this.getBorderColor()}
633
+ .showCopyButton=${!0}
634
+ .itemId=${this.elementData.elementId}
635
+ .isExpanded=${this.isExpanded}
636
+ .onToggle=${this.onToggle}
637
+ >
638
+ <div slot="content" class="element-content">
639
+ <div class="status-indicator ${this.getStatusIndicatorClass()}"></div>
640
+ <span class="element-name ${this.isActive?"callback-active":""}">
641
+ ${this.elementData.name||"unnamed"}
642
+ </span>
643
+ </div>
644
+ <div slot="details">${this.formatElementDetails()}</div>
645
+ </expandable-item>
646
+ `}};f.styles=[rt`
647
+ :host {
648
+ display: block;
649
+ }
650
+
651
+ .element-content {
652
+ display: flex;
653
+ align-items: center;
654
+ gap: 8px;
655
+ flex: 1;
656
+ }
657
+
658
+ .status-indicator {
659
+ width: 8px;
660
+ height: 8px;
661
+ flex-shrink: 0;
662
+ transition: all 0.3s ease;
663
+ }
664
+
665
+ .status-indicator.visible {
666
+ background-color: #4caf50;
667
+ box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.3);
668
+ }
669
+
670
+ .status-indicator.hidden {
671
+ background-color: #666;
672
+ box-shadow: 0 0 0 2px rgba(102, 102, 102, 0.2);
673
+ }
674
+
675
+ .status-indicator.prefetching {
676
+ background-color: #ffeb3b;
677
+ box-shadow: 0 0 0 2px rgba(255, 235, 59, 0.4);
678
+ }
679
+
680
+ .element-name {
681
+ flex-grow: 1;
682
+ white-space: nowrap;
683
+ overflow: hidden;
684
+ text-overflow: ellipsis;
685
+ font-size: 11px;
686
+ font-weight: 500;
687
+ color: #e8e8e8;
688
+ }
689
+
690
+ .element-name.callback-active {
691
+ color: #fff;
692
+ font-weight: 600;
693
+ }
694
+ `],i([A()],f.prototype,"elementData",2),i([A()],f.prototype,"isActive",2),i([A()],f.prototype,"isExpanded",2),i([A()],f.prototype,"onToggle",2),f=i([lt("single-element")],f);import{ForesightManager as I}from"js.foresight";var c=class extends ct{constructor(){super();this.hitCount={mouse:{hover:0,trajectory:0},scroll:{down:0,left:0,right:0,up:0},tab:{forwards:0,reverse:0},total:0};this.visibleElementsCount=0;this.totalElementsCount=0;this.elementListItems=new Map;this.noContentMessage="No Elements Registered To The Foresight Manager";this.activeCallbacks=new Set;this.expandedElementIds=new Set;this.elementIdCounter=0;this._abortController=null;this.handleSortChange=e=>{this.sortOrder=e};this.handleElementToggle=e=>{let t=new Set(this.expandedElementIds);t.has(e)?t.delete(e):t.add(e),this.expandedElementIds=t};this.sortByDocumentPosition=(e,t)=>{let o=e.element.compareDocumentPosition(t.element);return o&Node.DOCUMENT_POSITION_FOLLOWING?-1:o&Node.DOCUMENT_POSITION_PRECEDING?1:0};this.sortOrder=l.instance.devtoolsSettings.sortElementList,this.sortDropdown=[{value:"visibility",label:"Visibility",title:"Sort by Visibility",icon:de},{value:"documentOrder",label:"Document Order",title:"Sort by Document Order",icon:ce},{value:"insertionOrder",label:"Insertion Order",title:"Sort by Insertion Order",icon:pe}]}generateElementId(){return(++this.elementIdCounter).toString()}updateVisibilityCounts(){let e=0,t=0;this.elementListItems.forEach(o=>{t++,o.isIntersectingWithViewport&&e++}),this.visibleElementsCount=e,this.totalElementsCount=t,this.dispatchEvent(new CustomEvent("visibility-count-updated",{detail:{visibleCount:e,totalCount:t},bubbles:!0,composed:!0}))}_generateHitsChipTitle(e){let t=[];return t.push(`Total Hits: ${e.total}`),t.push(""),t.push(`Mouse: Trajectory: ${e.mouse.trajectory}, Hover: ${e.mouse.hover}`),t.push(`Scroll: Up: ${e.scroll.up}, Down: ${e.scroll.down}, Left: ${e.scroll.left}, Right: ${e.scroll.right}`),t.push(`Tab: Forwards: ${e.tab.forwards}, Reverse: ${e.tab.reverse}`),t.join(`
695
+ `)}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;this.updateElementListFromManager(),this.updateVisibilityCounts(),I.instance.addEventListener("elementRegistered",t=>{let o={...t.elementData,elementId:this.generateElementId()};this.elementListItems.set(t.elementData.element,o),this.updateVisibilityCounts()},{signal:e}),I.instance.addEventListener("elementDataUpdated",t=>{let o=this.elementListItems.get(t.elementData.element);if(o){let a={...t.elementData,elementId:o.elementId};this.elementListItems.set(t.elementData.element,a),this.updateVisibilityCounts(),this.requestUpdate()}},{signal:e}),I.instance.addEventListener("elementUnregistered",t=>{this.elementListItems.delete(t.elementData.element),this.updateVisibilityCounts(),this.elementListItems.size||(this.noContentMessage="No Elements Registered To The Foresight Manager"),this.requestUpdate(),this.activeCallbacks.delete(t.elementData.element)},{signal:e}),I.instance.addEventListener("callbackInvoked",t=>{this.activeCallbacks.add(t.elementData.element),this.requestUpdate()},{signal:e}),I.instance.addEventListener("callbackCompleted",t=>{this.handleCallbackCompleted(t.hitType),this.activeCallbacks.delete(t.elementData.element)},{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}updateElementListFromManager(){let e=new Map;I.instance.registeredElements.forEach((t,o)=>{e.set(o,{...t,elementId:this.generateElementId()})}),this.elementListItems=e}handleCallbackCompleted(e){switch(e.kind){case"mouse":this.hitCount.mouse[e.subType]++;break;case"tab":this.hitCount.tab[e.subType]++;break;case"scroll":this.hitCount.scroll[e.subType]++;break;default:}this.hitCount.total++,this.requestUpdate()}getSortedElements(){let e=Array.from(this.elementListItems.values());switch(this.sortOrder){case"insertionOrder":return e;case"documentOrder":return e.sort(this.sortByDocumentPosition);case"visibility":return e.sort((t,o)=>t.isIntersectingWithViewport!==o.isIntersectingWithViewport?t.isIntersectingWithViewport?-1:1:this.sortByDocumentPosition(t,o));default:return this.sortOrder,e}}render(){return ye`
696
+ <tab-header>
697
+ <div slot="chips" class="chips-container">
698
+ <chip-element title="Number of visible registered elements / total registered elements">
699
+ ${this.visibleElementsCount}/${this.totalElementsCount} visible
700
+ </chip-element>
701
+ <chip-element title="${this._generateHitsChipTitle(this.hitCount)}">
702
+ ${this.hitCount.total} hits
703
+ </chip-element>
704
+ </div>
705
+ <div slot="actions">
706
+ <single-select-dropdown
707
+ .dropdownOptions="${this.sortDropdown}"
708
+ .selectedOptionValue="${this.sortOrder}"
709
+ .onSelectionChange="${this.handleSortChange}"
710
+ ></single-select-dropdown>
711
+ </div>
712
+ </tab-header>
713
+ <tab-content
714
+ .noContentMessage=${this.noContentMessage}
715
+ .hasContent=${!!this.elementListItems.size}
716
+ >
717
+ ${gt(this.getSortedElements(),e=>ye`
718
+ <single-element
719
+ .elementData=${e}
720
+ .isActive=${this.activeCallbacks.has(e.element)}
721
+ .isExpanded=${this.expandedElementIds.has(e.elementId)}
722
+ .onToggle=${this.handleElementToggle}
723
+ ></single-element>
724
+ `)}
725
+ </tab-content>
726
+ `}};c.styles=dt`
727
+ :host {
728
+ display: flex;
729
+ flex-direction: column;
730
+ height: 100%;
731
+ }
732
+
733
+ .chips-container {
734
+ display: flex;
735
+ gap: 8px;
736
+ }
737
+
738
+ .element-content {
739
+ display: flex;
740
+ align-items: center;
741
+ gap: 8px;
742
+ flex: 1;
743
+ }
744
+
745
+ .status-indicator {
746
+ width: 8px;
747
+ height: 8px;
748
+ flex-shrink: 0;
749
+ transition: all 0.3s ease;
750
+ }
751
+
752
+ .status-indicator.visible {
753
+ background-color: #4caf50;
754
+ box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.3);
755
+ }
756
+
757
+ .status-indicator.hidden {
758
+ background-color: #666;
759
+ box-shadow: 0 0 0 2px rgba(102, 102, 102, 0.2);
760
+ }
761
+
762
+ .status-indicator.prefetching {
763
+ background-color: #ffeb3b;
764
+ box-shadow: 0 0 0 2px rgba(255, 235, 59, 0.4);
765
+ }
766
+
767
+ .element-name {
768
+ flex-grow: 1;
769
+ white-space: nowrap;
770
+ overflow: hidden;
771
+ text-overflow: ellipsis;
772
+ font-size: 11px;
773
+ font-weight: 500;
774
+ color: #e8e8e8;
775
+ }
776
+
777
+ .element-name.callback-active {
778
+ color: #fff;
779
+ font-weight: 600;
780
+ }
781
+ `,i([y()],c.prototype,"hitCount",2),i([y()],c.prototype,"visibleElementsCount",2),i([y()],c.prototype,"totalElementsCount",2),i([y()],c.prototype,"sortDropdown",2),i([y()],c.prototype,"sortOrder",2),i([y()],c.prototype,"elementListItems",2),i([y()],c.prototype,"noContentMessage",2),i([y()],c.prototype,"activeCallbacks",2),i([y()],c.prototype,"expandedElementIds",2),c=i([pt("element-tab")],c);import{css as ht,html as xe,LitElement as mt}from"lit";import{customElement as ut,property as bt}from"lit/decorators.js";var P=class extends mt{constructor(){super(...arguments);this.activeTab="settings";this.tabs=["settings","elements","logs"]}_handleTabClick(e){this.dispatchEvent(new CustomEvent("tab-change",{detail:{tab:e},bubbles:!0,composed:!0}))}render(){return xe`
782
+ <div class="tab-selector-wrapper">
783
+ ${this.tabs.map(e=>xe`
784
+ <button
785
+ class="tab-button ${this.activeTab===e?"active":""}"
786
+ @click="${()=>this._handleTabClick(e)}"
787
+ data-tab="${e}"
788
+ >
789
+ ${e.charAt(0).toUpperCase()+e.slice(1)}
790
+ </button>
791
+ `)}
792
+ </div>
793
+ `}};P.styles=ht`
794
+ .tab-selector-wrapper {
795
+ border-bottom: 2px solid #444;
796
+ margin-top: 12px;
797
+ display: flex;
798
+ justify-content: space-evenly;
799
+ width: 100%;
800
+ }
801
+
802
+ .tab-button {
803
+ background: none;
804
+ border: none;
805
+ color: #9e9e9e;
806
+ flex: 1;
807
+ padding: 8px;
808
+ cursor: pointer;
809
+ border-bottom: 2px solid transparent;
810
+ transition: all 0.2s ease;
811
+ font-size: 13px;
812
+ font-weight: 500;
813
+ text-align: center;
814
+ }
815
+ .tab-button:hover {
816
+ color: #b0c4de;
817
+ background-color: rgba(176, 196, 222, 0.1);
818
+ }
819
+
820
+ .tab-button.active {
821
+ color: #b0c4de;
822
+ border-bottom-color: #b0c4de;
823
+ }
824
+ `,i([bt({type:String})],P.prototype,"activeTab",2),P=i([ut("tab-selector")],P);import{ForesightManager as X}from"js.foresight";import{LitElement as St,css as Tt,html as H}from"lit";import{customElement as Mt,property as _t,state as U}from"lit/decorators.js";import{map as Lt}from"lit/directives/map.js";function we(n){try{switch(n.type){case"elementRegistered":return{type:"elementRegistered",name:n.elementData.name,id:n.elementData.element.id||"",registerCount:n.elementData.registerCount,hitslop:n.elementData.elementBounds.hitSlop,localizedTimestamp:new Date(n.timestamp).toLocaleTimeString(),summary:n.elementData.registerCount===1?n.elementData.name:`${n.elementData.name} - ${ft(n.elementData.registerCount)} time`};case"elementUnregistered":return{type:"elementUnregistered",name:n.elementData.name,id:n.elementData.element.id||"",registerCount:n.elementData.registerCount,unregisterReason:n.unregisterReason,localizedTimestamp:new Date(n.timestamp).toLocaleTimeString(),summary:`${n.elementData.name} - ${n.unregisterReason}`};case"elementDataUpdated":return{type:"elementDataUpdated",name:n.elementData.name,updatedProps:n.updatedProps||[],isIntersecting:n.elementData.isIntersectingWithViewport,localizedTimestamp:new Date().toLocaleTimeString(),summary:`${n.elementData.name} - ${n.updatedProps.toString()}`};case"callbackInvoked":return{type:"callbackInvoked",name:n.elementData.name,hitType:n.hitType,localizedTimestamp:new Date(n.timestamp).toLocaleTimeString(),summary:`${n.elementData.name} - ${n.hitType.kind}`};case"callbackCompleted":let s=vt(n.elapsed);return{type:"callbackCompleted",...n.status==="error"?{status:"error",errorMessage:n.errorMessage}:{status:"success"},name:n.elementData.name,hitType:n.hitType,callbackRunTimeFormatted:s,callbackRunTimeRaw:n.elapsed,localizedTimestamp:new Date(n.timestamp).toLocaleTimeString(),summary:`${n.elementData.name} - ${s}`};case"mouseTrajectoryUpdate":return{type:"mouseTrajectoryUpdate",currentPoint:n.trajectoryPositions?.currentPoint,predictedPoint:n.trajectoryPositions?.predictedPoint,positionCount:n.trajectoryPositions?.positions?.length||0,mousePredictionEnabled:n.predictionEnabled,localizedTimestamp:new Date().toLocaleTimeString(),summary:""};case"scrollTrajectoryUpdate":return{type:"scrollTrajectoryUpdate",currentPoint:n.currentPoint,predictedPoint:n.predictedPoint,scrollDirection:n.scrollDirection,localizedTimestamp:new Date().toLocaleTimeString(),summary:n.scrollDirection};case"managerSettingsChanged":return{type:"managerSettingsChanged",globalSettings:n.managerData?.globalSettings||{},settingsChanged:n.updatedSettings,localizedTimestamp:new Date(n.timestamp).toLocaleTimeString(),summary:n.updatedSettings.map(t=>t.setting).join(", ")};default:return{type:"serializationError",error:"Failed to serialize event data",errorMessage:JSON.stringify(n),localizedTimestamp:new Date().toLocaleTimeString(),summary:""}}}catch(s){return{type:"serializationError",error:"Failed to serialize event data",localizedTimestamp:new Date().toLocaleTimeString(),errorMessage:s instanceof Error?s.message:String(s),summary:""}}}function vt(n){return`${(n/1e3).toFixed(4)} s`}function ft(n){let s=["th","st","nd","rd"],e=n%100;return n+(s[(e-20)%10]||s[e]||s[0])}import{html as ke,css as yt}from"lit";import{customElement as xt,property as Ee}from"lit/decorators.js";var _=class extends M{constructor(){super(...arguments);this.selectedValues=[]}_handleOptionClick(e){let t=this.selectedValues.includes(e.value);t?this.selectedValues=this.selectedValues.filter(a=>a!==e.value):this.selectedValues=[...this.selectedValues,e.value];let o=!t;this.onSelectionChange?.(e.value,o)}_getTriggerIcon(){return m}_isOptionSelected(e){return this.selectedValues.includes(e.value)}_getTriggerTitle(){let e=this.selectedValues.length;return e===0?"No items selected":e===1?"1 item selected":`${e} items selected`}_getTriggerLabel(){return`Filter options: ${this.selectedValues.length} selected`}render(){let e=`trigger-button ${this.isDropdownOpen?"active":""}`,t=`dropdown-menu ${this.isDropdownOpen?"active":""}`;return ke`
825
+ <div class="dropdown-container">
826
+ <button
827
+ class="${e}"
828
+ title="${this._getTriggerTitle()}"
829
+ @click="${this._toggleDropdown}"
830
+ aria-haspopup="true"
831
+ aria-expanded="${this.isDropdownOpen}"
832
+ aria-controls="dropdown-menu"
833
+ aria-label="${this._getTriggerLabel()}"
834
+ >
835
+ ${this._getTriggerIcon()}
836
+ <span class="selected-count">${this.selectedValues.length}</span>
837
+ <svg
838
+ class="arrow-icon"
839
+ xmlns="http://www.w3.org/2000/svg"
840
+ viewBox="0 0 24 24"
841
+ stroke="currentColor"
842
+ stroke-width="2"
843
+ stroke-linecap="round"
844
+ stroke-linejoin="round"
845
+ >
846
+ <polyline points="6 9 12 15 18 9"></polyline>
847
+ </svg>
848
+ </button>
849
+
850
+ <div class="${t}" id="dropdown-menu" role="menu">
851
+ ${this.dropdownOptions.map(o=>ke`
852
+ <button
853
+ value="${o.value}"
854
+ title="${o.title}"
855
+ class="${this._isOptionSelected(o)?"active":""}"
856
+ @click="${()=>this._handleOptionClick(o)}"
857
+ role="menuitem"
858
+ >
859
+ ${o.label}
860
+ </button>
861
+ `)}
862
+ </div>
863
+ </div>
864
+ `}};_.styles=[...M.styles,yt`
865
+ .dropdown-menu button.active::after {
866
+ content: "✓";
867
+ position: absolute;
868
+ right: 8px;
869
+ top: 50%;
870
+ transform: translateY(-50%);
871
+ color: #b0c4de;
872
+ font-weight: bold;
873
+ }
874
+
875
+ .selected-count {
876
+ font-size: 10px;
877
+ color: #b0c4de;
878
+ margin-left: 2px;
879
+ }
880
+ `],i([Ee({type:Array})],_.prototype,"selectedValues",2),i([Ee()],_.prototype,"onSelectionChange",2),_=i([xt("multi-select-dropdown")],_);import{LitElement as wt,html as kt,css as Et}from"lit";import{customElement as Ct,property as J}from"lit/decorators.js";var E=class extends wt{constructor(e){super();this.isExpanded=!1;this.log=e}serializeLogDataWithoutSummary(e){let{summary:t,...o}=e;return JSON.stringify(o,null,2)}getLogTypeColor(e){return{elementRegistered:"#2196f3",callbackInvoked:"#00bcd4",callbackCompleted:"#4caf50",elementDataUpdated:"#ffc107",elementUnregistered:"#ff9800",managerSettingsChanged:"#f44336",mouseTrajectoryUpdate:"#78909c",scrollTrajectoryUpdate:"#607d8b"}[e]||"#555"}getEventDisplayName(e){return{elementRegistered:"Registered",elementUnregistered:"Unregistered",elementDataUpdated:"Data Updated",callbackInvoked:"Invoked",callbackCompleted:"Completed",mouseTrajectoryUpdate:"Mouse",scrollTrajectoryUpdate:"Scroll",managerSettingsChanged:"Settings"}[e]||e}truncateLogSummary(e,t=50){return e.length<=t?e:e.substring(0,t)+"..."}render(){let e=this.log,t=`log-${e.type}`;e.type==="callbackCompleted"&&"status"in e&&e.status==="error"&&(t+=" error-status"),this.className=t;let o=e.type==="callbackCompleted"&&"status"in e&&e.status==="error"?"#f44336":this.getLogTypeColor(e.type);return kt`
881
+ <expandable-item
882
+ .borderColor=${o}
883
+ .itemId=${e.logId}
884
+ .isExpanded=${this.isExpanded}
885
+ .onToggle=${this.onToggle}
886
+ >
887
+ <div slot="content">
888
+ <div class="log-content">
889
+ <span class="log-time">${e.localizedTimestamp}</span>
890
+ <span class="log-type-badge">${this.getEventDisplayName(e.type)}</span>
891
+ <span class="log-summary">${this.truncateLogSummary(e.summary)}</span>
892
+ </div>
893
+ </div>
894
+ <div slot="details">${this.serializeLogDataWithoutSummary(e)}</div>
895
+ </expandable-item>
896
+ `}};E.styles=[Et`
897
+ :host {
898
+ display: block;
899
+ }
900
+
901
+ .log-time {
902
+ color: #b8b8b8;
903
+ font-weight: 500;
904
+ font-size: 10px;
905
+ font-family: "SF Mono", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;
906
+ min-width: 70px;
907
+ max-width: 70px;
908
+ text-align: left;
909
+ letter-spacing: 0.02em;
910
+ flex-shrink: 0;
911
+ }
912
+
913
+ .log-type-badge {
914
+ display: inline-flex;
915
+ align-items: center;
916
+ font-size: 10px;
917
+ font-weight: 600;
918
+ text-transform: uppercase;
919
+ letter-spacing: 0.02em;
920
+ color: var(--log-color, #b0c4de);
921
+ min-width: 90px;
922
+ max-width: 90px;
923
+ white-space: nowrap;
924
+ text-align: left;
925
+ margin-left: 10px;
926
+ flex-shrink: 0;
927
+ }
928
+
929
+ .log-summary {
930
+ flex: 1;
931
+ color: #ccc;
932
+ font-size: 11px;
933
+ opacity: 0.9;
934
+ white-space: nowrap;
935
+ overflow: hidden;
936
+ text-overflow: ellipsis;
937
+ margin-left: 6px;
938
+ font-weight: 400;
939
+ min-width: 0;
940
+ }
941
+
942
+ .log-content {
943
+ display: flex;
944
+ align-items: center;
945
+ width: 100%;
946
+ min-width: 0;
947
+ }
948
+
949
+ :host(.log-elementRegistered) {
950
+ --log-color: #2196f3;
951
+ }
952
+ :host(.log-callbackInvoked) {
953
+ --log-color: #00bcd4;
954
+ }
955
+ :host(.log-callbackCompleted) {
956
+ --log-color: #4caf50;
957
+ }
958
+ :host(.log-elementDataUpdated) {
959
+ --log-color: #ffc107;
960
+ }
961
+ :host(.log-elementUnregistered) {
962
+ --log-color: #ff9800;
963
+ }
964
+ :host(.log-managerSettingsChanged) {
965
+ --log-color: #f44336;
966
+ }
967
+ :host(.log-mouseTrajectoryUpdate) {
968
+ --log-color: #78909c;
969
+ }
970
+ :host(.log-scrollTrajectoryUpdate) {
971
+ --log-color: #607d8b;
972
+ }
973
+
974
+ :host(.log-callbackCompleted.error-status) {
975
+ --log-color: #f44336;
976
+ background-color: rgba(244, 67, 54, 0.1);
977
+ }
978
+ `],i([J()],E.prototype,"log",2),i([J()],E.prototype,"isExpanded",2),i([J()],E.prototype,"onToggle",2),E=i([Ct("single-log")],E);var h=class extends St{constructor(){super();this.logs=[];this.expandedLogIds=new Set;this.MAX_LOGS=100;this.logIdCounter=0;this.noContentMessage="No logs available";this._abortController=null;this._eventListeners=new Map;this.handleLogLocationChange=e=>{this.logLocation=e};this.handleFilterChange=(e,t)=>{this.eventsEnabled={...this.eventsEnabled,[e]:t},t?this.addForesightEventListener(e):this.removeForesightEventListener(e)};this.handleLogToggle=e=>{let t=new Set(this.expandedLogIds);t.has(e)?t.delete(e):t.add(e),this.expandedLogIds=t};let{logging:{logLocation:e,...t}}=l.instance.devtoolsSettings;this.eventsEnabled=t,this.logLocation=e,this.logDropdown=[{value:"controlPanel",label:"Control Panel",title:"Log only to the control panel",icon:se},{value:"console",label:"Console",title:"Log only to the console",icon:ae},{value:"both",label:"Both",title:"Log to both the control panel and the console",icon:le},{value:"none",label:"None",title:"Dont log anywhere",icon:re}],this.filterDropdown=[{value:"elementRegistered",label:"Element Registered",title:"Show element registration events",icon:m},{value:"elementUnregistered",label:"Element Unregistered",title:"Show element unregistration events",icon:m},{value:"elementDataUpdated",label:"Element Data Updated",title:"Show element data update events",icon:m},{value:"callbackInvoked",label:"Callback Invoked",title:"Show callback invoked events",icon:m},{value:"callbackCompleted",label:"Callback Completed",title:"Show callback completed events",icon:m},{value:"mouseTrajectoryUpdate",label:"Mouse Trajectory Update",title:"Show mouse trajectory update events",icon:m},{value:"scrollTrajectoryUpdate",label:"Scroll Trajectory Update",title:"Show scroll trajectory update events",icon:m},{value:"managerSettingsChanged",label:"Manager Settings Changed",title:"Show manager settings change events",icon:m}]}getSelectedEventFilters(){return Object.entries(this.eventsEnabled).filter(([e,t])=>t).map(([e,t])=>e)}shouldShowPerformanceWarning(){let e=this.logLocation==="console"||this.logLocation==="both",t=this.eventsEnabled.mouseTrajectoryUpdate||this.eventsEnabled.scrollTrajectoryUpdate||this.eventsEnabled.elementDataUpdated;return e&&t}getNoLogsMessage(){return Object.values(this.eventsEnabled).filter(Boolean).length===0?"Logging for all events is turned off":this.logLocation==="console"?"No logs to display. Logging location is set to console - check browser console for events.":this.logLocation==="none"?"No logs to display. Logging location is set to none":"Interact with Foresight to generate events."}clearLogs(){this.logs=[],this.expandedLogIds.clear(),this.noContentMessage="Logs cleared"}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController,this.setupDynamicEventListeners()}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this.removeAllEventListeners()}setupDynamicEventListeners(){Object.entries(this.eventsEnabled).forEach(([e,t])=>{t&&this.addForesightEventListener(e)})}addForesightEventListener(e){if(this._eventListeners.has(e))return;let t=o=>{this.handleEvent(e,o)};this._eventListeners.set(e,t),X.instance.addEventListener(e,t,{signal:this._abortController?.signal})}removeForesightEventListener(e){let t=this._eventListeners.get(e);t&&(X.instance.removeEventListener(e,t),this._eventListeners.delete(e))}removeAllEventListeners(){this._eventListeners.forEach((e,t)=>{X.instance.removeEventListener(t,e)}),this._eventListeners.clear()}getEventColor(e){return{elementRegistered:"#2196f3",callbackInvoked:"#00bcd4",callbackCompleted:"#4caf50",elementDataUpdated:"#ffc107",elementUnregistered:"#ff9800",managerSettingsChanged:"#f44336",mouseTrajectoryUpdate:"#78909c",scrollTrajectoryUpdate:"#607d8b"}[e]||"#ffffff"}handleEvent(e,t){if(this.logLocation!=="none"){if(this.logLocation==="console"||this.logLocation==="both"){let o=this.getEventColor(e);console.log(`%c[ForesightJS] ${e}`,`color: ${o}; font-weight: bold;`,t)}(this.logLocation==="controlPanel"||this.logLocation==="both")&&this.addEventLog(t)}}addEventLog(e){let t=we(e);if(t.type==="serializationError"){console.error(t.error,t.errorMessage);return}let o={...t,logId:(++this.logIdCounter).toString()};this.logs.unshift(o),this.logs.length>this.MAX_LOGS&&this.logs.pop(),this.requestUpdate()}render(){return H`
979
+ <tab-header>
980
+ <div slot="chips" class="chips-container">
981
+ <chip-element title="Number of logged events (Max ${this.MAX_LOGS})">
982
+ ${this.logs.length} events
983
+ </chip-element>
984
+ </div>
985
+ <div slot="actions">
986
+ ${this.shouldShowPerformanceWarning()?H`
987
+ <div
988
+ class="warning-container"
989
+ title="Console logging can be slow with frequent trajectory events.
990
+ Consider using 'Control Panel' only for better performance."
991
+ >
992
+ ${ue}
993
+ </div>
994
+ `:""}
995
+ <single-select-dropdown
996
+ .dropdownOptions="${this.logDropdown}"
997
+ .selectedOptionValue="${this.logLocation}"
998
+ .onSelectionChange="${this.handleLogLocationChange}"
999
+ ></single-select-dropdown>
1000
+
1001
+ <multi-select-dropdown
1002
+ .dropdownOptions="${this.filterDropdown}"
1003
+ .selectedValues="${this.getSelectedEventFilters()}"
1004
+ .onSelectionChange="${this.handleFilterChange}"
1005
+ ></multi-select-dropdown>
1006
+ <button
1007
+ class="clear-button"
1008
+ title="Clear all logs"
1009
+ ?disabled="${this.logs.length===0}"
1010
+ @click="${this.clearLogs}"
1011
+ >
1012
+ ${ge}
1013
+ </button>
1014
+ </div>
1015
+ </tab-header>
1016
+ <tab-content .noContentMessage=${this.noContentMessage} .hasContent=${!!this.logs.length}>
1017
+ ${this.logs.length===0?H`<div class="no-items">${this.getNoLogsMessage()}</div>`:Lt(this.logs,e=>H`
1018
+ <single-log
1019
+ .log=${e}
1020
+ .isExpanded=${this.expandedLogIds.has(e.logId)}
1021
+ .onToggle=${this.handleLogToggle}
1022
+ ></single-log>
1023
+ `)}
1024
+ </tab-content>
1025
+ `}};h.styles=[Tt`
1026
+ :host {
1027
+ display: flex;
1028
+ flex-direction: column;
1029
+ height: 100%;
1030
+ }
1031
+
1032
+ .chips-container {
1033
+ display: flex;
1034
+ gap: 4px;
1035
+ }
1036
+
1037
+ .clear-button {
1038
+ background: none;
1039
+ border: none;
1040
+ color: white;
1041
+ cursor: pointer;
1042
+ padding: 6px;
1043
+ display: inline-flex;
1044
+ align-items: center;
1045
+ justify-content: center;
1046
+ transition: all 0.2s ease;
1047
+ vertical-align: top;
1048
+ }
1049
+
1050
+ .clear-button svg {
1051
+ width: 16px;
1052
+ height: 16px;
1053
+ stroke: white;
1054
+ transition: stroke 0.2s;
1055
+ }
1056
+
1057
+ .clear-button:hover {
1058
+ background-color: rgba(176, 196, 222, 0.1);
1059
+ }
1060
+
1061
+ .clear-button:hover svg {
1062
+ stroke: #b0c4de;
1063
+ }
1064
+
1065
+ .clear-button:disabled {
1066
+ opacity: 0.4;
1067
+ cursor: not-allowed;
1068
+ }
1069
+
1070
+ .clear-button:disabled:hover {
1071
+ background: none;
1072
+ }
1073
+
1074
+ .clear-button:disabled svg {
1075
+ stroke: #666;
1076
+ }
1077
+
1078
+ .no-items {
1079
+ display: flex;
1080
+ align-items: center;
1081
+ justify-content: center;
1082
+ height: 200px;
1083
+ text-align: center;
1084
+ font-family: "Courier New", monospace;
1085
+ font-style: italic;
1086
+ padding: 20px;
1087
+ color: #999;
1088
+ }
1089
+
1090
+ .warning-container {
1091
+ background: none;
1092
+ border: none;
1093
+ color: #ffc107;
1094
+ cursor: help;
1095
+ padding: 6px;
1096
+ display: inline-flex;
1097
+ align-items: center;
1098
+ justify-content: center;
1099
+ transition: all 0.2s ease;
1100
+ vertical-align: top;
1101
+ }
1102
+
1103
+ .warning-container svg {
1104
+ width: 16px;
1105
+ height: 16px;
1106
+ stroke: #ffc107;
1107
+ fill: none;
1108
+ transition: stroke 0.2s;
1109
+ }
1110
+
1111
+ .warning-container:hover {
1112
+ background-color: rgba(255, 193, 7, 0.1);
1113
+ }
1114
+
1115
+ .warning-container:hover svg {
1116
+ stroke: #ffdc3e;
1117
+ }
1118
+ `],i([U()],h.prototype,"logDropdown",2),i([U()],h.prototype,"filterDropdown",2),i([U()],h.prototype,"logLocation",2),i([U()],h.prototype,"eventsEnabled",2),i([U()],h.prototype,"logs",2),i([U()],h.prototype,"expandedLogIds",2),i([_t()],h.prototype,"noContentMessage",2),h=i([Mt("log-tab")],h);import{ForesightManager as _e}from"js.foresight";import{css as Qt,html as Le,LitElement as ei}from"lit";import{customElement as ti,state as G}from"lit/decorators.js";var Z="points",Ce="px",Se="tabs",Te="ms";import{LitElement as Pt,html as Ut,css as Nt}from"lit";import{customElement as jt,property as B}from"lit/decorators.js";import{LitElement as Dt,html as Ot,css as $t}from"lit";import{customElement as It,property as Me}from"lit/decorators.js";var L=class extends Dt{constructor(){super(...arguments);this.header="";this.description=""}render(){return Ot`<div class="setting-item">
1119
+ <label>
1120
+ <span class="setting-header">${this.header}</span>
1121
+ <span class="setting-description"> ${this.description} </span>
1122
+ </label>
1123
+ <div class="setting-controls">
1124
+ <slot name="controls"></slot>
1125
+ </div>
1126
+ </div>`}};L.styles=[$t`
1127
+ .setting-item {
1128
+ display: flex;
1129
+ align-items: center;
1130
+ gap: 12px;
1131
+ padding: 10px 0;
1132
+ border-bottom: 1px solid rgba(80, 80, 80, 0.2);
1133
+ }
1134
+
1135
+ .setting-item:last-child {
1136
+ border-bottom: none;
1137
+ }
1138
+ .setting-controls {
1139
+ display: flex;
1140
+ align-items: center;
1141
+ gap: 8px;
1142
+ flex-shrink: 0;
1143
+ }
1144
+ .setting-description {
1145
+ font-size: 11px;
1146
+ color: #9e9e9e;
1147
+ line-height: 1.3;
1148
+ font-weight: normal;
1149
+ }
1150
+ .setting-item label {
1151
+ flex: 1;
1152
+ display: flex;
1153
+ flex-direction: column;
1154
+ gap: 4px;
1155
+ font-weight: 500;
1156
+ color: #fff;
1157
+ font-size: 13px;
1158
+ cursor: pointer;
1159
+ min-width: 180px;
1160
+ }
1161
+ .setting-header {
1162
+ font-weight: 500;
1163
+ color: #fff;
1164
+ font-size: 13px;
1165
+ }
1166
+ `],i([Me({type:String})],L.prototype,"header",2),i([Me({type:String})],L.prototype,"description",2),L=i([It("setting-item")],L);import{ForesightManager as Ft}from"js.foresight";var x=class extends Pt{constructor(){super(...arguments);this.isChecked=!1;this.header="";this.description="";this.setting="enableMousePrediction"}handleCheckboxChange(e){let t=e.target;if(t instanceof HTMLInputElement){let o=t.checked;this.setting==="showNameTags"?this.dispatchEvent(new CustomEvent("setting-changed",{detail:{setting:this.setting,value:o},bubbles:!0})):Ft.instance.alterGlobalSettings({[this.setting]:o})}}render(){return Ut`<setting-item header=${this.header} description=${this.description}>
1167
+ <input
1168
+ slot="controls"
1169
+ type="checkbox"
1170
+ .checked=${this.isChecked}
1171
+ @change=${this.handleCheckboxChange}
1172
+ />
1173
+ </setting-item>`}};x.styles=[Nt`
1174
+ input[type="checkbox"] {
1175
+ appearance: none;
1176
+ -webkit-appearance: none;
1177
+ -moz-appearance: none;
1178
+ position: relative;
1179
+ width: 44px;
1180
+ height: 22px;
1181
+ background-color: #444;
1182
+ cursor: pointer;
1183
+ outline: none;
1184
+ transition: all 0.3s ease;
1185
+ vertical-align: middle;
1186
+ flex-shrink: 0;
1187
+ margin: 0;
1188
+ border: 2px solid #555;
1189
+ }
1190
+
1191
+ input[type="checkbox"]::before {
1192
+ content: "";
1193
+ position: absolute;
1194
+ width: 16px;
1195
+ height: 16px;
1196
+ background-color: white;
1197
+ top: 1px;
1198
+ left: 1px;
1199
+ transition: all 0.3s ease;
1200
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
1201
+ }
1202
+
1203
+ input[type="checkbox"]:checked {
1204
+ background-color: #b0c4de;
1205
+ border-color: #b0c4de;
1206
+ }
1207
+
1208
+ input[type="checkbox"]:checked::before {
1209
+ transform: translateX(22px);
1210
+ background-color: white;
1211
+ }
1212
+
1213
+ input[type="checkbox"]:hover {
1214
+ box-shadow: 0 0 0 3px rgba(176, 196, 222, 0.1);
1215
+ }
1216
+ `],i([B({type:Boolean})],x.prototype,"isChecked",2),i([B({type:String})],x.prototype,"header",2),i([B({type:String})],x.prototype,"description",2),i([B({type:String})],x.prototype,"setting",2),x=i([jt("setting-item-checkbox")],x);import{LitElement as Vt,html as zt,css as Rt}from"lit";import{customElement as At,property as D,state as Ht}from"lit/decorators.js";import{ForesightManager as Bt}from"js.foresight";var p=class extends Vt{constructor(){super(...arguments);this.minValue=0;this.maxValue=100;this.currentValue=50;this.unit="px";this.header="";this.description="";this.setting="tabOffset";this.displayValue=50}handleRangeInput(e){let t=e.target;t instanceof HTMLInputElement&&(this.displayValue=parseInt(t.value,10))}handleRangeChange(e){let t=e.target;if(t instanceof HTMLInputElement){let o=parseInt(t.value,10);this.displayValue=o,Bt.instance.alterGlobalSettings({[this.setting]:o})}}willUpdate(e){super.willUpdate(e),e.has("currentValue")&&(this.displayValue=this.currentValue)}render(){return zt`<setting-item header=${this.header} description=${this.description}>
1217
+ <div slot="controls" class="range-wrapper">
1218
+ <input
1219
+ slot="controls"
1220
+ type="range"
1221
+ min="${this.minValue}"
1222
+ max="${this.maxValue}"
1223
+ step="1"
1224
+ .value=${this.displayValue}
1225
+ @input=${this.handleRangeInput}
1226
+ @change=${this.handleRangeChange}
1227
+ />
1228
+ <span class="setting-range-value">${this.displayValue} ${this.unit}</span>
1229
+ </div>
1230
+ </setting-item>`}};p.styles=[Rt`
1231
+ .setting-range-value {
1232
+ font-size: 12px;
1233
+ color: #b0c4de;
1234
+ font-weight: 500;
1235
+ min-width: 45px;
1236
+ text-align: right;
1237
+ }
1238
+
1239
+ .range-wrapper {
1240
+ display: flex;
1241
+ align-items: center;
1242
+ gap: 8px;
1243
+ width: 100%;
1244
+ }
1245
+
1246
+ input[type="range"] {
1247
+ margin: 0;
1248
+ cursor: pointer;
1249
+ -webkit-appearance: none;
1250
+ appearance: none;
1251
+ background: transparent;
1252
+ height: 22px;
1253
+ vertical-align: middle;
1254
+ width: 100px;
1255
+ }
1256
+
1257
+ input[type="range"]::-webkit-slider-runnable-track {
1258
+ height: 6px;
1259
+ background: #444;
1260
+ border: 1px solid #555;
1261
+ }
1262
+
1263
+ input[type="range"]::-moz-range-track {
1264
+ height: 6px;
1265
+ background: #444;
1266
+ border: 1px solid #555;
1267
+ }
1268
+
1269
+ input[type="range"]::-webkit-slider-thumb {
1270
+ -webkit-appearance: none;
1271
+ appearance: none;
1272
+ margin-top: -7px;
1273
+ background: #b0c4de;
1274
+ height: 20px;
1275
+ width: 20px;
1276
+ border: 2px solid #333;
1277
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
1278
+ transition: all 0.2s ease;
1279
+ }
1280
+
1281
+ input[type="range"]::-moz-range-thumb {
1282
+ background: #b0c4de;
1283
+ height: 20px;
1284
+ width: 20px;
1285
+ border: 2px solid #333;
1286
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
1287
+ transition: all 0.2s ease;
1288
+ }
1289
+
1290
+ input[type="range"]:hover::-webkit-slider-thumb {
1291
+ transform: scale(1.1);
1292
+ box-shadow: 0 0 0 4px rgba(176, 196, 222, 0.2);
1293
+ }
1294
+
1295
+ input[type="range"]:hover::-moz-range-thumb {
1296
+ transform: scale(1.1);
1297
+ box-shadow: 0 0 0 4px rgba(176, 196, 222, 0.2);
1298
+ }
1299
+ `],i([D({type:Number})],p.prototype,"minValue",2),i([D({type:Number})],p.prototype,"maxValue",2),i([D({type:Number})],p.prototype,"currentValue",2),i([D({type:String})],p.prototype,"unit",2),i([D({type:String})],p.prototype,"header",2),i([D({type:String})],p.prototype,"description",2),i([D({type:String})],p.prototype,"setting",2),i([Ht()],p.prototype,"displayValue",2),p=i([At("setting-item-range")],p);var w=class extends ei{constructor(){super();this.changedSettings=[];this._abortController=null;let e=l.instance.devtoolsSettings,t=_e.instance.getManagerData.globalSettings;this.devtoolsSettings=Object.assign({},e),this.managerSettings=Object.assign({},t),this.initialSettings={devtools:Object.assign({},e),manager:Object.assign({},t)}}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;_e.instance.addEventListener("managerSettingsChanged",t=>{this.managerSettings=t.managerData.globalSettings,this._updateChangedSettings()},{signal:e}),this._updateChangedSettings()}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}_updateChangedSettings(){let e=[];this._checkManagerSettingsChanges(e),this._checkDevtoolsSettingsChanges(e),this.changedSettings=e}_checkManagerSettingsChanges(e){let t=["enableMousePrediction","enableTabPrediction","enableScrollPrediction","trajectoryPredictionTime","positionHistorySize","tabOffset","scrollMargin"];for(let o of t){let a=this.initialSettings.manager[o],r=this.managerSettings[o];a!==r&&e.push({name:o,initial:a,current:r})}}_checkDevtoolsSettingsChanges(e){let t=["showNameTags"];for(let o of t){let a=this.initialSettings.devtools[o],r=this.devtoolsSettings[o];a!==r&&e.push({name:o,initial:a,current:r})}}_handleDevtoolsSettingChange(e){let{setting:t,value:o}=e.detail;t==="showNameTags"&&(this.devtoolsSettings={...this.devtoolsSettings,showNameTags:o},l.instance.alterDevtoolsSettings({showNameTags:o}),this._updateChangedSettings())}async handleCopySettings(){if(this.managerSettings)try{let e=this.generateSettingsCode(this.managerSettings);navigator.clipboard&&navigator.clipboard.writeText&&await navigator.clipboard.writeText(e)}catch(e){console.error("Failed to copy settings code:",e)}}generateSettingsCode(e){let t={enableMousePrediction:e.enableMousePrediction,enableTabPrediction:e.enableTabPrediction,enableScrollPrediction:e.enableScrollPrediction,positionHistorySize:e.positionHistorySize,trajectoryPredictionTime:e.trajectoryPredictionTime,tabOffset:e.tabOffset,scrollMargin:e.scrollMargin};return`ForesightManager.initialize(${JSON.stringify(t,null,2)})`}render(){if(!this.managerSettings||!this.devtoolsSettings)return Le`<tab-content
1300
+ .noContentMessage=${"Loading settings..."}
1301
+ .hasContent=${!1}
1302
+ ></tab-content>`;let e=this.managerSettings,t=this.changedSettings.length>0?`Settings that have been changed this session compared to your initialized settings.
1303
+ Click on the copy icon to easely copy the new setting into your project
1304
+
1305
+ `+this.changedSettings.map(o=>`${o.name}: ${JSON.stringify(o.initial)} -> ${JSON.stringify(o.current)}`).join(`
1306
+ `):"No settings changed from initial values";return Le`
1307
+ <tab-header>
1308
+ <div slot="chips" class="chips-container">
1309
+ <chip-element .title=${t}> ${this.changedSettings.length} changed </chip-element>
1310
+ </div>
1311
+ <div slot="actions">
1312
+ <copy-icon
1313
+ title="Copy current settings as code"
1314
+ .onCopy=${()=>this.handleCopySettings()}
1315
+ ></copy-icon>
1316
+ </div>
1317
+ </tab-header>
1318
+
1319
+ <tab-content .hasContent=${!0}>
1320
+ <div class="settings-content">
1321
+ <div class="settings-section">
1322
+ <div class="settings-group">
1323
+ <h4>Mouse Prediction</h4>
1324
+ <setting-item-checkbox
1325
+ .isChecked=${e.enableMousePrediction}
1326
+ header="Enable Mouse Prediction"
1327
+ description="Execute callbacks when mouse is ${e.trajectoryPredictionTime}ms away from registered elements in mouse direction"
1328
+ setting="enableMousePrediction"
1329
+ ></setting-item-checkbox>
1330
+ <setting-item-range
1331
+ .currentValue=${e.trajectoryPredictionTime}
1332
+ .maxValue=${200}
1333
+ .minValue=${10}
1334
+ .unit=${Te}
1335
+ header="Prediction Time"
1336
+ description="How far into the future to calculate mouse trajectory path"
1337
+ setting="trajectoryPredictionTime"
1338
+ ></setting-item-range>
1339
+ <setting-item-range
1340
+ .currentValue=${e.positionHistorySize}
1341
+ .maxValue=${30}
1342
+ .minValue=${2}
1343
+ .unit=${Z}
1344
+ header="Position History Size"
1345
+ description="How far into the future, in ${Z}, to calculate mouse trajectory path"
1346
+ setting="positionHistorySize"
1347
+ >
1348
+ </setting-item-range>
1349
+ </div>
1350
+ <div class="settings-group">
1351
+ <h4>Keyboard Navigation</h4>
1352
+ <setting-item-checkbox
1353
+ .isChecked=${e.enableTabPrediction}
1354
+ header="Enable Tab Prediction"
1355
+ description="Execute callbacks when user ${e.tabOffset} tabbable elements away from registered elements in tab direction"
1356
+ setting="enableTabPrediction"
1357
+ >
1358
+ </setting-item-checkbox>
1359
+ <setting-item-range
1360
+ .currentValue=${e.tabOffset}
1361
+ .maxValue=${20}
1362
+ .minValue=${0}
1363
+ .unit=${Se}
1364
+ header="Tab Offset"
1365
+ description="Number of tabbable elements to look ahead when predicting navigation"
1366
+ setting="tabOffset"
1367
+ >
1368
+ </setting-item-range>
1369
+ </div>
1370
+
1371
+ <div class="settings-group">
1372
+ <h4>Scroll Prediction</h4>
1373
+ <setting-item-checkbox
1374
+ .isChecked=${e.enableScrollPrediction}
1375
+ header="Enable Scroll Prediction"
1376
+ description="Execute callbacks when user is ${e.scrollMargin}px away from registered elements in scroll direction"
1377
+ setting="enableScrollPrediction"
1378
+ ></setting-item-checkbox>
1379
+ <setting-item-range
1380
+ .currentValue=${e.scrollMargin}
1381
+ .maxValue=${300}
1382
+ .minValue=${30}
1383
+ .unit=${Ce}
1384
+ header="Scroll Margin"
1385
+ description="Pixel distance to check from mouse position in scroll direction"
1386
+ setting="scrollMargin"
1387
+ ></setting-item-range>
1388
+ </div>
1389
+
1390
+ <!-- Developer Tools Group -->
1391
+ <div class="settings-group">
1392
+ <h4>Developer Tools</h4>
1393
+ <setting-item-checkbox
1394
+ .isChecked=${this.devtoolsSettings.showNameTags}
1395
+ header="Show Name Tags"
1396
+ description="Display name tags over each registered element in the debugger"
1397
+ setting="showNameTags"
1398
+ @setting-changed=${this._handleDevtoolsSettingChange}
1399
+ ></setting-item-checkbox>
1400
+ </div>
1401
+ </div>
1402
+ </div>
1403
+ </tab-content>
1404
+ `}};w.styles=Qt`
1405
+ :host {
1406
+ display: flex;
1407
+ flex-direction: column;
1408
+ height: 100%;
1409
+ }
1410
+
1411
+ .settings-content {
1412
+ display: block;
1413
+ }
1414
+
1415
+ .settings-section {
1416
+ display: flex;
1417
+ flex-direction: column;
1418
+ gap: 16px;
1419
+ }
1420
+
1421
+ .settings-group {
1422
+ background: rgba(30, 30, 30, 0.6);
1423
+ padding: 16px;
1424
+ border: 1px solid rgba(176, 196, 222, 0.1);
1425
+ }
1426
+
1427
+ .settings-group h4 {
1428
+ margin: 0 0 12px 0;
1429
+ font-size: 14px;
1430
+ font-weight: 600;
1431
+ color: #b0c4de;
1432
+ border-bottom: 1px solid rgba(176, 196, 222, 0.2);
1433
+ padding-bottom: 8px;
1434
+ }
1435
+ `,i([G()],w.prototype,"managerSettings",2),i([G()],w.prototype,"initialSettings",2),i([G()],w.prototype,"devtoolsSettings",2),i([G()],w.prototype,"changedSettings",2),w=i([ti("settings-tab")],w);var b=class extends ii{constructor(){super();this.isMinimized=!1;this.visibleCount=0;this.totalCount=0;this.localStorageSelectedTabKey="foresight-devtools-control-panel-tab";this._handleVisibilityCountChange=e=>{let t=e;this.visibleCount=t.detail.visibleCount,this.totalCount=t.detail.totalCount};let e=localStorage.getItem(this.localStorageSelectedTabKey);this.activeTab=e||"logs"}_handleTabChange(e){this.activeTab=e.detail.tab,localStorage.setItem(this.localStorageSelectedTabKey,this.activeTab)}connectedCallback(){super.connectedCallback(),this.addEventListener("visibility-count-updated",this._handleVisibilityCountChange)}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("visibility-count-updated",this._handleVisibilityCountChange)}render(){return ni`
1436
+ <div class="control-wrapper ${this.isMinimized?"minimized":""}">
1437
+ <div class="title-wrapper">
1438
+ <button @click="${()=>this.isMinimized=!this.isMinimized}" class="minimize-button">
1439
+ -
1440
+ </button>
1441
+ <h1>Foresight DevTools</h1>
1442
+ <span
1443
+ title="Number of visible registered elements / total registered elements"
1444
+ class="title-element-count"
1445
+ >${this.visibleCount}/${this.totalCount}</span
1446
+ >
1447
+ </div>
1448
+
1449
+ <div class="tab-container ${this.isMinimized?"hidden":""}">
1450
+ <tab-selector
1451
+ .activeTab="${this.activeTab}"
1452
+ @tab-change="${this._handleTabChange}"
1453
+ ></tab-selector>
1454
+
1455
+ <div class="tab-content">
1456
+ <log-tab class=${Q({active:this.activeTab==="logs"})}></log-tab>
1457
+ <element-tab class=${Q({active:this.activeTab==="elements"})}></element-tab>
1458
+ <settings-tab
1459
+ class=${Q({active:this.activeTab==="settings"})}
1460
+ ></settings-tab>
1461
+ </div>
1462
+ </div>
1463
+ </div>
1464
+ `}};b.styles=oi`
1465
+ .control-wrapper {
1466
+ padding: 12px;
1467
+ position: fixed;
1468
+ bottom: 10px;
1469
+ right: 10px;
1470
+ background-color: rgba(0, 0, 0, 0.9);
1471
+ color: white;
1472
+ font-family: Arial, sans-serif;
1473
+ font-size: 13px;
1474
+ z-index: 10001;
1475
+ pointer-events: auto;
1476
+ display: flex;
1477
+ flex-direction: column;
1478
+ width: 450px;
1479
+ height: 450px;
1480
+ transition: width 0.3s ease, height 0.3s ease;
1481
+ box-sizing: border-box;
1482
+ }
1483
+ .control-wrapper.minimized {
1484
+ width: 230px;
1485
+ height: 45px;
1486
+ }
1487
+
1488
+ .title-wrapper {
1489
+ display: flex;
1490
+ justify-content: space-between;
1491
+ align-items: center;
1492
+ padding: 0;
1493
+ flex-shrink: 0;
1494
+ }
1495
+
1496
+ .title-wrapper h1 {
1497
+ margin: 0;
1498
+ font-size: 15px;
1499
+ }
1500
+
1501
+ .title-element-count {
1502
+ font-size: 14px;
1503
+ text-align: right;
1504
+ }
1505
+
1506
+ .minimize-button {
1507
+ background: none;
1508
+ border: none;
1509
+ color: white;
1510
+ font-size: 22px;
1511
+ cursor: pointer;
1512
+ line-height: 1;
1513
+ padding: 0;
1514
+ }
1515
+
1516
+ .tab-container {
1517
+ display: flex;
1518
+ flex-direction: column;
1519
+ flex: 1;
1520
+ overflow: hidden;
1521
+ }
1522
+
1523
+ .tab-container.hidden {
1524
+ display: none;
1525
+ }
1526
+
1527
+ .tab-content {
1528
+ flex: 1;
1529
+ position: relative;
1530
+ }
1531
+
1532
+ .tab-content > * {
1533
+ display: none;
1534
+ }
1535
+
1536
+ .tab-content > .active {
1537
+ display: flex;
1538
+ position: absolute;
1539
+ top: 0;
1540
+ left: 0;
1541
+ width: 100%;
1542
+ height: 100%;
1543
+ }
1544
+ `,i([W()],b.prototype,"activeTab",2),i([W()],b.prototype,"isMinimized",2),i([W()],b.prototype,"visibleCount",2),i([W()],b.prototype,"totalCount",2),b=i([si("control-panel")],b);customElements.get("control-panel")||customElements.define("control-panel",b);import{LitElement as wi,css as ki,html as Ei}from"lit";import{customElement as Ci}from"lit/decorators.js";import{LitElement as ai,html as ri,css as li}from"lit";import{customElement as di,state as De,query as ci}from"lit/decorators.js";import{ForesightManager as V}from"js.foresight";var C=class extends ai{constructor(){super(...arguments);this.overlayMap=new Map;this.callbackAnimations=new Map;this._abortController=null}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;V.instance.addEventListener("elementRegistered",t=>{t.elementData.isIntersectingWithViewport&&this.createOrUpdateElementOverlay(t.elementData)},{signal:e}),V.instance.addEventListener("elementUnregistered",t=>{this.removeElementOverlay(t.elementData)},{signal:e}),V.instance.addEventListener("elementDataUpdated",t=>{t.updatedProps.includes("bounds")&&this.createOrUpdateElementOverlay(t.elementData),t.updatedProps.includes("visibility")&&(t.elementData.isIntersectingWithViewport||this.removeElementOverlay(t.elementData))},{signal:e}),V.instance.addEventListener("callbackInvoked",t=>{this.highlightElementCallback(t.elementData,t.hitType)},{signal:e}),V.instance.addEventListener("callbackCompleted",t=>{this.unhighlightElementCallback(t.elementData)},{signal:e}),document.addEventListener("showNameTagsChanged",t=>{let o=t;this.updateNameTagVisibility(o.detail.showNameTags)},{signal:e})}createElementOverlays(e){let t=document.createElement("div");t.className="expanded-overlay";let o=document.createElement("div");o.className="name-label",this.containerElement.appendChild(t),this.containerElement.appendChild(o);let a={expandedOverlay:t,nameLabel:o};return this.overlayMap.set(e.element,a),a}updateElementOverlays(e,t){let{expandedOverlay:o,nameLabel:a}=e,{expandedRect:r}=t.elementBounds,N=r.right-r.left,te=r.bottom-r.top;o.style.width=`${N}px`,o.style.height=`${te}px`,o.style.transform=`translate3d(${r.left}px, ${r.top}px, 0)`,l.instance.devtoolsSettings.showNameTags?(a.textContent=t.name,a.style.display="block",a.style.transform=`translate3d(${r.left}px, ${r.top-25}px, 0)`):a.style.display="none"}createOrUpdateElementOverlay(e){let t=this.overlayMap.get(e.element);t||(t=this.createElementOverlays(e)),this.updateElementOverlays(t,e)}removeElementOverlay(e){let t=this.overlayMap.get(e.element);t&&(t.expandedOverlay.remove(),t.nameLabel.remove(),this.overlayMap.delete(e.element)),this.clearCallbackAnimationTimeout(e.element)}clearCallbackAnimationTimeout(e){let t=this.callbackAnimations.get(e);t&&(clearTimeout(t.timeoutId),this.callbackAnimations.delete(e))}highlightElementCallback(e,t){let o=this.overlayMap.get(e.element);if(o)switch(this.clearCallbackAnimationTimeout(e.element),t.kind){case"mouse":o.expandedOverlay.classList.add("invoked-by-mouse");break;case"scroll":o.expandedOverlay.classList.add("invoked-by-scroll");break;case"tab":o.expandedOverlay.classList.add("invoked-by-tab");break;default:}}unhighlightElementCallback(e){let t=this.overlayMap.get(e.element);if(t){let o=setTimeout(()=>{t.expandedOverlay.classList.remove("callback-invoked"),this.callbackAnimations.delete(e.element)},400);this.callbackAnimations.set(e.element,{element:e.element,timeoutId:o})}}updateNameTagVisibility(e){this.overlayMap.forEach(t=>{let o=t.nameLabel;e?o.style.display="block":o.style.display="none"})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}render(){return ri` <div id="overlays-container"></div> `}};C.styles=[li`
1545
+ :host {
1546
+ position: fixed;
1547
+ top: 0;
1548
+ left: 0;
1549
+ width: 100%;
1550
+ height: 100%;
1551
+ pointer-events: none;
1552
+ z-index: 9999;
1553
+ }
1554
+
1555
+ .expanded-overlay {
1556
+ position: absolute;
1557
+ will-change: transform, box-shadow;
1558
+ border: 1px dashed rgba(100, 116, 139, 0.4);
1559
+ background-color: rgba(100, 116, 139, 0.05);
1560
+ transition: border-color 0.2s ease, background-color 0.2s ease;
1561
+ }
1562
+
1563
+ .expanded-overlay.invoked-by-scroll {
1564
+ --glow-color-rgb: 234, 179, 8;
1565
+ border-color: #eab308;
1566
+ background-color: rgba(var(--glow-color-rgb), 0.1);
1567
+ animation: callback-glow 2s ease-in-out infinite;
1568
+ }
1569
+
1570
+ .expanded-overlay.invoked-by-mouse {
1571
+ --glow-color-rgb: 59, 130, 246;
1572
+ border-color: #3b82f6;
1573
+ background-color: rgba(var(--glow-color-rgb), 0.1);
1574
+ animation: callback-glow 2s ease-in-out infinite;
1575
+ }
1576
+
1577
+ .expanded-overlay.invoked-by-tab {
1578
+ --glow-color-rgb: 249, 115, 22;
1579
+ border-color: #f97316;
1580
+ background-color: rgba(var(--glow-color-rgb), 0.1);
1581
+ animation: callback-glow 2s ease-in-out infinite;
1582
+ }
1583
+ @keyframes callback-glow {
1584
+ 0% {
1585
+ box-shadow: 0 0 5px 2px rgba(var(--glow-color-rgb), 0.3);
1586
+ }
1587
+ 50% {
1588
+ box-shadow: 0 0 15px 4px rgba(var(--glow-color-rgb), 0.6);
1589
+ }
1590
+ 100% {
1591
+ box-shadow: 0 0 5px 2px rgba(var(--glow-color-rgb), 0.3);
1592
+ }
1593
+ }
1594
+
1595
+ .name-label {
1596
+ position: absolute;
1597
+ top: 0;
1598
+ left: 0;
1599
+ will-change: transform;
1600
+ background-color: rgba(27, 31, 35, 0.85);
1601
+ backdrop-filter: blur(4px);
1602
+ color: white;
1603
+ padding: 4px 8px;
1604
+ font-size: 11px;
1605
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
1606
+ sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
1607
+ z-index: 10001;
1608
+ white-space: nowrap;
1609
+ pointer-events: none;
1610
+ }
1611
+ `],i([De()],C.prototype,"overlayMap",2),i([De()],C.prototype,"callbackAnimations",2),i([ci("#overlays-container")],C.prototype,"containerElement",2),C=i([di("element-overlays")],C);import{LitElement as pi,html as gi,css as hi}from"lit";import{customElement as mi,state as ee}from"lit/decorators.js";import{styleMap as ui}from"lit/directives/style-map.js";import{ForesightManager as Y}from"js.foresight";var S=class extends pi{constructor(){super(...arguments);this._abortController=new AbortController;this._mousePredictionIsEnabled=Y.instance.getManagerData.globalSettings.enableMousePrediction;this._isVisible=!1;this._trajectoryStyles={};this._isUpdateScheduled=!1;this._latestTrajectory=null;this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableMousePrediction;this._mousePredictionIsEnabled=t,t||(this._isVisible=!1)};this.handleTrajectoryUpdate=e=>{this._mousePredictionIsEnabled&&(this._isVisible=!0,this._latestTrajectory=e.trajectoryPositions,this._isUpdateScheduled||(this._isUpdateScheduled=!0,requestAnimationFrame(this.renderTrajectory)))};this.renderTrajectory=()=>{if(!this._latestTrajectory){this._isUpdateScheduled=!1;return}let{currentPoint:e,predictedPoint:t}=this._latestTrajectory,o=t.x-e.x,a=t.y-e.y,r=Math.sqrt(o*o+a*a);if(r===0)this._trajectoryStyles={display:"none"};else{let N=Math.atan2(a,o)*180/Math.PI;this._trajectoryStyles={transform:`translate(${e.x}px, ${e.y}px) rotate(${N}deg)`,width:`${r}px`}}this._isUpdateScheduled=!1,this.requestUpdate()}}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;Y.instance.addEventListener("mouseTrajectoryUpdate",this.handleTrajectoryUpdate,{signal:e}),Y.instance.addEventListener("scrollTrajectoryUpdate",()=>{this._isVisible=!1},{signal:e}),Y.instance.addEventListener("managerSettingsChanged",this.handleSettingsChange,{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}render(){let e={display:this._isVisible?"block":"none",...this._trajectoryStyles};return gi` <div class="trajectory-line" style=${ui(e)}></div> `}};S.styles=[hi`
1612
+ :host {
1613
+ display: block;
1614
+ }
1615
+
1616
+ .trajectory-line {
1617
+ position: absolute;
1618
+ top: 0;
1619
+ left: 0;
1620
+ will-change: transform, width;
1621
+ transform-origin: left center;
1622
+ height: 4px;
1623
+ background: linear-gradient(90deg, #3b82f6, rgba(59, 130, 246, 0.4));
1624
+ z-index: 9999;
1625
+ border-radius: 2px;
1626
+ box-shadow: 0 0 12px rgba(59, 130, 246, 0.4);
1627
+ }
1628
+
1629
+ .trajectory-line::after {
1630
+ content: "";
1631
+ position: absolute;
1632
+ right: -6px;
1633
+ top: 50%;
1634
+ transform: translateY(-50%);
1635
+ width: 0;
1636
+ height: 0;
1637
+ border-left: 8px solid #3b82f6;
1638
+ border-top: 4px solid transparent;
1639
+ border-bottom: 4px solid transparent;
1640
+ filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.6));
1641
+ }
1642
+ `],i([ee()],S.prototype,"_mousePredictionIsEnabled",2),i([ee()],S.prototype,"_isVisible",2),i([ee()],S.prototype,"_trajectoryStyles",2),S=i([mi("mouse-trajectory")],S);import{LitElement as bi,html as vi,css as fi}from"lit";import{customElement as yi,state as q}from"lit/decorators.js";import{styleMap as xi}from"lit/directives/style-map.js";import{ForesightManager as z}from"js.foresight";var k=class extends bi{constructor(){super(...arguments);this._abortController=new AbortController;this._scrollPredictionIsEnabled=z.instance.getManagerData.globalSettings.enableScrollPrediction;this._scrollMargin=z.instance.getManagerData.globalSettings.scrollMargin;this._isVisible=!1;this._trajectoryStyles={};this._isUpdateScheduled=!1;this._latestScrollTrajectory=null;this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableScrollPrediction;this._scrollPredictionIsEnabled=t,t||(this._isVisible=!1);let o=e.updatedSettings.find(a=>a.setting==="scrollMargin");o&&(this._scrollMargin=o.newValue)};this.handleScrollUpdate=e=>{this._scrollPredictionIsEnabled&&(this._isVisible=!0,this._latestScrollTrajectory={currentPoint:e.currentPoint,predictedPoint:e.predictedPoint},this._isUpdateScheduled||(this._isUpdateScheduled=!0,requestAnimationFrame(this.renderScrollTrajectory)))};this.renderScrollTrajectory=()=>{if(!this._latestScrollTrajectory){this._isUpdateScheduled=!1;return}let{currentPoint:e,predictedPoint:t}=this._latestScrollTrajectory,o=t.x-e.x,a=t.y-e.y,r=Math.atan2(a,o)*180/Math.PI;this._trajectoryStyles={transform:`translate(${e.x}px, ${e.y}px) rotate(${r}deg)`},this._isUpdateScheduled=!1,this.requestUpdate()}}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;z.instance.addEventListener("scrollTrajectoryUpdate",this.handleScrollUpdate,{signal:e}),z.instance.addEventListener("mouseTrajectoryUpdate",()=>{this._isVisible=!1},{signal:e}),z.instance.addEventListener("managerSettingsChanged",this.handleSettingsChange,{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}render(){let e={display:this._isVisible?"block":"none",width:`${this._scrollMargin}px`,...this._trajectoryStyles};return vi` <div class="scroll-trajectory-line" style=${xi(e)}></div> `}};k.styles=[fi`
1643
+ :host {
1644
+ display: block;
1645
+ }
1646
+
1647
+ .scroll-trajectory-line {
1648
+ position: absolute;
1649
+ top: 0;
1650
+ left: 0;
1651
+ will-change: transform, width;
1652
+ transform-origin: left center;
1653
+ height: 4px;
1654
+ background: repeating-linear-gradient(
1655
+ 90deg,
1656
+ #eab308 0px,
1657
+ #eab308 8px,
1658
+ transparent 8px,
1659
+ transparent 16px
1660
+ );
1661
+ z-index: 9999;
1662
+ border-radius: 2px;
1663
+ animation: scroll-dash-flow 1.5s linear infinite;
1664
+ box-shadow: 0 0 12px rgba(234, 179, 8, 0.4);
1665
+ }
1666
+
1667
+ .scroll-trajectory-line::after {
1668
+ content: "";
1669
+ position: absolute;
1670
+ right: -6px;
1671
+ top: 50%;
1672
+ transform: translateY(-50%);
1673
+ width: 0;
1674
+ height: 0;
1675
+ border-left: 8px solid #eab308;
1676
+ border-top: 4px solid transparent;
1677
+ border-bottom: 4px solid transparent;
1678
+ filter: drop-shadow(0 0 6px rgba(234, 179, 8, 0.6));
1679
+ animation: scroll-arrow-pulse 1.5s ease-in-out infinite;
1680
+ }
1681
+
1682
+ @keyframes scroll-dash-flow {
1683
+ 0% {
1684
+ background-position: 0px 0px;
1685
+ }
1686
+ 100% {
1687
+ background-position: 16px 0px;
1688
+ }
1689
+ }
1690
+
1691
+ @keyframes scroll-arrow-pulse {
1692
+ 0%,
1693
+ 100% {
1694
+ transform: translateY(-50%) scale(1);
1695
+ filter: drop-shadow(0 0 6px rgba(234, 179, 8, 0.6));
1696
+ }
1697
+ 50% {
1698
+ transform: translateY(-50%) scale(1.2);
1699
+ filter: drop-shadow(0 0 12px rgba(234, 179, 8, 0.8));
1700
+ }
1701
+ }
1702
+ `],i([q()],k.prototype,"_scrollPredictionIsEnabled",2),i([q()],k.prototype,"_scrollMargin",2),i([q()],k.prototype,"_isVisible",2),i([q()],k.prototype,"_trajectoryStyles",2),k=i([yi("scroll-trajectory")],k);var R=class extends wi{render(){return Ei`
1703
+ <div id="overlay-container">
1704
+ <mouse-trajectory></mouse-trajectory>
1705
+ <scroll-trajectory></scroll-trajectory>
1706
+ <element-overlays></element-overlays>
1707
+ </div>
1708
+ `}};R.styles=[ki`
1709
+ :host {
1710
+ display: block;
1711
+ }
1712
+ #overlay-container {
1713
+ position: fixed;
1714
+ top: 0;
1715
+ left: 0;
1716
+ pointer-events: none;
1717
+ z-index: 9999;
1718
+ }
1719
+ `],R=i([Ci("debug-overlay")],R);var l=class extends Si{constructor(){super();this.isInitialized=!1;this.devtoolsSettings={showDebugger:!0,isControlPanelDefaultMinimized:!1,showNameTags:!0,sortElementList:"visibility",logging:{logLocation:"controlPanel",callbackCompleted:!0,callbackInvoked:!0,elementDataUpdated:!1,elementRegistered:!1,elementUnregistered:!1,managerSettingsChanged:!0,mouseTrajectoryUpdate:!1,scrollTrajectoryUpdate:!1}}}static createAndAppendInstance(){typeof window>"u"||typeof document>"u"||(l._instance=document.createElement("foresight-devtools"),document.body.appendChild(l._instance))}static initialize(e){if(l._instance||l.createAndAppendInstance(),!l._instance)return l._instance;let t=l._instance;return t.isInitialized=!0,e!==void 0&&t.alterDevtoolsSettings(e),t}static get instance(){return l._instance?l._instance:l.initialize()}disconnectedCallback(){super.disconnectedCallback(),this.cleanup()}shouldUpdateSetting(e,t){return e!==void 0&&e!==t}alterDevtoolsSettings(e){e&&(this.shouldUpdateSetting(e.showNameTags,this.devtoolsSettings.showNameTags)&&(this.devtoolsSettings.showNameTags=e.showNameTags,this.dispatchEvent(new CustomEvent("showNameTagsChanged",{detail:{showNameTags:e.showNameTags},bubbles:!0}))),this.shouldUpdateSetting(e.showDebugger,this.devtoolsSettings.showDebugger)&&(this.devtoolsSettings.showDebugger=e.showDebugger,this.requestUpdate()),this.shouldUpdateSetting(e.isControlPanelDefaultMinimized,this.devtoolsSettings.isControlPanelDefaultMinimized)&&(this.devtoolsSettings.isControlPanelDefaultMinimized=e.isControlPanelDefaultMinimized),this.shouldUpdateSetting(e.sortElementList,this.devtoolsSettings.sortElementList)&&(this.devtoolsSettings.sortElementList=e.sortElementList),e.logging&&(this.shouldUpdateSetting(e.logging.logLocation,this.devtoolsSettings.logging.logLocation)&&(this.devtoolsSettings.logging.logLocation=e.logging.logLocation),this.shouldUpdateSetting(e.logging.callbackCompleted,this.devtoolsSettings.logging.callbackCompleted)&&(this.devtoolsSettings.logging.callbackCompleted=e.logging.callbackCompleted),this.shouldUpdateSetting(e.logging.callbackInvoked,this.devtoolsSettings.logging.callbackInvoked)&&(this.devtoolsSettings.logging.callbackInvoked=e.logging.callbackInvoked),this.shouldUpdateSetting(e.logging.elementDataUpdated,this.devtoolsSettings.logging.elementDataUpdated)&&(this.devtoolsSettings.logging.elementDataUpdated=e.logging.elementDataUpdated),this.shouldUpdateSetting(e.logging.elementRegistered,this.devtoolsSettings.logging.elementRegistered)&&(this.devtoolsSettings.logging.elementRegistered=e.logging.elementRegistered),this.shouldUpdateSetting(e.logging.elementUnregistered,this.devtoolsSettings.logging.elementUnregistered)&&(this.devtoolsSettings.logging.elementUnregistered=e.logging.elementUnregistered),this.shouldUpdateSetting(e.logging.managerSettingsChanged,this.devtoolsSettings.logging.managerSettingsChanged)&&(this.devtoolsSettings.logging.managerSettingsChanged=e.logging.managerSettingsChanged),this.shouldUpdateSetting(e.logging.mouseTrajectoryUpdate,this.devtoolsSettings.logging.mouseTrajectoryUpdate)&&(this.devtoolsSettings.logging.mouseTrajectoryUpdate=e.logging.mouseTrajectoryUpdate),this.shouldUpdateSetting(e.logging.scrollTrajectoryUpdate,this.devtoolsSettings.logging.scrollTrajectoryUpdate)&&(this.devtoolsSettings.logging.scrollTrajectoryUpdate=e.logging.scrollTrajectoryUpdate)))}cleanup(){this.requestUpdate()}render(){return!this.isInitialized||!this.devtoolsSettings.showDebugger?Oe``:Oe`<control-panel></control-panel> <debug-overlay></debug-overlay>`}};l.styles=[Ti`
1720
+ :host {
1721
+ display: block;
1722
+ }
1723
+ `],l._instance=null,i([_i()],l.prototype,"isInitialized",2),l=i([Mi("foresight-devtools")],l);export{l as ForesightDevtools};
1724
+ //# sourceMappingURL=index.mjs.map