js.foresight-devtools 2.0.0 → 2.1.0

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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,property as i,query as a,state as o}from"lit/decorators.js";import{classMap as s}from"lit/directives/class-map.js";import{ForesightManager as c}from"js.foresight";import{map as l}from"lit/directives/map.js";const u=[`controlPanel`,`nameTags`,`elementOverlays`,`mouseTrajectory`,`scrollTrajectory`],ee=n`
1
+ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,property as i,query as a,state as o}from"lit/decorators.js";import{ForesightManager as s}from"js.foresight";import{repeat as c}from"lit/directives/repeat.js";const l=[`controlPanel`,`nameTags`,`elementOverlays`,`mouseTrajectory`,`scrollTrajectory`],u=n`
2
2
  <svg
3
3
  xmlns="http://www.w3.org/2000/svg"
4
4
  width="16"
@@ -15,7 +15,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
15
15
  <line x1="7" y1="21" x2="17" y2="21"></line>
16
16
  <line x1="12" y1="17" x2="12" y2="21"></line>
17
17
  </svg>
18
- `,te=n`
18
+ `,d=n`
19
19
  <svg
20
20
  xmlns="http://www.w3.org/2000/svg"
21
21
  width="16"
@@ -30,7 +30,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
30
30
  <polyline points="4 17 10 11 4 5"></polyline>
31
31
  <line x1="12" y1="19" x2="20" y2="19"></line>
32
32
  </svg>
33
- `,d=n`
33
+ `,ee=n`
34
34
  <svg
35
35
  xmlns="http://www.w3.org/2000/svg"
36
36
  width="16"
@@ -46,7 +46,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
46
46
  <path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
47
47
  <line x1="1" y1="1" x2="23" y2="23"></line>
48
48
  </svg>
49
- `,f=n`
49
+ `,te=n`
50
50
  <svg
51
51
  xmlns="http://www.w3.org/2000/svg"
52
52
  width="16"
@@ -64,7 +64,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
64
64
  <circle cx="6" cy="18" r="2" />
65
65
  <circle cx="18" cy="18" r="2" />
66
66
  </svg>
67
- `,ne=n`
67
+ `,f=n`
68
68
  <svg
69
69
  xmlns="http://www.w3.org/2000/svg"
70
70
  width="16"
@@ -79,7 +79,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
79
79
  <path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z" />
80
80
  <circle cx="12" cy="12" r="3" />
81
81
  </svg>
82
- `,re=n`
82
+ `,ne=n`
83
83
  <svg
84
84
  xmlns="http://www.w3.org/2000/svg"
85
85
  width="16"
@@ -97,7 +97,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
97
97
  <line x1="16" y1="17" x2="8" y2="17" />
98
98
  <line x1="10" y1="9" x2="8" y2="9" />
99
99
  </svg>
100
- `,p=n`
100
+ `,re=n`
101
101
  <svg
102
102
  xmlns="http://www.w3.org/2000/svg"
103
103
  width="16"
@@ -111,7 +111,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
111
111
  >
112
112
  <path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" />
113
113
  </svg>
114
- `,m=n`
114
+ `,p=n`
115
115
  <svg
116
116
  xmlns="http://www.w3.org/2000/svg"
117
117
  width="16"
@@ -125,7 +125,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
125
125
  >
126
126
  <polygon points="22,3 2,3 10,12.46 10,19 14,21 14,12.46" />
127
127
  </svg>
128
- `,h=n`
128
+ `,ie=n`
129
129
  <svg
130
130
  xmlns="http://www.w3.org/2000/svg"
131
131
  width="16"
@@ -140,7 +140,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
140
140
  <circle cx="12" cy="12" r="10" />
141
141
  <line x1="4.93" y1="4.93" x2="19.07" y2="19.07" />
142
142
  </svg>
143
- `,ie=n`
143
+ `,ae=n`
144
144
  <svg
145
145
  xmlns="http://www.w3.org/2000/svg"
146
146
  width="24"
@@ -155,7 +155,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
155
155
  <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
156
156
  <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
157
157
  </svg>
158
- `,ae=n`
158
+ `,m=n`
159
159
  <svg
160
160
  xmlns="http://www.w3.org/2000/svg"
161
161
  width="24"
@@ -272,7 +272,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
272
272
  <circle cx="12" cy="12" r="10" />
273
273
  <line x1="4.93" y1="4.93" x2="19.07" y2="19.07" />
274
274
  </svg>
275
- `,ue=n`
275
+ `,h=n`
276
276
  <svg
277
277
  xmlns="http://www.w3.org/2000/svg"
278
278
  width="12"
@@ -609,7 +609,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
609
609
  title="${this.title}"
610
610
  @click=${this.handleClick}
611
611
  >
612
- ${this.isCopied?ae:ie}
612
+ ${this.isCopied?m:ae}
613
613
  </button>
614
614
  `}};_([i({type:String}),g(`design:type`,String)],C.prototype,`title`,void 0),_([i({type:Function}),g(`design:type`,Function)],C.prototype,`onCopy`,void 0),_([o(),g(`design:type`,Boolean)],C.prototype,`isCopied`,void 0),_([o(),g(`design:type`,Object)],C.prototype,`copyTimeout`,void 0),C=_([r(`copy-icon`)],C);let w=class extends e{constructor(...e){super(...e),this.borderColor=`#555`,this.showCopyButton=!1,this.itemId=``,this.isExpanded=!1}static{this.styles=[t`
615
615
  :host {
@@ -733,7 +733,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
733
733
  </div>
734
734
  `:``}
735
735
  </div>
736
- `}};_([i(),g(`design:type`,String)],w.prototype,`borderColor`,void 0),_([i(),g(`design:type`,Boolean)],w.prototype,`showCopyButton`,void 0),_([i(),g(`design:type`,String)],w.prototype,`itemId`,void 0),_([i(),g(`design:type`,Boolean)],w.prototype,`isExpanded`,void 0),_([i(),g(`design:type`,Object)],w.prototype,`onToggle`,void 0),w=_([r(`expandable-item`)],w);let T=class extends e{constructor(...e){super(...e),this.remainingTime=0,this.isCountdownActive=!1,this.intervalId=null,this.startTime=0,this.lastDisplayedTime=``,this.countdownForElement=null,this.countdownReactivateAfter=0,this.handleTimerClick=e=>{e.stopPropagation(),c.instance.reactivate(this.element)}}static{this.styles=[t`
736
+ `}};_([i(),g(`design:type`,String)],w.prototype,`borderColor`,void 0),_([i(),g(`design:type`,Boolean)],w.prototype,`showCopyButton`,void 0),_([i(),g(`design:type`,String)],w.prototype,`itemId`,void 0),_([i(),g(`design:type`,Boolean)],w.prototype,`isExpanded`,void 0),_([i(),g(`design:type`,Object)],w.prototype,`onToggle`,void 0),w=_([r(`expandable-item`)],w);let T=class extends e{constructor(...e){super(...e),this.remainingTime=0,this.isCountdownActive=!1,this.intervalId=null,this.startTime=0,this.lastDisplayedTime=``,this.countdownForElement=null,this.countdownReactivateAfter=0,this.handleTimerClick=e=>{e.stopPropagation(),s.instance.reactivate(this.element)}}static{this.styles=[t`
737
737
  :host {
738
738
  display: inline-block;
739
739
  }
@@ -779,7 +779,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
779
779
  >
780
780
  <span class="countdown-time clickable">${this.formatTime(this.remainingTime)}</span>
781
781
  </button>
782
- `:n``}};_([i({attribute:!1}),g(`design:type`,Object)],T.prototype,`element`,void 0),_([i({attribute:!1,hasChanged:()=>!0}),g(`design:type`,Object)],T.prototype,`state`,void 0),_([o(),g(`design:type`,Number)],T.prototype,`remainingTime`,void 0),_([o(),g(`design:type`,Boolean)],T.prototype,`isCountdownActive`,void 0),T=_([r(`reactivate-countdown`)],T);let E=class extends e{constructor(...e){super(...e),this.isExpanded=!1,this.currentDeviceStrategy=`mouse`,this._abortController=null,this.handleUnregister=e=>{e.stopPropagation(),c.instance.unregister(this.element,`devtools`)},this.handleToggleEnabled=e=>{e.stopPropagation(),c.instance.updateElementOptions(this.element,{enabled:!this.state.isEnabled})}}static{this.styles=[t`
782
+ `:n``}};_([i({attribute:!1}),g(`design:type`,Object)],T.prototype,`element`,void 0),_([i({attribute:!1}),g(`design:type`,Object)],T.prototype,`state`,void 0),_([o(),g(`design:type`,Number)],T.prototype,`remainingTime`,void 0),_([o(),g(`design:type`,Boolean)],T.prototype,`isCountdownActive`,void 0),T=_([r(`reactivate-countdown`)],T);let E=class extends e{constructor(...e){super(...e),this.isExpanded=!1,this.currentDeviceStrategy=`mouse`,this._abortController=null,this.handleUnregister=e=>{e.stopPropagation(),s.instance.unregister(this.element,`devtools`)},this.handleToggleEnabled=e=>{e.stopPropagation(),s.instance.updateElementOptions(this.element,{enabled:!this.state.isEnabled})}}static{this.styles=[t`
783
783
  :host {
784
784
  display: block;
785
785
  }
@@ -925,7 +925,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
925
925
  .element-wrapper.not-visible {
926
926
  opacity: 0.5;
927
927
  }
928
- `]}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;this.currentDeviceStrategy=c.instance.getManagerData.currentDeviceStrategy,c.instance.addEventListener(`deviceStrategyChanged`,e=>{this.currentDeviceStrategy=e.newStrategy},{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}getInactiveReasons(){let e=[];return this.state.isEnabled||e.push({label:`disabled`,color:`#9e9e9e`,description:`Element is disabled, so its callback won't run until you re-enable it.`}),this.state.isParked&&e.push({label:`parked`,color:`#7986cb`,description:`Element is detached from the DOM and parked: kept registered but inactive until it reconnects.`}),this.state.isLimitedConnection&&e.push({label:`limited`,color:`#ffb74d`,description:`Element is on a limited connection (e.g. Save-Data or slow network), so prediction is paused.`}),this.state.isEnabled&&!this.state.isParked&&!this.state.isLimitedConnection&&!this.state.isActive&&this.state.isPredicted&&e.push({label:`fired`,color:`#4dd0e1`,description:`Callback already fired. Stays inactive until reactivated (never, unless reactivateAfter is set).`}),e}getBorderColor(){return this.state.isCallbackRunning?`#ffeb3b`:this.state.isActive?this.currentDeviceStrategy===`touch`?`#ba68c8`:this.state.isIntersectingWithViewport?`#4caf50`:`#666`:`#999`}getStatusIndicatorClass(){return this.state.isCallbackRunning?`prefetching`:this.state.isActive?this.currentDeviceStrategy===`touch`?`touch-device`:this.state.isIntersectingWithViewport?`visible`:`hidden`:`inactive`}getStatusText(){if(this.state.isCallbackRunning)return`callback active`;if(!this.state.isActive){let e=this.getInactiveReasons();return e.length?`inactive: ${e.map(e=>e.label).join(`, `)}`:`inactive`}return(this.state.isIntersectingWithViewport?`in viewport`:`not in viewport`)+(this.currentDeviceStrategy===`touch`?` (touch device)`:``)}formatElementDetails(){if(!this.isExpanded)return``;let{elementBounds:e,...t}=this.state;return JSON.stringify({...t,status:this.getStatusText(),hitSlop:e.hitSlop},null,2)}render(){let e=!this.state.isIntersectingWithViewport&&this.currentDeviceStrategy!==`touch`,t=this.getInactiveReasons();return n`
928
+ `]}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;this.currentDeviceStrategy=s.instance.getManagerData.currentDeviceStrategy,s.instance.addEventListener(`deviceStrategyChanged`,e=>{this.currentDeviceStrategy=e.newStrategy},{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}getInactiveReasons(){let e=[];return this.state.isEnabled||e.push({label:`disabled`,color:`#9e9e9e`,description:`Element is disabled, so its callback won't run until you re-enable it.`}),this.state.isParked&&e.push({label:`parked`,color:`#7986cb`,description:`Element is detached from the DOM and parked: kept registered but inactive until it reconnects.`}),this.state.isLimitedConnection&&e.push({label:`limited`,color:`#ffb74d`,description:`Element is on a limited connection (e.g. Save-Data or slow network), so prediction is paused.`}),this.state.isEnabled&&!this.state.isParked&&!this.state.isLimitedConnection&&!this.state.isActive&&this.state.isPredicted&&e.push({label:`fired`,color:`#4dd0e1`,description:`Callback already fired. Stays inactive until reactivated (never, unless reactivateAfter is set).`}),e}getBorderColor(){return this.state.isCallbackRunning?`#ffeb3b`:this.state.isActive?this.currentDeviceStrategy===`touch`?`#ba68c8`:this.state.isIntersectingWithViewport?`#4caf50`:`#666`:`#999`}getStatusIndicatorClass(){return this.state.isCallbackRunning?`prefetching`:this.state.isActive?this.currentDeviceStrategy===`touch`?`touch-device`:this.state.isIntersectingWithViewport?`visible`:`hidden`:`inactive`}getStatusText(){if(this.state.isCallbackRunning)return`callback active`;if(!this.state.isActive){let e=this.getInactiveReasons();return e.length?`inactive: ${e.map(e=>e.label).join(`, `)}`:`inactive`}return(this.state.isIntersectingWithViewport?`in viewport`:`not in viewport`)+(this.currentDeviceStrategy===`touch`?` (touch device)`:``)}formatElementDetails(){return this.isExpanded?JSON.stringify({...this.state,status:this.getStatusText()},null,2):``}render(){let e=!this.state.isIntersectingWithViewport&&this.currentDeviceStrategy!==`touch`,t=this.getInactiveReasons();return n`
929
929
  <div class="element-wrapper ${e?`not-visible`:``}">
930
930
  <expandable-item
931
931
  .borderColor=${this.getBorderColor()}
@@ -967,7 +967,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
967
967
  @click="${this.handleToggleEnabled}"
968
968
  title="Enable element"
969
969
  >
970
- ${ue}
970
+ ${h}
971
971
  </button>
972
972
  `}
973
973
  <button
@@ -981,7 +981,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
981
981
  <div slot="details">${this.formatElementDetails()}</div>
982
982
  </expandable-item>
983
983
  </div>
984
- `}};_([i({attribute:!1}),g(`design:type`,Object)],E.prototype,`element`,void 0),_([i({attribute:!1,hasChanged:()=>!0}),g(`design:type`,Object)],E.prototype,`state`,void 0),_([i(),g(`design:type`,Boolean)],E.prototype,`isExpanded`,void 0),_([i(),g(`design:type`,Object)],E.prototype,`onToggle`,void 0),_([o(),g(`design:type`,String)],E.prototype,`currentDeviceStrategy`,void 0),E=_([r(`single-element`)],E);var D,O;let k=class extends e{static{this.styles=t`
984
+ `}};_([i({attribute:!1}),g(`design:type`,Object)],E.prototype,`element`,void 0),_([i({attribute:!1}),g(`design:type`,Object)],E.prototype,`state`,void 0),_([i(),g(`design:type`,Boolean)],E.prototype,`isExpanded`,void 0),_([i(),g(`design:type`,Object)],E.prototype,`onToggle`,void 0),_([o(),g(`design:type`,String)],E.prototype,`currentDeviceStrategy`,void 0),E=_([r(`single-element`)],E);var D,O;let k=class extends e{static{this.styles=t`
985
985
  :host {
986
986
  display: flex;
987
987
  flex-direction: column;
@@ -1034,8 +1034,8 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1034
1034
  .section-header.inactive {
1035
1035
  color: #999;
1036
1036
  }
1037
- `}constructor(){super(),this.hitCount={mouse:{hover:0,trajectory:0},scroll:{down:0,left:0,right:0,up:0},tab:{forwards:0,reverse:0},touch:0,viewport:0,total:0},this.elementListItems=new Map,this.noContentMessage=`No Elements Registered To The Foresight Manager`,this.expandedElementIds=new Set,this.activeSectionCollapsed=!1,this.inactiveSectionCollapsed=!1,this._abortController=null,this._elementSubscriptions=new Map,this._pendingElementUpdates=new Map,this._updateDebounceId=null,this._cachedActiveElements=[],this._cachedInactiveElements=[],this._elementsCacheDirty=!0,this.handleSortChange=e=>{this.sortOrder=e,this._elementsCacheDirty=!0},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 n=e.element.compareDocumentPosition(t.element);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0},this.sortOrder=$.instance.devtoolsSettings.sortElementList,this.sortDropdown=[{value:`visibility`,label:`Visibility`,title:`Sort by Visibility`,icon:ne},{value:`documentOrder`,label:`Document Order`,title:`Sort by Document Order`,icon:re},{value:`insertionOrder`,label:`Insertion Order`,title:`Sort by Insertion Order`,icon:p}]}_generateHitsChipTitle(e){let t=[];t.push(`Total Callback Hits: ${e.total}`),t.push(``);let n=e.mouse.trajectory+e.mouse.hover,r=e.scroll.up+e.scroll.down+e.scroll.left+e.scroll.right,i=e.tab.forwards+e.tab.reverse;t.push(`Desktop Strategy`),n>0?t.push(` Mouse (${n}): ${e.mouse.trajectory} trajectory, ${e.mouse.hover} hover`):t.push(` Mouse: No hits`),r>0?t.push(` Scroll (${r}): Up ${e.scroll.up}, Down ${e.scroll.down}, Left ${e.scroll.left}, Right ${e.scroll.right}`):t.push(` Scroll: No hits`),i>0?t.push(` Tab (${i}): ${e.tab.forwards} forward, ${e.tab.reverse} reverse`):t.push(` Tab: No hits`),t.push(``);let a=e.touch+e.viewport;return t.push(`Touch Strategy`),e.touch>0?t.push(` Touch Start: ${e.touch}`):t.push(` Touch Start: No hits`),e.viewport>0?t.push(` Viewport Enter: ${e.viewport}`):t.push(` Viewport Enter: No hits`),a===0&&n+r+i===0&&(t.push(``),t.push(`Interact with registered elements to see callback statistics`)),t.join(`
1038
- `)}_subscribeToElement(e){if(this._elementSubscriptions.has(e))return;let t=c.instance.subscribeToElement(e,()=>{let t=c.instance.registeredElements.get(e);t&&t.isRegistered&&(this._pendingElementUpdates.set(e,t),this._scheduleDebouncedUpdate())});t&&this._elementSubscriptions.set(e,t)}_unsubscribeFromElement(e){this._elementSubscriptions.get(e)?.(),this._elementSubscriptions.delete(e)}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;this.updateElementListFromManager();for(let e of this.elementListItems.keys())this._subscribeToElement(e);c.instance.addEventListener(`elementRegistered`,e=>{this.elementListItems.set(e.element,e.state),this._subscribeToElement(e.element),this._elementsCacheDirty=!0,this.requestUpdate()},{signal:e}),c.instance.addEventListener(`elementUnregistered`,e=>{this._unsubscribeFromElement(e.element),this.elementListItems.delete(e.element),this._pendingElementUpdates.delete(e.element),this.elementListItems.size||(this.noContentMessage=`No Elements Registered To The Foresight Manager`),this._elementsCacheDirty=!0,this.requestUpdate()},{signal:e}),c.instance.addEventListener(`callbackInvoked`,e=>{this._pendingElementUpdates.set(e.element,e.state),this._scheduleDebouncedUpdate()},{signal:e}),c.instance.addEventListener(`callbackCompleted`,e=>{this.handleCallbackCompleted(e.hitType)},{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null;for(let e of this._elementSubscriptions.values())e();this._elementSubscriptions.clear(),this._updateDebounceId!==null&&(clearTimeout(this._updateDebounceId),this._updateDebounceId=null),this._pendingElementUpdates.clear()}_scheduleDebouncedUpdate(){this._updateDebounceId===null&&(this._updateDebounceId=setTimeout(()=>{this._updateDebounceId=null,this._flushPendingUpdates()},16))}_flushPendingUpdates(){if(this._pendingElementUpdates.size!==0){for(let[e,t]of this._pendingElementUpdates)this.elementListItems.set(e,t);this._pendingElementUpdates.clear(),this._elementsCacheDirty=!0,this.requestUpdate()}}updateElementListFromManager(){this.elementListItems=new Map(c.instance.registeredElements),this._elementsCacheDirty=!0}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;case`touch`:this.hitCount.touch++;break;case`viewport`:this.hitCount.viewport++;break;default:}this.hitCount.total++,this.requestUpdate()}getSortedElements(){let e=Array.from(this.elementListItems,([e,t])=>({element:e,state:t}));switch(this.sortOrder){case`insertionOrder`:return e;case`documentOrder`:return e.sort(this.sortByDocumentPosition);case`visibility`:return e.sort((e,t)=>e.state.isIntersectingWithViewport===t.state.isIntersectingWithViewport?this.sortByDocumentPosition(e,t):e.state.isIntersectingWithViewport?-1:1);default:return this.sortOrder,e}}_recomputeElementsCache(){if(!this._elementsCacheDirty)return;let e=[],t=[];for(let n of this.getSortedElements())n.state.isActive?e.push(n):t.push(n);this._cachedActiveElements=e,this._cachedInactiveElements=t,this._elementsCacheDirty=!1}get activeElements(){return this._recomputeElementsCache(),this._cachedActiveElements}get inactiveElements(){return this._recomputeElementsCache(),this._cachedInactiveElements}renderElementSection(e,t,r,i,a){return r.length===0?``:n`
1037
+ `}get hitCount(){return s.instance.getManagerData.globalCallbackHits}constructor(){super(),this.elementListItems=new Map,this.noContentMessage=`No Elements Registered To The Foresight Manager`,this.expandedElementIds=new Set,this.activeSectionCollapsed=!1,this.inactiveSectionCollapsed=!1,this._abortController=null,this._elementSubscriptions=new Map,this._pendingElementUpdates=new Map,this._updateDebounceId=null,this._cachedActiveElements=[],this._cachedInactiveElements=[],this._elementsCacheDirty=!0,this.handleSortChange=e=>{this.sortOrder=e,this._elementsCacheDirty=!0},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 n=e.element.compareDocumentPosition(t.element);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0},this.sortOrder=$.instance.devtoolsSettings.sortElementList,this.sortDropdown=[{value:`visibility`,label:`Visibility`,title:`Sort by Visibility`,icon:f},{value:`documentOrder`,label:`Document Order`,title:`Sort by Document Order`,icon:ne},{value:`insertionOrder`,label:`Insertion Order`,title:`Sort by Insertion Order`,icon:re}]}_generateHitsChipTitle(e){let t=[];t.push(`Total Callback Hits: ${e.total}`),t.push(``);let n=e.mouse.trajectory+e.mouse.hover,r=e.scroll.up+e.scroll.down+e.scroll.left+e.scroll.right,i=e.tab.forwards+e.tab.reverse;t.push(`Desktop Strategy`),n>0?t.push(` Mouse (${n}): ${e.mouse.trajectory} trajectory, ${e.mouse.hover} hover`):t.push(` Mouse: No hits`),r>0?t.push(` Scroll (${r}): Up ${e.scroll.up}, Down ${e.scroll.down}, Left ${e.scroll.left}, Right ${e.scroll.right}`):t.push(` Scroll: No hits`),i>0?t.push(` Tab (${i}): ${e.tab.forwards} forward, ${e.tab.reverse} reverse`):t.push(` Tab: No hits`),t.push(``);let a=e.touch+e.viewport;return t.push(`Touch Strategy`),e.touch>0?t.push(` Touch Start: ${e.touch}`):t.push(` Touch Start: No hits`),e.viewport>0?t.push(` Viewport Enter: ${e.viewport}`):t.push(` Viewport Enter: No hits`),a===0&&n+r+i===0&&(t.push(``),t.push(`Interact with registered elements to see callback statistics`)),t.join(`
1038
+ `)}_subscribeToElement(e){if(this._elementSubscriptions.has(e))return;let t=s.instance.subscribeToElement(e,()=>{let t=s.instance.registeredElements.get(e);!t||!t.isRegistered||(this._pendingElementUpdates.set(e,t),this._scheduleDebouncedUpdate())});t&&this._elementSubscriptions.set(e,t)}_unsubscribeFromElement(e){this._elementSubscriptions.get(e)?.(),this._elementSubscriptions.delete(e)}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;this.updateElementListFromManager();for(let e of this.elementListItems.keys())this._subscribeToElement(e);s.instance.addEventListener(`elementRegistered`,e=>{this.elementListItems.set(e.element,e.state),this._subscribeToElement(e.element),this._elementsCacheDirty=!0,this.requestUpdate()},{signal:e}),s.instance.addEventListener(`elementUnregistered`,e=>{this._unsubscribeFromElement(e.element),this.elementListItems.delete(e.element),this._pendingElementUpdates.delete(e.element),this.elementListItems.size||(this.noContentMessage=`No Elements Registered To The Foresight Manager`),this._elementsCacheDirty=!0,this.requestUpdate()},{signal:e}),s.instance.addEventListener(`callbackInvoked`,e=>{this._pendingElementUpdates.set(e.element,e.state),this._scheduleDebouncedUpdate()},{signal:e}),s.instance.addEventListener(`callbackCompleted`,()=>{this.requestUpdate()},{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null;for(let e of this._elementSubscriptions.values())e();this._elementSubscriptions.clear(),this._updateDebounceId!==null&&(clearTimeout(this._updateDebounceId),this._updateDebounceId=null),this._pendingElementUpdates.clear()}_scheduleDebouncedUpdate(){this._updateDebounceId===null&&(this._updateDebounceId=setTimeout(()=>{this._updateDebounceId=null,this._flushPendingUpdates()},16))}_flushPendingUpdates(){if(this._pendingElementUpdates.size!==0){for(let[e,t]of this._pendingElementUpdates){let n=this.elementListItems.get(e);(!n||n.isActive!==t.isActive||n.isIntersectingWithViewport!==t.isIntersectingWithViewport)&&(this._elementsCacheDirty=!0),this.elementListItems.set(e,t)}this._pendingElementUpdates.clear(),this.requestUpdate()}}updateElementListFromManager(){this.elementListItems=new Map(s.instance.registeredElements),this._elementsCacheDirty=!0}getSortedElements(){let e=Array.from(this.elementListItems,([e,t])=>({element:e,state:t}));switch(this.sortOrder){case`insertionOrder`:return e;case`documentOrder`:return e.sort(this.sortByDocumentPosition);case`visibility`:return e.sort((e,t)=>e.state.isIntersectingWithViewport===t.state.isIntersectingWithViewport?this.sortByDocumentPosition(e,t):e.state.isIntersectingWithViewport?-1:1);default:return this.sortOrder,e}}_recomputeElementsCache(){if(!this._elementsCacheDirty)return;let e=[],t=[];for(let n of this.getSortedElements())n.state.isActive?e.push(n.element):t.push(n.element);this._cachedActiveElements=e,this._cachedInactiveElements=t,this._elementsCacheDirty=!1}get activeElements(){return this._recomputeElementsCache(),this._cachedActiveElements}get inactiveElements(){return this._recomputeElementsCache(),this._cachedInactiveElements}renderElementSection(e,t,r,i,a){return r.length===0?``:n`
1039
1039
  <div class="element-section">
1040
1040
  <h3
1041
1041
  class="section-header ${t} ${i?`collapsed`:``}"
@@ -1043,15 +1043,15 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1043
1043
  >
1044
1044
  ${e} (${r.length})
1045
1045
  </h3>
1046
- ${i?``:l(r,e=>n`
1047
- <single-element
1048
- .element=${e.element}
1049
- .state=${e.state}
1050
- .isExpanded=${this.expandedElementIds.has(e.state.id)}
1051
- .onToggle=${this.handleElementToggle}
1052
- >
1053
- </single-element>
1054
- `)}
1046
+ ${i?``:c(r,e=>this.elementListItems.get(e)?.id??``,e=>{let t=this.elementListItems.get(e);return t?n`
1047
+ <single-element
1048
+ .element=${e}
1049
+ .state=${t}
1050
+ .isExpanded=${this.expandedElementIds.has(t.id)}
1051
+ .onToggle=${this.handleElementToggle}
1052
+ >
1053
+ </single-element>
1054
+ `:``})}
1055
1055
  </div>
1056
1056
  `}render(){return n`
1057
1057
  <tab-header>
@@ -1075,7 +1075,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1075
1075
  ${this.renderElementSection(`Active Elements`,`active`,this.activeElements,this.activeSectionCollapsed,()=>{this.activeSectionCollapsed=!this.activeSectionCollapsed})}
1076
1076
  ${this.renderElementSection(`Inactive Elements`,`inactive`,this.inactiveElements,this.inactiveSectionCollapsed,()=>{this.inactiveSectionCollapsed=!this.inactiveSectionCollapsed})}
1077
1077
  </tab-content>
1078
- `}};_([o(),g(`design:type`,Object)],k.prototype,`hitCount`,void 0),_([o(),g(`design:type`,Array)],k.prototype,`sortDropdown`,void 0),_([o(),g(`design:type`,Object)],k.prototype,`sortOrder`,void 0),_([o(),g(`design:type`,typeof(D=typeof Map<`u`&&Map)==`function`?D:Object)],k.prototype,`elementListItems`,void 0),_([o(),g(`design:type`,String)],k.prototype,`noContentMessage`,void 0),_([o(),g(`design:type`,typeof(O=typeof Set<`u`&&Set)==`function`?O:Object)],k.prototype,`expandedElementIds`,void 0),_([o(),g(`design:type`,Object)],k.prototype,`activeSectionCollapsed`,void 0),_([o(),g(`design:type`,Object)],k.prototype,`inactiveSectionCollapsed`,void 0),k=_([r(`element-tab`),g(`design:paramtypes`,[])],k);let A=class extends e{constructor(...e){super(...e),this.activeTab=`settings`,this.tabs=[`settings`,`elements`,`logs`]}static{this.styles=t`
1078
+ `}};_([o(),g(`design:type`,Array)],k.prototype,`sortDropdown`,void 0),_([o(),g(`design:type`,Object)],k.prototype,`sortOrder`,void 0),_([o(),g(`design:type`,typeof(D=typeof Map<`u`&&Map)==`function`?D:Object)],k.prototype,`elementListItems`,void 0),_([o(),g(`design:type`,String)],k.prototype,`noContentMessage`,void 0),_([o(),g(`design:type`,typeof(O=typeof Set<`u`&&Set)==`function`?O:Object)],k.prototype,`expandedElementIds`,void 0),_([o(),g(`design:type`,Object)],k.prototype,`activeSectionCollapsed`,void 0),_([o(),g(`design:type`,Object)],k.prototype,`inactiveSectionCollapsed`,void 0),k=_([r(`element-tab`),g(`design:paramtypes`,[])],k);let A=class extends e{constructor(...e){super(...e),this.activeTab=`settings`,this.tabs=[`settings`,`elements`,`logs`]}static{this.styles=t`
1079
1079
  .tab-selector-wrapper {
1080
1080
  border-bottom: 2px solid #444;
1081
1081
  margin-top: 12px;
@@ -1118,8 +1118,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1118
1118
  </button>
1119
1119
  `)}
1120
1120
  </div>
1121
- `}};_([i({type:String}),g(`design:type`,Object)],A.prototype,`activeTab`,void 0),A=_([r(`tab-selector`)],A);const j=(e,t)=>{let n={};e.eventListeners.forEach((e,t)=>{n[t]=e.length});let r=[];return e.registeredElements.forEach((e,t)=>{r.push({...e,elementInfo:`${t.id?`#${t.id}`:``}${t.className?`.${t.className.replace(/\s+/g,`.`)}`:``}`})}),{type:`managerDataPayload`,warning:`this is a lot easier to view in the console`,logId:t,globalCallbackHits:e.globalCallbackHits,localizedTimestamp:new Date().toLocaleTimeString(),eventListenerCount:n,managerSettings:e.globalSettings,registeredElements:r,loadedModules:e.loadedModules,summary:`${r.length} elements, ${Object.values(n).flat().length} listeners,
1122
- ${e.globalCallbackHits.total} hits`}},de=(e,t)=>{try{switch(e.type){case`elementRegistered`:return{type:`elementRegistered`,name:e.state.name,id:e.element.id||``,state:e.state,hitslop:e.state.elementBounds.hitSlop,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),meta:e.state.meta,logId:t,summary:e.state.registerCount>1?`${e.state.name} - ${M(e.state.registerCount)} time`:e.state.name};case`elementUnregistered`:return{type:`elementUnregistered`,name:e.state.name,id:e.element.id||``,meta:e.state.meta,state:e.state,wasLastRegisteredElement:e.wasLastRegisteredElement,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:`${e.state.name} - ${e.unregisterReason}`};case`callbackInvoked`:return{type:`callbackInvoked`,name:e.state.name,hitType:e.hitType,state:e.state,meta:e.state.meta,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:`${e.state.name} - ${e.hitType.kind}`};case`callbackCompleted`:{let n=fe(e.state.durationMs||0);return{type:`callbackCompleted`,name:e.state.name,hitType:e.hitType,state:e.state,meta:e.state.meta,wasLastActiveElement:e.wasLastActiveElement,elapsed:n,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,status:e.state.status,errorMessage:e.state.error,summary:`${e.state.name} - ${n}`}}case`mouseTrajectoryUpdate`:return{type:`mouseTrajectoryUpdate`,currentPoint:e.trajectoryPositions?.currentPoint,predictedPoint:e.trajectoryPositions?.predictedPoint,positionCount:e.trajectoryPositions?.positions?.length||0,mousePredictionEnabled:e.predictionEnabled,localizedTimestamp:new Date().toLocaleTimeString(),logId:t,summary:``};case`scrollTrajectoryUpdate`:return{type:`scrollTrajectoryUpdate`,currentPoint:e.currentPoint,predictedPoint:e.predictedPoint,scrollDirection:e.scrollDirection,localizedTimestamp:new Date().toLocaleTimeString(),logId:t,summary:e.scrollDirection};case`managerSettingsChanged`:return{type:`managerSettingsChanged`,globalSettings:e.managerData?.globalSettings||{},settingsChanged:e.updatedSettings,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:e.updatedSettings.map(e=>e.setting).join(`, `)};case`deviceStrategyChanged`:return{type:`deviceStrategyChanged`,oldStrategy:e.oldStrategy,newStrategy:e.newStrategy,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:`${e.oldStrategy} → ${e.newStrategy}`};default:return{type:`serializationError`,error:`Failed to serialize event data`,errorMessage:JSON.stringify(e),localizedTimestamp:new Date().toLocaleTimeString(),logId:t,summary:``}}}catch(e){return{type:`serializationError`,error:`Failed to serialize event data`,localizedTimestamp:new Date().toLocaleTimeString(),errorMessage:e instanceof Error?e.message:String(e),logId:t,summary:``}}},fe=e=>`${(e/1e3).toFixed(4)} s`,M=e=>{let t=e%100;if(t>=11&&t<=13)return`${e}th`;switch(e%10){case 1:return`${e}st`;case 2:return`${e}nd`;case 3:return`${e}rd`;default:return`${e}th`}};let N=class extends x{constructor(...e){super(...e),this.selectedValues=[]}static{this.styles=[...x.styles,t`
1121
+ `}};_([i({type:String}),g(`design:type`,Object)],A.prototype,`activeTab`,void 0),A=_([r(`tab-selector`)],A);let j=class extends x{constructor(...e){super(...e),this.selectedValues=[]}static{this.styles=[...x.styles,t`
1123
1122
  .dropdown-menu button.active::after {
1124
1123
  content: "✓";
1125
1124
  position: absolute;
@@ -1135,7 +1134,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1135
1134
  color: #b0c4de;
1136
1135
  margin-left: 2px;
1137
1136
  }
1138
- `]}_handleOptionClick(e){let t=this.selectedValues.includes(e.value);t?this.selectedValues=this.selectedValues.filter(t=>t!==e.value):this.selectedValues=[...this.selectedValues,e.value];let n=!t;this.onSelectionChange?.(e.value,n)}_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 n`
1137
+ `]}_handleOptionClick(e){let t=this.selectedValues.includes(e.value);t?this.selectedValues=this.selectedValues.filter(t=>t!==e.value):this.selectedValues=[...this.selectedValues,e.value];let n=!t;this.onSelectionChange?.(e.value,n)}_getTriggerIcon(){return p}_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 n`
1139
1138
  <div class="dropdown-container">
1140
1139
  <button
1141
1140
  class="${e}"
@@ -1175,7 +1174,8 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1175
1174
  `)}
1176
1175
  </div>
1177
1176
  </div>
1178
- `}};_([i({type:Array}),g(`design:type`,Array)],N.prototype,`selectedValues`,void 0),_([i(),g(`design:type`,Function)],N.prototype,`onSelectionChange`,void 0),N=_([r(`multi-select-dropdown`)],N);let P=class extends e{static{this.styles=[t`
1177
+ `}};_([i({type:Array}),g(`design:type`,Array)],j.prototype,`selectedValues`,void 0),_([i(),g(`design:type`,Function)],j.prototype,`onSelectionChange`,void 0),j=_([r(`multi-select-dropdown`)],j);const ue=(e,t)=>{let n={};e.eventListeners.forEach((e,t)=>{n[t]=e.length});let r=[];return e.registeredElements.forEach((e,t)=>{r.push({...e,elementInfo:`${t.id?`#${t.id}`:``}${t.className?`.${t.className.replace(/\s+/g,`.`)}`:``}`})}),{type:`managerDataPayload`,warning:`this is a lot easier to view in the console`,logId:t,globalCallbackHits:e.globalCallbackHits,localizedTimestamp:new Date().toLocaleTimeString(),eventListenerCount:n,managerSettings:e.globalSettings,registeredElements:r,loadedModules:e.loadedModules,summary:`${r.length} elements, ${Object.values(n).flat().length} listeners,
1178
+ ${e.globalCallbackHits.total} hits`}},M=(e,t)=>{try{switch(e.type){case`elementRegistered`:return{type:`elementRegistered`,name:e.state.name,id:e.element.id||``,state:e.state,hitslop:e.state.hitSlop,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),meta:e.state.meta,logId:t,summary:e.state.registerCount>1?`${e.state.name} - ${fe(e.state.registerCount)} time`:e.state.name};case`elementUnregistered`:return{type:`elementUnregistered`,name:e.state.name,id:e.element.id||``,meta:e.state.meta,state:e.state,wasLastRegisteredElement:e.wasLastRegisteredElement,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:`${e.state.name} - ${e.unregisterReason}`};case`callbackInvoked`:return{type:`callbackInvoked`,name:e.state.name,hitType:e.hitType,state:e.state,meta:e.state.meta,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:`${e.state.name} - ${e.hitType.kind}`};case`callbackCompleted`:{let n=de(e.state.durationMs||0);return{type:`callbackCompleted`,name:e.state.name,hitType:e.hitType,state:e.state,meta:e.state.meta,wasLastActiveElement:e.wasLastActiveElement,elapsed:n,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,status:e.state.status,errorMessage:e.state.error,summary:`${e.state.name} - ${n}`}}case`mouseTrajectoryUpdate`:return{type:`mouseTrajectoryUpdate`,currentPoint:e.trajectoryPositions?.currentPoint,predictedPoint:e.trajectoryPositions?.predictedPoint,positionCount:e.trajectoryPositions?.positions?.length||0,mousePredictionEnabled:e.predictionEnabled,localizedTimestamp:new Date().toLocaleTimeString(),logId:t,summary:``};case`scrollTrajectoryUpdate`:return{type:`scrollTrajectoryUpdate`,currentPoint:e.currentPoint,predictedPoint:e.predictedPoint,scrollDirection:e.scrollDirection,localizedTimestamp:new Date().toLocaleTimeString(),logId:t,summary:e.scrollDirection};case`managerSettingsChanged`:return{type:`managerSettingsChanged`,globalSettings:e.managerData?.globalSettings||{},settingsChanged:e.updatedSettings,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:e.updatedSettings.map(e=>e.setting).join(`, `)};case`deviceStrategyChanged`:return{type:`deviceStrategyChanged`,oldStrategy:e.oldStrategy,newStrategy:e.newStrategy,localizedTimestamp:new Date(e.timestamp).toLocaleTimeString(),logId:t,summary:`${e.oldStrategy} → ${e.newStrategy}`};default:return{type:`serializationError`,error:`Failed to serialize event data`,errorMessage:JSON.stringify(e),localizedTimestamp:new Date().toLocaleTimeString(),logId:t,summary:``}}}catch(e){return{type:`serializationError`,error:`Failed to serialize event data`,localizedTimestamp:new Date().toLocaleTimeString(),errorMessage:e instanceof Error?e.message:String(e),logId:t,summary:``}}},de=e=>`${(e/1e3).toFixed(4)} s`,fe=e=>{let t=e%100;if(t>=11&&t<=13)return`${e}th`;switch(e%10){case 1:return`${e}st`;case 2:return`${e}nd`;case 3:return`${e}rd`;default:return`${e}th`}},N={elementRegistered:`#2196f3`,callbackInvoked:`#00bcd4`,callbackCompleted:`#4caf50`,elementUnregistered:`#ff9800`,managerSettingsChanged:`#f44336`,mouseTrajectoryUpdate:`#78909c`,scrollTrajectoryUpdate:`#607d8b`,deviceStrategyChanged:`#9c27b0`};var pe=class{constructor(){this.logs=[],this.logIdCounter=0,this.changeListeners=new Set,this.managerListeners=new Map,this.isAttached=!1;let{logging:{logLocation:e,...t}}=$.instance.devtoolsSettings;this.logLocation=e,this.eventsEnabled=t}attach(){if(!this.isAttached){this.isAttached=!0;for(let[e,t]of Object.entries(this.eventsEnabled))t&&this.addManagerListener(e)}}detach(){this.managerListeners.forEach((e,t)=>{s.instance.removeEventListener(t,e)}),this.managerListeners.clear(),this.isAttached=!1}subscribe(e){return this.changeListeners.add(e),()=>this.changeListeners.delete(e)}setLogLocation(e){this.logLocation=e,this.notify()}setEventEnabled(e,t){this.eventsEnabled={...this.eventsEnabled,[e]:t},this.isAttached&&(t?this.addManagerListener(e):this.removeManagerListener(e)),this.notify()}clear(){this.logs=[],this.notify()}logManagerData(){this.logLocation!==`none`&&((this.logLocation===`console`||this.logLocation===`both`)&&console.log(s.instance.getManagerData),(this.logLocation===`controlPanel`||this.logLocation===`both`)&&this.addLog(ue(s.instance.getManagerData,(++this.logIdCounter).toString())))}addManagerListener(e){if(this.managerListeners.has(e))return;let t=t=>{this.handleEvent(e,t)};this.managerListeners.set(e,t),s.instance.addEventListener(e,t)}removeManagerListener(e){let t=this.managerListeners.get(e);t&&(s.instance.removeEventListener(e,t),this.managerListeners.delete(e))}handleEvent(e,t){if(this.logLocation!==`none`){if(this.logLocation===`console`||this.logLocation===`both`){let n=N[e]||`#ffffff`;console.log(`%c[ForesightJS] ${e}`,`color: ${n}; font-weight: bold;`,t)}if(this.logLocation===`controlPanel`||this.logLocation===`both`){let e=M(t,(++this.logIdCounter).toString());if(e.type===`serializationError`){console.error(e.error,e.errorMessage);return}this.addLog(e)}}}addLog(e){this.logs.unshift(e),this.logs.length>100&&this.logs.pop(),this.notify()}notify(){for(let e of this.changeListeners)e()}};let me=null;const P=()=>me??=new pe;let F=class extends e{static{this.styles=[t`
1179
1179
  :host {
1180
1180
  display: block;
1181
1181
  /*
@@ -1239,7 +1239,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1239
1239
  * as all styling is now handled by setting CSS variables below.
1240
1240
  * This makes the component's styling more self-contained.
1241
1241
  */
1242
- `]}constructor(e){super(),this.isExpanded=!1,this.log=e}updated(e){if(e.has(`log`)&&this.log){let e=this.log,t=e.type===`callbackCompleted`&&`status`in e&&e.status===`error`,n=t?`#f44336`:this.getLogTypeColor(e.type),r=t?`rgba(244, 67, 54, 0.1)`:`transparent`;this.style.setProperty(`--log-color`,n),this.style.setProperty(`--log-background-color`,r)}}serializeLogDataWithoutSummary(e){let{summary:t,...n}=e;return JSON.stringify(n,null,2)}getLogTypeColor(e){return{elementRegistered:`#2196f3`,callbackInvoked:`#00bcd4`,callbackCompleted:`#4caf50`,elementUnregistered:`#ff9800`,managerSettingsChanged:`#f44336`,mouseTrajectoryUpdate:`#78909c`,scrollTrajectoryUpdate:`#607d8b`,deviceStrategyChanged:`#9c27b0`}[e]||`#555`}getEventDisplayName(e){return{elementRegistered:`Registered`,elementUnregistered:`Unregistered`,callbackInvoked:`Invoked`,callbackCompleted:`Completed`,mouseTrajectoryUpdate:`Mouse`,scrollTrajectoryUpdate:`Scroll`,managerSettingsChanged:`Settings`,managerDataPayload:`ManagerData`,deviceStrategyChanged:`Strategy`}[e]||e}truncateLogSummary(e,t=50){return e.length<=t?e:e.substring(0,t)+`...`}render(){let e=this.log;return n`
1242
+ `]}constructor(e){super(),this.isExpanded=!1,this.log=e}updated(e){if(e.has(`log`)&&this.log){let e=this.log,t=e.type===`callbackCompleted`&&`status`in e&&e.status===`error`,n=t?`#f44336`:this.getLogTypeColor(e.type),r=t?`rgba(244, 67, 54, 0.1)`:`transparent`;this.style.setProperty(`--log-color`,n),this.style.setProperty(`--log-background-color`,r)}}serializeLogDataWithoutSummary(e){let{summary:t,...n}=e;return JSON.stringify(n,null,2)}getLogTypeColor(e){return N[e]||`#555`}getEventDisplayName(e){return{elementRegistered:`Registered`,elementUnregistered:`Unregistered`,callbackInvoked:`Invoked`,callbackCompleted:`Completed`,mouseTrajectoryUpdate:`Mouse`,scrollTrajectoryUpdate:`Scroll`,managerSettingsChanged:`Settings`,managerDataPayload:`ManagerData`,deviceStrategyChanged:`Strategy`}[e]||e}truncateLogSummary(e,t=50){return e.length<=t?e:e.substring(0,t)+`...`}render(){let e=this.log;return n`
1243
1243
  <expandable-item
1244
1244
  .borderColor=${e.type===`callbackCompleted`&&`status`in e&&e.status===`error`?`#f44336`:this.getLogTypeColor(e.type)}
1245
1245
  .itemId=${e.logId}
@@ -1255,7 +1255,7 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1255
1255
  </div>
1256
1256
  <div slot="details">${this.serializeLogDataWithoutSummary(e)}</div>
1257
1257
  </expandable-item>
1258
- `}};_([i({attribute:!1}),g(`design:type`,Object)],P.prototype,`log`,void 0),_([i({type:Boolean}),g(`design:type`,Boolean)],P.prototype,`isExpanded`,void 0),_([i(),g(`design:type`,Object)],P.prototype,`onToggle`,void 0),P=_([r(`single-log`),g(`design:paramtypes`,[Object])],P);var F,I;let L=class extends e{static{this.styles=[t`
1258
+ `}};_([i({attribute:!1}),g(`design:type`,Object)],F.prototype,`log`,void 0),_([i({type:Boolean}),g(`design:type`,Boolean)],F.prototype,`isExpanded`,void 0),_([i(),g(`design:type`,Object)],F.prototype,`onToggle`,void 0),F=_([r(`single-log`),g(`design:paramtypes`,[Object])],F);var I;let L=class extends e{static{this.styles=[t`
1259
1259
  :host {
1260
1260
  display: flex;
1261
1261
  flex-direction: column;
@@ -1348,11 +1348,11 @@ import{LitElement as e,css as t,html as n}from"lit";import{customElement as r,pr
1348
1348
  .warning-container:hover svg {
1349
1349
  stroke: #ffdc3e;
1350
1350
  }
1351
- `]}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}}=$.instance.devtoolsSettings;this.eventsEnabled=t,this.logLocation=e,this.logDropdown=[{value:`controlPanel`,label:`Control Panel`,title:`Log only to the control panel`,icon:ee},{value:`console`,label:`Console`,title:`Log only to the console`,icon:te},{value:`both`,label:`Both`,title:`Log to both the control panel and the console`,icon:f},{value:`none`,label:`None`,title:`Dont log anywhere`,icon:d}],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:`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},{value:`deviceStrategyChanged`,label:`Strategy Changed`,title:`Show strategy change events`,icon:m}]}getSelectedEventFilters(){return Object.entries(this.eventsEnabled).filter(([,e])=>e).map(([e])=>e)}shouldShowPerformanceWarning(){let e=this.logLocation===`console`||this.logLocation===`both`,t=this.eventsEnabled.mouseTrajectoryUpdate||this.eventsEnabled.scrollTrajectoryUpdate;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=t=>{this.handleEvent(e,t)};this._eventListeners.set(e,t),c.instance.addEventListener(e,t,{signal:this._abortController?.signal})}removeForesightEventListener(e){let t=this._eventListeners.get(e);t&&(c.instance.removeEventListener(e,t),this._eventListeners.delete(e))}removeAllEventListeners(){this._eventListeners.forEach((e,t)=>{c.instance.removeEventListener(t,e)}),this._eventListeners.clear()}getEventColor(e){return{elementRegistered:`#2196f3`,callbackInvoked:`#00bcd4`,callbackCompleted:`#4caf50`,elementUnregistered:`#ff9800`,managerSettingsChanged:`#f44336`,mouseTrajectoryUpdate:`#78909c`,scrollTrajectoryUpdate:`#607d8b`,deviceStrategyChanged:`#9c27b0`}[e]||`#ffffff`}handleEvent(e,t){if(this.logLocation!==`none`){if(this.logLocation===`console`||this.logLocation===`both`){let n=this.getEventColor(e);console.log(`%c[ForesightJS] ${e}`,`color: ${n}; font-weight: bold;`,t)}(this.logLocation===`controlPanel`||this.logLocation===`both`)&&this.addEventLog(t)}}addLog(e){this.logs.unshift(e),this.logs.length>this.MAX_LOGS&&this.logs.pop(),this.requestUpdate()}logManagerData(){this.logLocation!==`none`&&((this.logLocation===`console`||this.logLocation===`both`)&&console.log(c.instance.getManagerData),(this.logLocation===`controlPanel`||this.logLocation===`both`)&&this.addManagerLog())}addManagerLog(){let e=j(c.instance.getManagerData,(++this.logIdCounter).toString());this.addLog(e)}addEventLog(e){let t=de(e,(++this.logIdCounter).toString());if(t.type===`serializationError`){console.error(t.error,t.errorMessage);return}this.addLog(t)}render(){return n`
1351
+ `]}constructor(){super(),this.store=P(),this.expandedLogIds=new Set,this.noContentMessage=`No logs available`,this._unsubscribeStore=null,this.handleLogLocationChange=e=>{this.store.setLogLocation(e)},this.handleFilterChange=(e,t)=>{this.store.setEventEnabled(e,t)},this.handleLogToggle=e=>{let t=new Set(this.expandedLogIds);t.has(e)?t.delete(e):t.add(e),this.expandedLogIds=t},this.logManagerData=()=>{this.store.logManagerData()},this.logDropdown=[{value:`controlPanel`,label:`Control Panel`,title:`Log only to the control panel`,icon:u},{value:`console`,label:`Console`,title:`Log only to the console`,icon:d},{value:`both`,label:`Both`,title:`Log to both the control panel and the console`,icon:te},{value:`none`,label:`None`,title:`Dont log anywhere`,icon:ee}],this.filterDropdown=[{value:`elementRegistered`,label:`Element Registered`,title:`Show element registration events`,icon:p},{value:`elementUnregistered`,label:`Element Unregistered`,title:`Show element unregistration events`,icon:p},{value:`callbackInvoked`,label:`Callback Invoked`,title:`Show callback invoked events`,icon:p},{value:`callbackCompleted`,label:`Callback Completed`,title:`Show callback completed events`,icon:p},{value:`mouseTrajectoryUpdate`,label:`Mouse Trajectory Update`,title:`Show mouse trajectory update events`,icon:p},{value:`scrollTrajectoryUpdate`,label:`Scroll Trajectory Update`,title:`Show scroll trajectory update events`,icon:p},{value:`managerSettingsChanged`,label:`Manager Settings Changed`,title:`Show manager settings change events`,icon:p},{value:`deviceStrategyChanged`,label:`Strategy Changed`,title:`Show strategy change events`,icon:p}]}getSelectedEventFilters(){return Object.entries(this.store.eventsEnabled).filter(([,e])=>e).map(([e])=>e)}shouldShowPerformanceWarning(){let{logLocation:e,eventsEnabled:t}=this.store,n=e===`console`||e===`both`,r=t.mouseTrajectoryUpdate||t.scrollTrajectoryUpdate;return n&&r}getNoLogsMessage(){return Object.values(this.store.eventsEnabled).filter(Boolean).length===0?`Logging for all events is turned off`:this.store.logLocation===`console`?`No logs to display. Logging location is set to console - check browser console for events.`:this.store.logLocation===`none`?`No logs to display. Logging location is set to none`:`Interact with Foresight to generate events.`}clearLogs(){this.store.clear(),this.expandedLogIds.clear(),this.noContentMessage=`Logs cleared`}connectedCallback(){super.connectedCallback(),this._unsubscribeStore=this.store.subscribe(()=>this.requestUpdate())}disconnectedCallback(){super.disconnectedCallback(),this._unsubscribeStore?.(),this._unsubscribeStore=null}render(){let e=this.store.logs;return n`
1352
1352
  <tab-header>
1353
1353
  <div slot="chips" class="chips-container">
1354
- <chip-element title="Number of logged events (Max ${this.MAX_LOGS})">
1355
- ${this.logs.length} events
1354
+ <chip-element title="Number of logged events (Max ${100})">
1355
+ ${e.length} events
1356
1356
  </chip-element>
1357
1357
  </div>
1358
1358
  <div slot="actions">
@@ -1367,7 +1367,7 @@ Consider using 'Control Panel' only for better performance."
1367
1367
  `:``}
1368
1368
  <single-select-dropdown
1369
1369
  .dropdownOptions="${this.logDropdown}"
1370
- .selectedOptionValue="${this.logLocation}"
1370
+ .selectedOptionValue="${this.store.logLocation}"
1371
1371
  .onSelectionChange="${this.handleLogLocationChange}"
1372
1372
  ></single-select-dropdown>
1373
1373
 
@@ -1386,15 +1386,15 @@ Consider using 'Control Panel' only for better performance."
1386
1386
  <button
1387
1387
  class="single-button"
1388
1388
  title="Clear all logs"
1389
- ?disabled="${this.logs.length===0}"
1389
+ ?disabled="${e.length===0}"
1390
1390
  @click="${this.clearLogs}"
1391
1391
  >
1392
- ${h}
1392
+ ${ie}
1393
1393
  </button>
1394
1394
  </div>
1395
1395
  </tab-header>
1396
- <tab-content .noContentMessage=${this.noContentMessage} .hasContent=${!!this.logs.length}>
1397
- ${this.logs.length===0?n`<div class="no-items">${this.getNoLogsMessage()}</div>`:l(this.logs,e=>n`
1396
+ <tab-content .noContentMessage=${this.noContentMessage} .hasContent=${!!e.length}>
1397
+ ${e.length===0?n`<div class="no-items">${this.getNoLogsMessage()}</div>`:c(e,e=>e.logId,e=>n`
1398
1398
  <single-log
1399
1399
  .log=${e}
1400
1400
  .isExpanded=${this.expandedLogIds.has(e.logId)}
@@ -1402,7 +1402,7 @@ Consider using 'Control Panel' only for better performance."
1402
1402
  ></single-log>
1403
1403
  `)}
1404
1404
  </tab-content>
1405
- `}};_([o(),g(`design:type`,Array)],L.prototype,`logDropdown`,void 0),_([o(),g(`design:type`,Array)],L.prototype,`filterDropdown`,void 0),_([o(),g(`design:type`,Object)],L.prototype,`logLocation`,void 0),_([o(),g(`design:type`,Object)],L.prototype,`eventsEnabled`,void 0),_([o(),g(`design:type`,typeof(F=typeof Array<`u`&&Array)==`function`?F:Object)],L.prototype,`logs`,void 0),_([o(),g(`design:type`,typeof(I=typeof Set<`u`&&Set)==`function`?I:Object)],L.prototype,`expandedLogIds`,void 0),_([i(),g(`design:type`,String)],L.prototype,`noContentMessage`,void 0),L=_([r(`log-tab`),g(`design:paramtypes`,[])],L);const R=`points`;let z=class extends e{constructor(...e){super(...e),this.header=``,this.description=``}static{this.styles=[t`
1405
+ `}};_([o(),g(`design:type`,Array)],L.prototype,`logDropdown`,void 0),_([o(),g(`design:type`,Array)],L.prototype,`filterDropdown`,void 0),_([o(),g(`design:type`,typeof(I=typeof Set<`u`&&Set)==`function`?I:Object)],L.prototype,`expandedLogIds`,void 0),_([i(),g(`design:type`,String)],L.prototype,`noContentMessage`,void 0),L=_([r(`log-tab`),g(`design:paramtypes`,[])],L);const R=`points`;let z=class extends e{constructor(...e){super(...e),this.header=``,this.description=``}static{this.styles=[t`
1406
1406
  .setting-item {
1407
1407
  display: flex;
1408
1408
  align-items: center;
@@ -1492,7 +1492,7 @@ Consider using 'Control Panel' only for better performance."
1492
1492
  input[type="checkbox"]:hover {
1493
1493
  box-shadow: 0 0 0 3px rgba(176, 196, 222, 0.1);
1494
1494
  }
1495
- `]}handleCheckboxChange(e){let t=e.target;if(t instanceof HTMLInputElement){let e=t.checked;String(this.setting).startsWith(`show.`)?this.dispatchEvent(new CustomEvent(`setting-changed`,{detail:{setting:this.setting,value:e},bubbles:!0})):c.instance.alterGlobalSettings({[this.setting]:e})}}render(){return n`<setting-item header=${this.header} description=${this.description}>
1495
+ `]}handleCheckboxChange(e){let t=e.target;if(t instanceof HTMLInputElement){let e=t.checked;String(this.setting).startsWith(`show.`)?this.dispatchEvent(new CustomEvent(`setting-changed`,{detail:{setting:this.setting,value:e},bubbles:!0})):s.instance.alterGlobalSettings({[this.setting]:e})}}render(){return n`<setting-item header=${this.header} description=${this.description}>
1496
1496
  <input
1497
1497
  slot="controls"
1498
1498
  type="checkbox"
@@ -1568,7 +1568,7 @@ Consider using 'Control Panel' only for better performance."
1568
1568
  transform: scale(1.1);
1569
1569
  box-shadow: 0 0 0 4px rgba(176, 196, 222, 0.2);
1570
1570
  }
1571
- `]}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 e=parseInt(t.value,10);this.displayValue=e,c.instance.alterGlobalSettings({[this.setting]:e})}}willUpdate(e){super.willUpdate(e),e.has(`currentValue`)&&(this.displayValue=this.currentValue)}render(){return n`<setting-item header=${this.header} description=${this.description}>
1571
+ `]}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 e=parseInt(t.value,10);this.displayValue=e,s.instance.alterGlobalSettings({[this.setting]:e})}}willUpdate(e){super.willUpdate(e),e.has(`currentValue`)&&(this.displayValue=this.currentValue)}render(){return n`<setting-item header=${this.header} description=${this.description}>
1572
1572
  <div slot="controls" class="range-wrapper">
1573
1573
  <input
1574
1574
  slot="controls"
@@ -1613,7 +1613,7 @@ Consider using 'Control Panel' only for better performance."
1613
1613
  border-bottom: 1px solid rgba(176, 196, 222, 0.2);
1614
1614
  padding-bottom: 8px;
1615
1615
  }
1616
- `}constructor(){super(),this.changedSettings=[],this.currentCorner=`bottom-right`,this.touchDeviceStrategyOptions=[{value:`onTouchStart`,label:`On Touch Start`,title:`Execute callbacks when user touches registered elements`,icon:n`<span>Touch</span>`},{value:`viewport`,label:`Viewport Entry`,title:`Execute callbacks when registered elements enter the viewport`,icon:n`<span>Viewport</span>`},{value:`none`,label:`None`,title:`Disable touch device prediction`,icon:n`<span>None</span>`}],this.minimumConnectionTypeOptions=[{value:`slow-2g`,label:`Slow 2G`,title:`Slow 2G`,icon:n`<span>Slow 2G</span>`},{value:`2g`,label:`2G`,title:`2G`,icon:n`<span>2G</span>`},{value:`3g`,label:`3G`,title:`3G`,icon:n`<span>3G</span>`},{value:`4g`,label:`4G`,title:`4G`,icon:n`<span>4G</span>`}],this.cornerOptions=[{value:`top-left`,label:`Top Left`,title:`Position control panel in top-left corner`,icon:n`<span>↖</span>`},{value:`top-right`,label:`Top Right`,title:`Position control panel in top-right corner`,icon:n`<span>↗</span>`},{value:`bottom-left`,label:`Bottom Left`,title:`Position control panel in bottom-left corner`,icon:n`<span>↙</span>`},{value:`bottom-right`,label:`Bottom Right`,title:`Position control panel in bottom-right corner`,icon:n`<span>↘</span>`}],this._abortController=null,this._handleTouchDeviceStrategyChange=e=>{c.instance.alterGlobalSettings({touchDeviceStrategy:e})},this._handleMinimumConnectionTypeChange=e=>{c.instance.alterGlobalSettings({minimumConnectionType:e})},this._handleCornerChange=e=>{this.currentCorner=e,this.dispatchEvent(new CustomEvent(`corner-change`,{detail:{corner:e},bubbles:!0,composed:!0}))};let e=$.instance.devtoolsSettings,t=c.instance.getManagerData.globalSettings;this.devtoolsSettings={...e,show:{...e.show}},this.managerSettings=Object.assign({},t),this.currentCorner=this.getCurrentCorner(),this.initialSettings={devtools:{...e,show:{...e.show}},manager:Object.assign({},t)}}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;c.instance.addEventListener(`managerSettingsChanged`,e=>{this.managerSettings=e.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){for(let t of[`enableMousePrediction`,`enableTabPrediction`,`enableScrollPrediction`,`trajectoryPredictionTime`,`positionHistorySize`,`tabOffset`,`scrollMargin`,`touchDeviceStrategy`,`minimumConnectionType`]){let n=this.initialSettings.manager[t],r=this.managerSettings[t];n!==r&&e.push({setting:t,oldValue:n,newValue:r})}}_checkDevtoolsSettingsChanges(e){for(let t of u){let n=this.initialSettings.devtools.show[t],r=this.devtoolsSettings.show[t];n!==r&&e.push({setting:`show.${t}`,oldValue:n,newValue:r})}}_handleDevtoolsSettingChange(e){let{setting:t,value:n}=e.detail;if(!t.startsWith(`show.`))return;let r=t.slice(5);u.includes(r)&&(this.devtoolsSettings={...this.devtoolsSettings,show:{...this.devtoolsSettings.show,[r]:n}},$.instance.alterDevtoolsSettings({show:{[r]:n}}),this._updateChangedSettings())}getCurrentCorner(){try{let e=localStorage.getItem(`foresight-devtools-control-panel-corner`);if(e&&[`top-left`,`top-right`,`bottom-left`,`bottom-right`].includes(e))return e}catch(e){console.warn(`ForesightDevtools: Failed to load corner from localStorage:`,e)}return`bottom-right`}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,touchDeviceStrategy:e.touchDeviceStrategy,minimumConnectionType:e.minimumConnectionType};return`ForesightManager.initialize(${JSON.stringify(t,null,2)})`}render(){if(!this.managerSettings||!this.devtoolsSettings)return n`<tab-content
1616
+ `}constructor(){super(),this.changedSettings=[],this.currentCorner=`bottom-right`,this.touchDeviceStrategyOptions=[{value:`onTouchStart`,label:`On Touch Start`,title:`Execute callbacks when user touches registered elements`,icon:n`<span>Touch</span>`},{value:`viewport`,label:`Viewport Entry`,title:`Execute callbacks when registered elements enter the viewport`,icon:n`<span>Viewport</span>`},{value:`none`,label:`None`,title:`Disable touch device prediction`,icon:n`<span>None</span>`}],this.minimumConnectionTypeOptions=[{value:`slow-2g`,label:`Slow 2G`,title:`Slow 2G`,icon:n`<span>Slow 2G</span>`},{value:`2g`,label:`2G`,title:`2G`,icon:n`<span>2G</span>`},{value:`3g`,label:`3G`,title:`3G`,icon:n`<span>3G</span>`},{value:`4g`,label:`4G`,title:`4G`,icon:n`<span>4G</span>`}],this.cornerOptions=[{value:`top-left`,label:`Top Left`,title:`Position control panel in top-left corner`,icon:n`<span>↖</span>`},{value:`top-right`,label:`Top Right`,title:`Position control panel in top-right corner`,icon:n`<span>↗</span>`},{value:`bottom-left`,label:`Bottom Left`,title:`Position control panel in bottom-left corner`,icon:n`<span>↙</span>`},{value:`bottom-right`,label:`Bottom Right`,title:`Position control panel in bottom-right corner`,icon:n`<span>↘</span>`}],this._abortController=null,this._handleTouchDeviceStrategyChange=e=>{s.instance.alterGlobalSettings({touchDeviceStrategy:e})},this._handleMinimumConnectionTypeChange=e=>{s.instance.alterGlobalSettings({minimumConnectionType:e})},this._handleCornerChange=e=>{this.currentCorner=e,this.dispatchEvent(new CustomEvent(`corner-change`,{detail:{corner:e},bubbles:!0,composed:!0}))};let e=$.instance.devtoolsSettings,t=s.instance.getManagerData.globalSettings;this.devtoolsSettings={...e,show:{...e.show}},this.managerSettings=Object.assign({},t),this.currentCorner=this.getCurrentCorner(),this.initialSettings={devtools:{...e,show:{...e.show}},manager:Object.assign({},t)}}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;s.instance.addEventListener(`managerSettingsChanged`,e=>{this.managerSettings=e.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){for(let t of[`enableMousePrediction`,`enableTabPrediction`,`enableScrollPrediction`,`trajectoryPredictionTime`,`positionHistorySize`,`tabOffset`,`scrollMargin`,`touchDeviceStrategy`,`minimumConnectionType`]){let n=this.initialSettings.manager[t],r=this.managerSettings[t];n!==r&&e.push({setting:t,oldValue:n,newValue:r})}}_checkDevtoolsSettingsChanges(e){for(let t of l){let n=this.initialSettings.devtools.show[t],r=this.devtoolsSettings.show[t];n!==r&&e.push({setting:`show.${t}`,oldValue:n,newValue:r})}}_handleDevtoolsSettingChange(e){let{setting:t,value:n}=e.detail;if(!t.startsWith(`show.`))return;let r=t.slice(5);l.includes(r)&&(this.devtoolsSettings={...this.devtoolsSettings,show:{...this.devtoolsSettings.show,[r]:n}},$.instance.alterDevtoolsSettings({show:{[r]:n}}),this._updateChangedSettings())}getCurrentCorner(){try{let e=localStorage.getItem(`foresight-devtools-control-panel-corner`);if(e&&[`top-left`,`top-right`,`bottom-left`,`bottom-right`].includes(e))return e}catch(e){console.warn(`ForesightDevtools: Failed to load corner from localStorage:`,e)}return`bottom-right`}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,touchDeviceStrategy:e.touchDeviceStrategy,minimumConnectionType:e.minimumConnectionType};return`ForesightManager.initialize(${JSON.stringify(t,null,2)})`}render(){if(!this.managerSettings||!this.devtoolsSettings)return n`<tab-content
1617
1617
  .noContentMessage=${`Loading settings...`}
1618
1618
  .hasContent=${!1}
1619
1619
  ></tab-content>`;let e=this.managerSettings;return n`
@@ -1855,20 +1855,12 @@ Click on the copy icon to easely copy the new setting into your project
1855
1855
  overflow: hidden;
1856
1856
  }
1857
1857
 
1858
- .tab-container.hidden {
1859
- display: none;
1860
- }
1861
-
1862
1858
  .tab-content {
1863
1859
  flex: 1;
1864
1860
  position: relative;
1865
1861
  }
1866
1862
 
1867
1863
  .tab-content > * {
1868
- display: none;
1869
- }
1870
-
1871
- .tab-content > .active {
1872
1864
  display: flex;
1873
1865
  position: absolute;
1874
1866
  top: 0;
@@ -1920,7 +1912,7 @@ Click on the copy icon to easely copy the new setting into your project
1920
1912
  .dismiss-button:hover {
1921
1913
  opacity: 0.7;
1922
1914
  }
1923
- `}constructor(){super(),this.isMinimized=$.instance.devtoolsSettings.isControlPanelDefaultMinimized,this.isTouchDevice=!1,this.isWarningDismissed=!1,this.corner=`bottom-right`,this.localStorageSelectedTabKey=`foresight-devtools-control-panel-tab`,this.localStorageCornerKey=`foresight-devtools-control-panel-corner`,this._abortController=null,this.activeTab=this.getStoredTab(),this.corner=this.getStoredCorner(),this.isTouchDevice=c.instance.getManagerData.currentDeviceStrategy===`touch`}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;c.instance.addEventListener(`deviceStrategyChanged`,e=>{this.isTouchDevice=e.newStrategy===`touch`,e.newStrategy===`touch`&&(this.isWarningDismissed=!1)},{signal:e}),this.addEventListener(`corner-change`,(e=>{this.setCorner(e.detail.corner)}),{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}getStoredTab(){try{return localStorage.getItem(this.localStorageSelectedTabKey)||`logs`}catch(e){return console.error(e),`logs`}}getStoredCorner(){try{let e=localStorage.getItem(this.localStorageCornerKey);if(e)return e}catch(e){console.error(`ForesightDevtools: Failed to load corner from localStorage:`,e)}return`bottom-right`}_handleTabChange(e){this.activeTab=e.detail.tab,this.setStoredTab(this.activeTab)}setStoredTab(e){try{localStorage.setItem(this.localStorageSelectedTabKey,e)}catch(e){console.warn(`ForesightDevtools: Failed to save tab preference to localStorage:`,e)}}setStoredCorner(e){try{localStorage.setItem(this.localStorageCornerKey,e)}catch(e){console.warn(`ForesightDevtools: Failed to save corner to localStorage:`,e)}}dismissWarning(){this.isWarningDismissed=!0}setCorner(e){this.corner=e,this.setStoredCorner(this.corner),this.requestUpdate()}handleMinimizeClick(e){e.stopPropagation(),this.isMinimized=!this.isMinimized}getMinimizeSymbol(){return this.isMinimized?`+`:`−`}render(){return n`
1915
+ `}constructor(){super(),this.isMinimized=$.instance.devtoolsSettings.isControlPanelDefaultMinimized,this.isTouchDevice=!1,this.isWarningDismissed=!1,this.corner=`bottom-right`,this.localStorageSelectedTabKey=`foresight-devtools-control-panel-tab`,this.localStorageCornerKey=`foresight-devtools-control-panel-corner`,this._abortController=null,this.activeTab=this.getStoredTab(),this.corner=this.getStoredCorner(),this.isTouchDevice=s.instance.getManagerData.currentDeviceStrategy===`touch`}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;P().attach(),s.instance.addEventListener(`deviceStrategyChanged`,e=>{this.isTouchDevice=e.newStrategy===`touch`,e.newStrategy===`touch`&&(this.isWarningDismissed=!1)},{signal:e}),this.addEventListener(`corner-change`,(e=>{this.setCorner(e.detail.corner)}),{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null,P().detach()}getStoredTab(){try{return localStorage.getItem(this.localStorageSelectedTabKey)||`logs`}catch(e){return console.error(e),`logs`}}getStoredCorner(){try{let e=localStorage.getItem(this.localStorageCornerKey);if(e)return e}catch(e){console.error(`ForesightDevtools: Failed to load corner from localStorage:`,e)}return`bottom-right`}_handleTabChange(e){this.activeTab=e.detail.tab,this.setStoredTab(this.activeTab)}setStoredTab(e){try{localStorage.setItem(this.localStorageSelectedTabKey,e)}catch(e){console.warn(`ForesightDevtools: Failed to save tab preference to localStorage:`,e)}}setStoredCorner(e){try{localStorage.setItem(this.localStorageCornerKey,e)}catch(e){console.warn(`ForesightDevtools: Failed to save corner to localStorage:`,e)}}dismissWarning(){this.isWarningDismissed=!0}setCorner(e){this.corner=e,this.setStoredCorner(this.corner),this.requestUpdate()}handleMinimizeClick(e){e.stopPropagation(),this.isMinimized=!this.isMinimized}getMinimizeSymbol(){return this.isMinimized?`+`:`−`}renderActiveTab(){switch(this.activeTab){case`elements`:return n`<element-tab></element-tab>`;case`settings`:return n`<settings-tab></settings-tab>`;default:return n`<log-tab></log-tab>`}}render(){return n`
1924
1916
  <div class="control-wrapper ${this.corner} ${this.isMinimized?`minimized`:``}">
1925
1917
  <div class="title-wrapper">
1926
1918
  <button @click="${this.handleMinimizeClick}" class="minimize-button">
@@ -1942,28 +1934,28 @@ Click on the copy icon to easely copy the new setting into your project
1942
1934
  </button>
1943
1935
  </div>
1944
1936
 
1945
- <div class="tab-container ${this.isMinimized?`hidden`:``}">
1946
- <tab-selector
1947
- .activeTab="${this.activeTab}"
1948
- @tab-change="${this._handleTabChange}"
1949
- ></tab-selector>
1950
-
1951
- <div class="tab-content">
1952
- <log-tab class=${s({active:this.activeTab===`logs`})}></log-tab>
1953
- <element-tab class=${s({active:this.activeTab===`elements`})}></element-tab>
1954
- <settings-tab
1955
- class=${s({active:this.activeTab===`settings`})}
1956
- ></settings-tab>
1957
- </div>
1958
- </div>
1937
+ ${this.isMinimized?``:n`
1938
+ <div class="tab-container">
1939
+ <tab-selector
1940
+ .activeTab="${this.activeTab}"
1941
+ @tab-change="${this._handleTabChange}"
1942
+ ></tab-selector>
1943
+
1944
+ <div class="tab-content">${this.renderActiveTab()}</div>
1945
+ </div>
1946
+ `}
1959
1947
  </div>
1960
1948
  `}};_([o(),g(`design:type`,Object)],W.prototype,`activeTab`,void 0),_([o(),g(`design:type`,Boolean)],W.prototype,`isMinimized`,void 0),_([o(),g(`design:type`,Boolean)],W.prototype,`isTouchDevice`,void 0),_([o(),g(`design:type`,Boolean)],W.prototype,`isWarningDismissed`,void 0),_([o(),g(`design:type`,String)],W.prototype,`corner`,void 0),W=_([r(`control-panel`),g(`design:paramtypes`,[])],W);var G,K,q;let J=class extends e{constructor(...e){super(...e),this.overlayMap=new Map,this.callbackAnimations=new Map,this._elementSubscriptions=new Map,this.showNameTags=!0,this._abortController=null}static{this.styles=[t`
1949
+ /* Anchored to the document origin (initial containing block), not the
1950
+ viewport: overlays are placed in document coordinates so the compositor
1951
+ moves them together with the page content during scroll, instead of
1952
+ JS chasing the scroll position a frame behind. */
1961
1953
  :host {
1962
- position: fixed;
1954
+ position: absolute;
1963
1955
  top: 0;
1964
1956
  left: 0;
1965
- width: 100%;
1966
- height: 100%;
1957
+ width: 0;
1958
+ height: 0;
1967
1959
  pointer-events: none;
1968
1960
  z-index: 9999;
1969
1961
  }
@@ -2058,7 +2050,7 @@ Click on the copy icon to easely copy the new setting into your project
2058
2050
  white-space: nowrap;
2059
2051
  pointer-events: none;
2060
2052
  }
2061
- `]}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;c.instance.addEventListener(`elementRegistered`,e=>{this._subscribeToElement(e.element),e.state.isIntersectingWithViewport&&this.createOrUpdateElementOverlay(e.element,e.state)},{signal:e}),c.instance.addEventListener(`elementUnregistered`,e=>{this._unsubscribeFromElement(e.element),this.removeElementOverlay(e.element)},{signal:e});for(let[e,t]of c.instance.registeredElements)this._subscribeToElement(e),t.isIntersectingWithViewport&&t.isActive&&this.createOrUpdateElementOverlay(e,t);c.instance.addEventListener(`callbackInvoked`,e=>{this.highlightElementCallback(e.element,e.hitType)},{signal:e}),c.instance.addEventListener(`callbackCompleted`,e=>{this.unhighlightElementCallback(e.element),this.removeElementOverlay(e.element)},{signal:e})}willUpdate(e){e.has(`showNameTags`)&&this.updateNameTagVisibility(this.showNameTags)}_subscribeToElement(e){if(this._elementSubscriptions.has(e))return;let t=c.instance.subscribeToElement(e,()=>{let t=c.instance.registeredElements.get(e);if(!t||!t.isIntersectingWithViewport||!t.isActive){this.removeElementOverlay(e);return}this.createOrUpdateElementOverlay(e,t)});t&&this._elementSubscriptions.set(e,t)}_unsubscribeFromElement(e){this._elementSubscriptions.get(e)?.(),this._elementSubscriptions.delete(e)}createOverlay(e){let t=document.createElement(`div`);t.className=`slop-area`;let n=document.createElement(`div`);n.className=`name-label`,this.containerElement.appendChild(t),this.containerElement.appendChild(n);let r={nameLabel:n,slopArea:t};return this.overlayMap.set(e,r),r}expandedBorderRadius(e,t){let n=getComputedStyle(e),r=e.getBoundingClientRect(),i=(e,t,n)=>{let[i,a=i]=e.split(` `),o=(e,t)=>{let n=parseFloat(e)||0;return e.endsWith(`%`)?n/100*t:n},s=o(i,r.width),c=o(a,r.height);return[s===0?0:s+t,c===0?0:c+n]},a=i(n.borderTopLeftRadius,t.left,t.top),o=i(n.borderTopRightRadius,t.right,t.top),s=i(n.borderBottomRightRadius,t.right,t.bottom),c=i(n.borderBottomLeftRadius,t.left,t.bottom);return`${a[0]}px ${o[0]}px ${s[0]}px ${c[0]}px / ${a[1]}px ${o[1]}px ${s[1]}px ${c[1]}px`}updateSlopArea(e,t,n){let{expandedRect:r,hitSlop:i}=n.elementBounds,{style:a}=e.slopArea;a.transform=`translate3d(${r.left}px, ${r.top}px, 0)`,a.width=`${r.right-r.left}px`,a.height=`${r.bottom-r.top}px`,a.borderRadius=this.expandedBorderRadius(t,i)}updateNameLabel(e,t){let{nameLabel:n}=e,{expandedRect:r}=t.elementBounds;!this.showNameTags||t.name===`unnamed`?n.style.display=`none`:(n.textContent=t.name,n.style.display=`block`,n.style.transform=`translate3d(${r.left}px, ${r.top-25}px, 0)`)}createOrUpdateElementOverlay(e,t){let n=this.overlayMap.get(e);n||=this.createOverlay(e),this.updateSlopArea(n,e,t),this.updateNameLabel(n,t)}removeElementOverlay(e){let t=this.overlayMap.get(e);t&&(t.nameLabel.remove(),t.slopArea.remove(),this.overlayMap.delete(e)),this.clearCallbackAnimationTimeout(e)}clearCallbackAnimationTimeout(e){let t=this.callbackAnimations.get(e);t&&(clearTimeout(t.timeoutId),this.callbackAnimations.delete(e))}highlightElementCallback(e,t){this.clearCallbackAnimationTimeout(e);let n=this.overlayMap.get(e);if(n)switch(t.kind){case`mouse`:case`scroll`:case`tab`:n.slopArea.dataset.hit=t.kind;break;case`touch`:break;case`viewport`:break;default:}}unhighlightElementCallback(e){let t=setTimeout(()=>{let t=this.overlayMap.get(e);t&&delete t.slopArea.dataset.hit,this.callbackAnimations.delete(e)},400);this.callbackAnimations.set(e,{element:e,timeoutId:t})}updateNameTagVisibility(e){this.overlayMap.forEach(t=>{let n=t.nameLabel;e?n.style.display=`block`:n.style.display=`none`})}disconnectedCallback(){super.disconnectedCallback();for(let e of this._elementSubscriptions.values())e();this._elementSubscriptions.clear(),this.callbackAnimations.forEach(e=>{clearTimeout(e.timeoutId)}),this.callbackAnimations.clear();for(let e of this.overlayMap.values())e.nameLabel.remove(),e.slopArea.remove();this.overlayMap.clear(),this._abortController?.abort(),this._abortController=null}render(){return n` <div id="overlays-container"></div> `}};_([o(),g(`design:type`,typeof(G=typeof Map<`u`&&Map)==`function`?G:Object)],J.prototype,`overlayMap`,void 0),_([o(),g(`design:type`,typeof(K=typeof Map<`u`&&Map)==`function`?K:Object)],J.prototype,`callbackAnimations`,void 0),_([a(`#overlays-container`),g(`design:type`,typeof(q=typeof HTMLElement<`u`&&HTMLElement)==`function`?q:Object)],J.prototype,`containerElement`,void 0),_([i({type:Boolean}),g(`design:type`,Object)],J.prototype,`showNameTags`,void 0),J=_([r(`element-overlays`)],J);let Y=class extends e{constructor(...e){super(...e),this._abortController=new AbortController,this._lineEl=null,this._mousePredictionIsEnabled=c.instance.getManagerData.globalSettings.enableMousePrediction,this._isVisible=!1,this.handleTrajectoryReset=e=>{(`wasLastActiveElement`in e&&e.wasLastActiveElement||`wasLastRegisteredElement`in e&&e.wasLastRegisteredElement)&&(this._setVisible(!1),this._lineEl&&(this._lineEl.style.transform=`translate3d(0px, 0px, 0) rotate(0deg)`,this._lineEl.style.width=`0px`))},this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableMousePrediction;this._mousePredictionIsEnabled=t,t||this._setVisible(!1)},this.handleTrajectoryUpdate=e=>{if(!this._mousePredictionIsEnabled)return;this._setVisible(!0);let{currentPoint:t,predictedPoint:n}=e.trajectoryPositions,r=n.x-t.x,i=n.y-t.y,a=Math.sqrt(r*r+i*i),o=Math.atan2(i,r)*57.29577951308232;this._lineEl&&(this._lineEl.style.transform=`translate3d(${t.x}px, ${t.y}px, 0) rotate(${o}deg)`,this._lineEl.style.width=`${a}px`)}}static{this.styles=[t`
2053
+ `]}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;s.instance.addEventListener(`elementRegistered`,e=>{this._subscribeToElement(e.element),e.state.isIntersectingWithViewport&&this.createOrUpdateElementOverlay(e.element,e.state)},{signal:e}),s.instance.addEventListener(`elementUnregistered`,e=>{this._unsubscribeFromElement(e.element),this.removeElementOverlay(e.element)},{signal:e});for(let[e,t]of s.instance.registeredElements)this._subscribeToElement(e),t.isIntersectingWithViewport&&t.isActive&&this.createOrUpdateElementOverlay(e,t);s.instance.addEventListener(`callbackInvoked`,e=>{this.highlightElementCallback(e.element,e.hitType)},{signal:e}),s.instance.addEventListener(`callbackCompleted`,e=>{this.unhighlightElementCallback(e.element),this.removeElementOverlay(e.element)},{signal:e})}willUpdate(e){e.has(`showNameTags`)&&this.updateNameTagVisibility(this.showNameTags)}_subscribeToElement(e){if(this._elementSubscriptions.has(e))return;let t=()=>{let t=s.instance.registeredElements.get(e);if(!t||!t.isIntersectingWithViewport||!t.isActive){this.removeElementOverlay(e);return}this.createOrUpdateElementOverlay(e,t)},n=s.instance.subscribeToElement(e,t),r=s.instance.subscribeToElementBounds(e,t);(n||r)&&this._elementSubscriptions.set(e,()=>{n?.(),r?.()})}_unsubscribeFromElement(e){this._elementSubscriptions.get(e)?.(),this._elementSubscriptions.delete(e)}createOverlay(e){let t=document.createElement(`div`);t.className=`slop-area`;let n=document.createElement(`div`);n.className=`name-label`,this.containerElement.appendChild(t),this.containerElement.appendChild(n);let r={nameLabel:n,slopArea:t,lastSlopRect:null,lastRadiusKey:null};return this.overlayMap.set(e,r),r}expandedBorderRadius(e,t){let n=getComputedStyle(e),r=e.getBoundingClientRect(),i=(e,t,n)=>{let[i,a=i]=e.split(` `),o=(e,t)=>{let n=parseFloat(e)||0;return e.endsWith(`%`)?n/100*t:n},s=o(i,r.width),c=o(a,r.height);return[s===0?0:s+t,c===0?0:c+n]},a=i(n.borderTopLeftRadius,t.left,t.top),o=i(n.borderTopRightRadius,t.right,t.top),s=i(n.borderBottomRightRadius,t.right,t.bottom),c=i(n.borderBottomLeftRadius,t.left,t.bottom);return`${a[0]}px ${o[0]}px ${s[0]}px ${c[0]}px / ${a[1]}px ${o[1]}px ${s[1]}px ${c[1]}px`}updateSlopArea(e,t,n,r){let{expandedRect:i}=r,a=i.left+window.scrollX,o=i.top+window.scrollY,s=i.right-i.left,c=i.bottom-i.top,l=e.lastSlopRect;if(l&&l.left===a&&l.top===o&&l.width===s&&l.height===c)return;e.lastSlopRect={left:a,top:o,width:s,height:c};let{style:u}=e.slopArea;u.transform=`translate3d(${a}px, ${o}px, 0)`,u.width=`${s}px`,u.height=`${c}px`;let d=`${s}|${c}|${n.top}|${n.right}|${n.bottom}|${n.left}`;e.lastRadiusKey!==d&&(e.lastRadiusKey=d,u.borderRadius=this.expandedBorderRadius(t,n))}updateNameLabel(e,t,n){let{nameLabel:r}=e,{expandedRect:i}=n;!this.showNameTags||t.name===`unnamed`?r.style.display=`none`:(r.textContent=t.name,r.style.display=`block`,r.style.transform=`translate3d(${i.left+window.scrollX}px, ${i.top-25+window.scrollY}px, 0)`)}createOrUpdateElementOverlay(e,t){let n=s.instance.getElementBounds(e);if(!n)return;let r=this.overlayMap.get(e);r||=this.createOverlay(e),this.updateSlopArea(r,e,t.hitSlop,n),this.updateNameLabel(r,t,n)}removeElementOverlay(e){let t=this.overlayMap.get(e);t&&(t.nameLabel.remove(),t.slopArea.remove(),this.overlayMap.delete(e)),this.clearCallbackAnimationTimeout(e)}clearCallbackAnimationTimeout(e){let t=this.callbackAnimations.get(e);t&&(clearTimeout(t.timeoutId),this.callbackAnimations.delete(e))}highlightElementCallback(e,t){this.clearCallbackAnimationTimeout(e);let n=this.overlayMap.get(e);if(n)switch(t.kind){case`mouse`:case`scroll`:case`tab`:n.slopArea.dataset.hit=t.kind;break;case`touch`:break;case`viewport`:break;default:}}unhighlightElementCallback(e){let t=setTimeout(()=>{let t=this.overlayMap.get(e);t&&delete t.slopArea.dataset.hit,this.callbackAnimations.delete(e)},400);this.callbackAnimations.set(e,{element:e,timeoutId:t})}updateNameTagVisibility(e){this.overlayMap.forEach(t=>{let n=t.nameLabel;e?n.style.display=`block`:n.style.display=`none`})}disconnectedCallback(){super.disconnectedCallback();for(let e of this._elementSubscriptions.values())e();this._elementSubscriptions.clear(),this.callbackAnimations.forEach(e=>{clearTimeout(e.timeoutId)}),this.callbackAnimations.clear();for(let e of this.overlayMap.values())e.nameLabel.remove(),e.slopArea.remove();this.overlayMap.clear(),this._abortController?.abort(),this._abortController=null}render(){return n` <div id="overlays-container"></div> `}};_([o(),g(`design:type`,typeof(G=typeof Map<`u`&&Map)==`function`?G:Object)],J.prototype,`overlayMap`,void 0),_([o(),g(`design:type`,typeof(K=typeof Map<`u`&&Map)==`function`?K:Object)],J.prototype,`callbackAnimations`,void 0),_([a(`#overlays-container`),g(`design:type`,typeof(q=typeof HTMLElement<`u`&&HTMLElement)==`function`?q:Object)],J.prototype,`containerElement`,void 0),_([i({type:Boolean}),g(`design:type`,Object)],J.prototype,`showNameTags`,void 0),J=_([r(`element-overlays`)],J);let Y=class extends e{constructor(...e){super(...e),this._abortController=new AbortController,this._lineEl=null,this._mousePredictionIsEnabled=s.instance.getManagerData.globalSettings.enableMousePrediction,this._isVisible=!1,this.handleTrajectoryReset=e=>{(`wasLastActiveElement`in e&&e.wasLastActiveElement||`wasLastRegisteredElement`in e&&e.wasLastRegisteredElement)&&(this._setVisible(!1),this._lineEl&&(this._lineEl.style.transform=`translate3d(0px, 0px, 0) rotate(0deg)`,this._lineEl.style.width=`0px`))},this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableMousePrediction;this._mousePredictionIsEnabled=t,t||this._setVisible(!1)},this.handleTrajectoryUpdate=e=>{if(!this._mousePredictionIsEnabled)return;this._setVisible(!0);let{currentPoint:t,predictedPoint:n}=e.trajectoryPositions,r=n.x-t.x,i=n.y-t.y,a=Math.sqrt(r*r+i*i),o=Math.atan2(i,r)*57.29577951308232;this._lineEl&&(this._lineEl.style.transform=`translate3d(${t.x}px, ${t.y}px, 0) rotate(${o}deg)`,this._lineEl.style.width=`${a}px`)}}static{this.styles=[t`
2062
2054
  :host {
2063
2055
  display: block;
2064
2056
  }
@@ -2094,7 +2086,7 @@ Click on the copy icon to easely copy the new setting into your project
2094
2086
  border-bottom: 4px solid transparent;
2095
2087
  filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.6));
2096
2088
  }
2097
- `]}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;c.instance.addEventListener(`callbackCompleted`,this.handleTrajectoryReset,{signal:e}),c.instance.addEventListener(`elementUnregistered`,this.handleTrajectoryReset,{signal:e}),c.instance.addEventListener(`mouseTrajectoryUpdate`,this.handleTrajectoryUpdate,{signal:e}),c.instance.addEventListener(`scrollTrajectoryUpdate`,()=>{this._setVisible(!1)},{signal:e}),c.instance.addEventListener(`managerSettingsChanged`,this.handleSettingsChange,{signal:e})}firstUpdated(){this._lineEl=this.shadowRoot.querySelector(`.trajectory-line`)}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}_setVisible(e){this._isVisible!==e&&(this._isVisible=e,this._lineEl&&(this._lineEl.style.display=e?`block`:`none`))}render(){return n`<div class="trajectory-line"></div>`}};Y=_([r(`mouse-trajectory`)],Y);let X=class extends e{constructor(...e){super(...e),this._abortController=new AbortController,this._lineEl=null,this._scrollPredictionIsEnabled=c.instance.getManagerData.globalSettings.enableScrollPrediction,this._scrollMargin=c.instance.getManagerData.globalSettings.scrollMargin,this._isVisible=!1,this._latestCurrentPoint=null,this._latestPredictedPoint=null,this._isUpdateScheduled=!1,this.handleTrajectoryReset=e=>{(`wasLastActiveElement`in e&&e.wasLastActiveElement||`wasLastRegisteredElement`in e&&e.wasLastRegisteredElement)&&(this._setVisible(!1),this._lineEl&&(this._lineEl.style.transform=`translate(0px, 0px) rotate(0deg)`))},this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableScrollPrediction;this._scrollPredictionIsEnabled=t,t||this._setVisible(!1);let n=e.updatedSettings.find(e=>e.setting===`scrollMargin`);n&&(this._scrollMargin=n.newValue,this._lineEl&&(this._lineEl.style.width=`${this._scrollMargin}px`))},this.handleScrollUpdate=e=>{this._scrollPredictionIsEnabled&&(this._setVisible(!0),this._latestCurrentPoint=e.currentPoint,this._latestPredictedPoint=e.predictedPoint,this._isUpdateScheduled||(this._isUpdateScheduled=!0,this.applyScrollTransform()))},this.applyScrollTransform=()=>{if(!this._latestCurrentPoint||!this._latestPredictedPoint){this._isUpdateScheduled=!1;return}let e=this._latestPredictedPoint.x-this._latestCurrentPoint.x,t=this._latestPredictedPoint.y-this._latestCurrentPoint.y,n=Math.atan2(t,e)*180/Math.PI;this._lineEl&&(this._lineEl.style.transform=`translate(${this._latestCurrentPoint.x}px, ${this._latestCurrentPoint.y}px) rotate(${n}deg)`),this._isUpdateScheduled=!1}}static{this.styles=[t`
2089
+ `]}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;s.instance.addEventListener(`callbackCompleted`,this.handleTrajectoryReset,{signal:e}),s.instance.addEventListener(`elementUnregistered`,this.handleTrajectoryReset,{signal:e}),s.instance.addEventListener(`mouseTrajectoryUpdate`,this.handleTrajectoryUpdate,{signal:e}),s.instance.addEventListener(`scrollTrajectoryUpdate`,()=>{this._setVisible(!1)},{signal:e}),s.instance.addEventListener(`managerSettingsChanged`,this.handleSettingsChange,{signal:e})}firstUpdated(){this._lineEl=this.shadowRoot.querySelector(`.trajectory-line`)}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}_setVisible(e){this._isVisible!==e&&(this._isVisible=e,this._lineEl&&(this._lineEl.style.display=e?`block`:`none`))}render(){return n`<div class="trajectory-line"></div>`}};Y=_([r(`mouse-trajectory`)],Y);let X=class extends e{constructor(...e){super(...e),this._abortController=new AbortController,this._lineEl=null,this._scrollPredictionIsEnabled=s.instance.getManagerData.globalSettings.enableScrollPrediction,this._scrollMargin=s.instance.getManagerData.globalSettings.scrollMargin,this._isVisible=!1,this._latestCurrentPoint=null,this._latestPredictedPoint=null,this._isUpdateScheduled=!1,this.handleTrajectoryReset=e=>{(`wasLastActiveElement`in e&&e.wasLastActiveElement||`wasLastRegisteredElement`in e&&e.wasLastRegisteredElement)&&(this._setVisible(!1),this._lineEl&&(this._lineEl.style.transform=`translate(0px, 0px) rotate(0deg)`))},this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableScrollPrediction;this._scrollPredictionIsEnabled=t,t||this._setVisible(!1);let n=e.updatedSettings.find(e=>e.setting===`scrollMargin`);n&&(this._scrollMargin=n.newValue,this._lineEl&&(this._lineEl.style.width=`${this._scrollMargin}px`))},this.handleScrollUpdate=e=>{this._scrollPredictionIsEnabled&&(this._setVisible(!0),this._latestCurrentPoint=e.currentPoint,this._latestPredictedPoint=e.predictedPoint,this._isUpdateScheduled||(this._isUpdateScheduled=!0,this.applyScrollTransform()))},this.applyScrollTransform=()=>{if(!this._latestCurrentPoint||!this._latestPredictedPoint){this._isUpdateScheduled=!1;return}let e=this._latestPredictedPoint.x-this._latestCurrentPoint.x,t=this._latestPredictedPoint.y-this._latestCurrentPoint.y,n=Math.atan2(t,e)*180/Math.PI;this._lineEl&&(this._lineEl.style.transform=`translate(${this._latestCurrentPoint.x}px, ${this._latestCurrentPoint.y}px) rotate(${n}deg)`),this._isUpdateScheduled=!1}}static{this.styles=[t`
2098
2090
  :host {
2099
2091
  display: block;
2100
2092
  }
@@ -2159,7 +2151,7 @@ Click on the copy icon to easely copy the new setting into your project
2159
2151
  filter: drop-shadow(0 0 12px rgba(234, 179, 8, 0.8));
2160
2152
  }
2161
2153
  }
2162
- `]}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;c.instance.addEventListener(`scrollTrajectoryUpdate`,this.handleScrollUpdate,{signal:e}),c.instance.addEventListener(`mouseTrajectoryUpdate`,()=>{this._setVisible(!1)},{signal:e}),c.instance.addEventListener(`callbackCompleted`,this.handleTrajectoryReset,{signal:e}),c.instance.addEventListener(`elementUnregistered`,this.handleTrajectoryReset,{signal:e}),c.instance.addEventListener(`managerSettingsChanged`,this.handleSettingsChange,{signal:e})}firstUpdated(){this._lineEl=this.shadowRoot.querySelector(`.scroll-trajectory-line`)}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}_setVisible(e){this._isVisible!==e&&(this._isVisible=e,this._lineEl&&(this._lineEl.style.display=e?`block`:`none`))}render(){return n`<div class="scroll-trajectory-line" style="width: ${this._scrollMargin}px"></div>`}};X=_([r(`scroll-trajectory`)],X);let Z=class extends e{constructor(...e){super(...e),this._abortController=null,this._strategy=c.instance.getManagerData.currentDeviceStrategy,this.showElementOverlays=!0,this.showMouseTrajectory=!0,this.showScrollTrajectory=!0,this.showNameTags=!0,this.handleDeviceStrategyChange=e=>this._strategy=e.newStrategy}static{this.styles=[t`
2154
+ `]}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;s.instance.addEventListener(`scrollTrajectoryUpdate`,this.handleScrollUpdate,{signal:e}),s.instance.addEventListener(`mouseTrajectoryUpdate`,()=>{this._setVisible(!1)},{signal:e}),s.instance.addEventListener(`callbackCompleted`,this.handleTrajectoryReset,{signal:e}),s.instance.addEventListener(`elementUnregistered`,this.handleTrajectoryReset,{signal:e}),s.instance.addEventListener(`managerSettingsChanged`,this.handleSettingsChange,{signal:e})}firstUpdated(){this._lineEl=this.shadowRoot.querySelector(`.scroll-trajectory-line`)}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}_setVisible(e){this._isVisible!==e&&(this._isVisible=e,this._lineEl&&(this._lineEl.style.display=e?`block`:`none`))}render(){return n`<div class="scroll-trajectory-line" style="width: ${this._scrollMargin}px"></div>`}};X=_([r(`scroll-trajectory`)],X);let Z=class extends e{constructor(...e){super(...e),this._abortController=null,this._strategy=s.instance.getManagerData.currentDeviceStrategy,this.showElementOverlays=!0,this.showMouseTrajectory=!0,this.showScrollTrajectory=!0,this.showNameTags=!0,this.handleDeviceStrategyChange=e=>this._strategy=e.newStrategy}static{this.styles=[t`
2163
2155
  :host {
2164
2156
  display: block;
2165
2157
  }
@@ -2170,22 +2162,27 @@ Click on the copy icon to easely copy the new setting into your project
2170
2162
  pointer-events: none;
2171
2163
  z-index: 9999;
2172
2164
  }
2173
- `]}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;c.instance.addEventListener(`deviceStrategyChanged`,this.handleDeviceStrategyChange,{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort()}render(){return n`
2165
+ `]}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;s.instance.addEventListener(`deviceStrategyChanged`,this.handleDeviceStrategyChange,{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort()}render(){return n`
2174
2166
  <div id="overlay-container">
2175
2167
  ${this._strategy===`mouse`?n`
2176
2168
  <mouse-trajectory ?hidden=${!this.showMouseTrajectory}></mouse-trajectory>
2177
2169
  <scroll-trajectory ?hidden=${!this.showScrollTrajectory}></scroll-trajectory>
2178
- <element-overlays
2179
- ?hidden=${!this.showElementOverlays}
2180
- .showNameTags=${this.showNameTags}
2181
- ></element-overlays>
2182
2170
  `:``}
2183
2171
  </div>
2172
+ <!-- element-overlays positions itself in document coordinates and must stay
2173
+ outside #overlay-container: the fixed container would become its
2174
+ containing block and pin it back to the viewport. -->
2175
+ ${this._strategy===`mouse`?n`
2176
+ <element-overlays
2177
+ ?hidden=${!this.showElementOverlays}
2178
+ .showNameTags=${this.showNameTags}
2179
+ ></element-overlays>
2180
+ `:``}
2184
2181
  `}};_([o(),g(`design:type`,String)],Z.prototype,`_strategy`,void 0),_([i({type:Boolean}),g(`design:type`,Object)],Z.prototype,`showElementOverlays`,void 0),_([i({type:Boolean}),g(`design:type`,Object)],Z.prototype,`showMouseTrajectory`,void 0),_([i({type:Boolean}),g(`design:type`,Object)],Z.prototype,`showScrollTrajectory`,void 0),_([i({type:Boolean}),g(`design:type`,Object)],Z.prototype,`showNameTags`,void 0),Z=_([r(`debug-overlay`)],Z);var Q;let $=class extends e{static{Q=this}static{this.styles=[t`
2185
2182
  :host {
2186
2183
  display: block;
2187
2184
  }
2188
- `]}static{this._instance=null}constructor(){super(),this.isInitialized=!1,this.devtoolsSettings={show:{controlPanel:!0,nameTags:!0,elementOverlays:!0,mouseTrajectory:!0,scrollTrajectory:!0},isControlPanelDefaultMinimized:!1,sortElementList:`visibility`,logging:{logLocation:`controlPanel`,callbackCompleted:!0,callbackInvoked:!0,elementRegistered:!1,elementUnregistered:!1,managerSettingsChanged:!0,mouseTrajectoryUpdate:!1,scrollTrajectoryUpdate:!1,deviceStrategyChanged:!0}}}static createAndAppendInstance(){typeof window>`u`||typeof document>`u`||(Q._instance=document.createElement(`foresight-devtools`),document.body.appendChild(Q._instance))}static initialize(e){if(Q._instance||Q.createAndAppendInstance(),!Q._instance)return Q._instance;let t=Q._instance;return t.isInitialized=!0,t.alterDevtoolsSettings(e),t}static get instance(){return Q._instance?Q._instance:Q.initialize()}disconnectedCallback(){super.disconnectedCallback(),this.cleanup()}shouldUpdateSetting(e,t){return e!==void 0&&e!==t}updateLoggingSetting(e,t){this.shouldUpdateSetting(t,this.devtoolsSettings.logging[e])&&(this.devtoolsSettings.logging[e]=t)}updateShowSetting(e,t){return this.shouldUpdateSetting(t,this.devtoolsSettings.show[e])?(this.devtoolsSettings.show[e]=t,!0):!1}setAllShow(e){let t=Object.fromEntries(u.map(t=>[t,e]));this.alterDevtoolsSettings({show:t})}alterDevtoolsSettings(e){if(e!==void 0){if(e.show){let t=!1;for(let n of u)this.updateShowSetting(n,e.show[n])&&(t=!0);t&&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.updateLoggingSetting(`callbackCompleted`,e.logging.callbackCompleted),this.updateLoggingSetting(`callbackInvoked`,e.logging.callbackInvoked),this.updateLoggingSetting(`elementRegistered`,e.logging.elementRegistered),this.updateLoggingSetting(`elementUnregistered`,e.logging.elementUnregistered),this.updateLoggingSetting(`managerSettingsChanged`,e.logging.managerSettingsChanged),this.updateLoggingSetting(`mouseTrajectoryUpdate`,e.logging.mouseTrajectoryUpdate),this.updateLoggingSetting(`scrollTrajectoryUpdate`,e.logging.scrollTrajectoryUpdate),this.updateLoggingSetting(`deviceStrategyChanged`,e.logging.deviceStrategyChanged))}}cleanup(){this.requestUpdate()}render(){if(!this.isInitialized)return n``;let{show:e}=this.devtoolsSettings;return n`
2185
+ `]}static{this._instance=null}constructor(){super(),this.isInitialized=!1,this.devtoolsSettings={show:{controlPanel:!0,nameTags:!0,elementOverlays:!0,mouseTrajectory:!0,scrollTrajectory:!0},isControlPanelDefaultMinimized:!1,sortElementList:`visibility`,logging:{logLocation:`controlPanel`,callbackCompleted:!0,callbackInvoked:!0,elementRegistered:!1,elementUnregistered:!1,managerSettingsChanged:!0,mouseTrajectoryUpdate:!1,scrollTrajectoryUpdate:!1,deviceStrategyChanged:!0}}}static createAndAppendInstance(){typeof window>`u`||typeof document>`u`||(Q._instance=document.createElement(`foresight-devtools`),document.body.appendChild(Q._instance))}static initialize(e){if(Q._instance||Q.createAndAppendInstance(),!Q._instance)return Q._instance;let t=Q._instance;return t.isInitialized=!0,t.alterDevtoolsSettings(e),t}static get instance(){return Q._instance?Q._instance:Q.initialize()}disconnectedCallback(){super.disconnectedCallback(),this.cleanup()}shouldUpdateSetting(e,t){return e!==void 0&&e!==t}updateLoggingSetting(e,t){this.shouldUpdateSetting(t,this.devtoolsSettings.logging[e])&&(this.devtoolsSettings.logging[e]=t)}updateShowSetting(e,t){return this.shouldUpdateSetting(t,this.devtoolsSettings.show[e])?(this.devtoolsSettings.show[e]=t,!0):!1}setAllShow(e){let t=Object.fromEntries(l.map(t=>[t,e]));this.alterDevtoolsSettings({show:t})}alterDevtoolsSettings(e){if(e!==void 0){if(e.show){let t=!1;for(let n of l)this.updateShowSetting(n,e.show[n])&&(t=!0);t&&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.updateLoggingSetting(`callbackCompleted`,e.logging.callbackCompleted),this.updateLoggingSetting(`callbackInvoked`,e.logging.callbackInvoked),this.updateLoggingSetting(`elementRegistered`,e.logging.elementRegistered),this.updateLoggingSetting(`elementUnregistered`,e.logging.elementUnregistered),this.updateLoggingSetting(`managerSettingsChanged`,e.logging.managerSettingsChanged),this.updateLoggingSetting(`mouseTrajectoryUpdate`,e.logging.mouseTrajectoryUpdate),this.updateLoggingSetting(`scrollTrajectoryUpdate`,e.logging.scrollTrajectoryUpdate),this.updateLoggingSetting(`deviceStrategyChanged`,e.logging.deviceStrategyChanged))}}cleanup(){this.requestUpdate()}render(){if(!this.isInitialized)return n``;let{show:e}=this.devtoolsSettings;return n`
2189
2186
  ${e.controlPanel?n`<control-panel></control-panel>`:``}
2190
2187
  <debug-overlay
2191
2188
  .showElementOverlays=${e.elementOverlays}