@aceshooting/lyra-ui 28.1.1 → 28.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/components/agent-tools/span-waterfall/span-waterfall.class.js +1 -1
  3. package/dist/components/charts/chart/box-plot.class.d.ts +1 -1
  4. package/dist/components/charts/chart/box-plot.class.js +2 -2
  5. package/dist/components/charts/chart/chart.class.d.ts +1 -1
  6. package/dist/components/charts/chart/chart.class.js +3 -3
  7. package/dist/components/conversation/push-to-talk/push-to-talk.class.d.ts +2 -1
  8. package/dist/components/conversation/push-to-talk/push-to-talk.class.js +1 -1
  9. package/dist/components/data/flow-canvas/flow-canvas.class.js +1 -1
  10. package/dist/components/data/heatmap/heatmap.class.js +1 -1
  11. package/dist/components/forms/textarea/textarea.class.js +1 -1
  12. package/dist/components/layout/details/accordion.class.js +1 -1
  13. package/dist/components/layout/menu/menu.class.d.ts +1 -1
  14. package/dist/components/layout/menu/menu.class.js +1 -1
  15. package/dist/components/layout/page/page.class.d.ts +1 -1
  16. package/dist/components/layout/page/page.class.js +1 -1
  17. package/dist/components/layout/responsive-panel/responsive-panel.class.js +1 -1
  18. package/dist/components/layout/widget/widget.class.js +1 -1
  19. package/dist/components/media/image-viewer/image-viewer.class.js +1 -1
  20. package/dist/components/overlays/overlay/dropdown.class.js +1 -1
  21. package/dist/components/overlays/overlay/popover.class.js +1 -1
  22. package/dist/components/retrieval/graph/graph.class.d.ts +1 -1
  23. package/dist/components/retrieval/graph/graph.class.js +1 -1
  24. package/dist/components/utility/tour/tour.class.js +4 -4
  25. package/dist/internal/dev-mode-attribute-warning.development.js +1 -1
  26. package/dist/internal/package-metadata.js +1 -1
  27. package/llms/components/lr-push-to-talk.md +3 -0
  28. package/llms/peers.md +1 -1
  29. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{GlassScrollLayer}from"../../../internal/glass-scroll-layer.js";import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{hostAriaLabel,nextId,resolveAccessibleTrigger}from"../../../internal/a11y.js";import{collectInitialSlotAssignment}from"../../../internal/initial-slot-collection.js";import{collectComposedFocusTargets}from"../../../internal/focus-navigation.js";import{CustomElementUpgradeObserver}from"../../../internal/custom-element-upgrade-observer.js";import{acquireAriaOwnership}from"../../../internal/aria-ownership.js";import{tag}from"../../../internal/prefix.js";import{resolveEffectivePositioningStrategy}from"../../../internal/positioning-strategy.js";import{deferredPlaceReady,syncTopLayerRelease,waitForDeferredPlacement}from"../../../internal/anchored-overlay-runtime.js";import{rtlAwarePlacement}from"../../../internal/rtl.js";import{finiteDuration,finiteNumber}from"../../../internal/numbers.js";import{deepActiveElementIn}from"../../../internal/active-element.js";import{isKeyboardFocusEvent}from"../../../internal/focus-modality.js";import{literalSetConverter,omittedEmptyStringConverter,optionalLiteralSetConverter}from"../../../internal/converters.js";import{activateNonmodalOverlay,composedContains}from"../../../internal/nonmodal-overlay-manager.js";import{setCustomState}from"../../../internal/custom-states.js";import{attachInternalsSafely}from"../../../internal/element-internals.js";import{animateRegistered}from"../../../internal/registered-animation.js";import{applyOverlayArrow}from"./overlay-arrow.js";import{normalizeVirtualRect,OverlayAnchorIdentity,OverlayDelayTimer,OverlayTransitionGate,resolveOverlayAnchor,resolveOverlayInteractionTrigger,settleOverlayTransition}from"./overlay-shared.js";import{styles}from"./overlay.styles.js";import{glassPopoverStyles}from"./popover-glass.styles.js";import{LYRA_DEFAULT_menuLabel,LYRA_DEFAULT_popover}from"../../../internal/default-strings/shared.generated.js";const DEFAULT_DISTANCE=8,EXPANDABLE_TRIGGER_ROLES=new Set(["application","button","checkbox","combobox","gridcell","link","listbox","menuitem","row","rowheader","tab","treeitem","columnheader","menuitemcheckbox","menuitemradio","switch"]);function supportsTriggerExpansion(element){const role=element.getAttribute("role")?.trim().split(/\s+/)[0];return role?EXPANDABLE_TRIGGER_ROLES.has(role):element.matches("button, a[href], select, summary")?!0:element.localName==="input"&&["button","submit","reset","image","checkbox"].includes(element.type)}let popoverConnectionSequence=0;const POPUP_ROLE=literalSetConverter(["dialog","menu","none"],"dialog"),POPOVER_TRIGGER_KEYWORDS=["click","hover","focus","manual"];function normalizeTriggerList(next){const keywords=[];for(const token of String(next??"").trim().toLowerCase().split(/\s+/)){const keyword=POPOVER_TRIGGER_KEYWORDS.find(candidate=>candidate===token);keyword&&!keywords.includes(keyword)&&keywords.push(keyword)}return keywords.length>0?keywords.join(" "):"click"}const DEFAULT_TRIGGER_DELAY=0,POSITIONING_STRATEGY=optionalLiteralSetConverter(["absolute","fixed"]);class LyraPopover extends LyraElement{static{this.defaultStrings={...super.defaultStrings,menuLabel:LYRA_DEFAULT_menuLabel,popover:LYRA_DEFAULT_popover}}constructor(){super(),this._open=!1,this.placement="top",this.topLayer=!1,this.distance=8,this.skidding=0,this._for="",this.anchor=null,this.interactionBoundary=null,this.withoutArrow=!1,this.arrowPlacement="anchor",this.arrowPadding=0,this._trigger="click",this.showDelay=0,this.hideDelay=0,this.hoverBridge=!1,this.accessibleLabel="",this._popupRole="dialog",this._disabled=!1,this.openedByInteraction=!1,this.pinned=!1,this.suppressTriggerFocusOpen=!1,this.delayTimer=new OverlayDelayTimer,this.resolvedSide="bottom",this.anchorPositioned=!1,this.popupHidden=!0,this.disconnecting=!1,this.reconnectedWhileDisconnecting=!1,this.directionChanged=!1,this.anchorIdentity=new OverlayAnchorIdentity,this.triggerUpgrades=new CustomElementUpgradeObserver(()=>{this.isConnected&&this.syncTriggerA11y()}),this.positioningGeneration=0,this.generatedHostId=nextId("popover"),this.popupId=nextId("popover-popup"),this.hostIdObserverGeneration=0,this.transitionToken=0,this.transitionGate=new OverlayTransitionGate,this.connectionSequence=0,this.popoverInternals=attachInternalsSafely(this),this.onExternalTriggerKeyDown=event=>{this.onTriggerKeyDown(event)},this.onTriggerSlotChange=event=>{this.collectTriggerFromSlot(event.target)},this.onTriggerClick=()=>{if(!this.virtualAnchor&&(this.syncTriggerA11y(),!this.isManualTrigger)){if(this.cancelPendingTransition(),this.opensOn("click")&&!this.opensOn("hover")&&!this.opensOn("focus")){this.open?this.hide():this.show();return}if(this.open&&this.pinned){this.hide();return}this.open||(this.openedByInteraction=!1,this.show()),this.pinned=this.open}},this.onTriggerPointerEnter=()=>{this.opensOn("hover")&&this.requestDelayedTransition(!0)},this.onTriggerPointerLeave=event=>{this.opensOn("hover")&&this.requestInteractionClose(event.relatedTarget)},this.onPopupPointerEnter=()=>{!this.opensOn("hover")||!this.open||this.cancelPendingTransition()},this.onPopupPointerLeave=event=>{this.opensOn("hover")&&this.requestInteractionClose(event.relatedTarget)},this.onSurfaceFocusIn=event=>{!this.opensOn("focus")||this.suppressTriggerFocusOpen||(!this.open||this.triggerElement!=null&&event.composedPath().includes(this.triggerElement))&&!isKeyboardFocusEvent(event)||this.requestDelayedTransition(!0)},this.onSurfaceFocusOut=event=>{this.opensOn("focus")&&this.requestInteractionClose(event.relatedTarget)},this.onPopupClick=event=>{if(event.defaultPrevented)return;const path=event.composedPath(),hostIndex=path.indexOf(this);if(hostIndex<0)return;const closeAction=path.slice(0,hostIndex).find(target=>target.nodeType===1&&target.getAttribute("data-popover")==="close");if(!closeAction)return;event.stopPropagation();const state2=closeAction;state2.effectiveDisabled===!0||state2.disabled===!0||closeAction.hasAttribute("disabled")||closeAction.getAttribute("aria-disabled")?.trim().toLowerCase()==="true"||closeAction.hasAttribute("inert")||closeAction.closest("[inert]")||this.hide()},this.onDocumentPointer=event=>{this.overlayHandle?.isTopmost()&&(this.isInsideLightDismissBoundary(event.composedPath())||this.hide())},new GlassScrollLayer(this,'[part~="popup"]')}static{this.styles=[LyraElement.styles,styles,glassPopoverStyles]}get open(){return this._open}set open(next){const normalized=!!next&&this.canOpen;if(normalized!==this._open){if(!this.hasUpdated){this.setOpen(normalized),this.isConnected&&this.connectionSequence>0&&this.updateBrowserDerivedState(()=>this.reconcileInitialPopoverPeers());return}normalized?this.show():this.hide()}}get positioningStrategy(){return this._positioningStrategy??this.defaultPositioningStrategy}set positioningStrategy(next){const normalized=POSITIONING_STRATEGY.normalize(next)??this.defaultPositioningStrategy,old=this.positioningStrategy;this._positioningStrategy=normalized,normalized!==old&&(this.requestUpdate("positioningStrategy",old),this.onPositioningStrategyChanged(old,normalized))}onPositioningStrategyChanged(_previous,_next){}get for(){return this._for}set for(next){this._for=next??""}get trigger(){return this._trigger}set trigger(next){const normalized=normalizeTriggerList(next);if(normalized===this._trigger)return;const old=this._trigger;this._trigger=normalized,this.requestUpdate("trigger",old)}get triggerKeywords(){return new Set(this._trigger.split(" "))}get isManualTrigger(){return this.triggerKeywords.has("manual")}opensOn(keyword){return!this.isManualTrigger&&this.triggerKeywords.has(keyword)}get popupRole(){return this._popupRole}set popupRole(next){const normalized=POPUP_ROLE.normalize(next);if(normalized===this._popupRole)return;const old=this._popupRole;this._popupRole=normalized,this.requestUpdate("popupRole",old)}get disabled(){return this._disabled}set disabled(next){const normalized=!!next;if(normalized===this._disabled)return;const old=this._disabled;this._disabled=normalized,this.requestUpdate("disabled",old),normalized&&this.open&&(this.hasUpdated?this.hide():this.open=!1)}get defaultDistance(){return DEFAULT_DISTANCE}get defaultPositioningStrategy(){return"fixed"}get resolvedPositioningStrategy(){return resolveEffectivePositioningStrategy(this,this._positioningStrategy,this.defaultPositioningStrategy)}get positioningSync(){}get animationNamespace(){return"popover"}animationDurationProperties(showing){return[showing?"--show-duration":"--hide-duration","--lr-duration-fast"]}get popupPartNames(){return["popup","dialog","popup__popup"].join(" ")}get contentPartNames(){return["content","body"].join(" ")}get triggerPopupRole(){return this.popupRole}get popupSurfaceRole(){return this.popupRole==="none"?void 0:this.popupRole}get effectivePopupLabel(){return hostAriaLabel(this)??(this.accessibleLabel||this.localize(this.triggerPopupRole==="menu"?"menuLabel":"popover"))}get rendersArrow(){return!this.withoutArrow}get arrowPartNames(){return"arrow popup__arrow"}get rendersHoverBridge(){return this.hoverBridge&&this.opensOn("hover")&&this.open}get canOpen(){return!this.disabled}renderPopupContent(){return html`<slot></slot>`}onTriggerKeyDown(_event){}isInsideLightDismissBoundary(path){const boundary=this.virtualAnchor?this.virtualInteractionBoundary:this.interactionBoundary;return path.includes(this)||this.triggerElement!=null&&path.includes(this.triggerElement)||boundary!=null&&boundary.isConnected&&boundary.ownerDocument===this.ownerDocument&&path.includes(boundary)}onPopupPositioned(){this.openedByInteraction||this.overlayHandle?.focusAutofocus()}willUpdate(changed){super.willUpdate(changed);const direction=this.effectiveDirection;this.directionChanged=direction!==this.positioningDirection,this.positioningDirection=direction,this.anchorIdentity.lostAnchorProperty(changed,this.anchor)&&this.open&&!this.resolveAnchor()&&this.forceClose({focusTrigger:!1}),changed.has("open")&&!this.open&&(this.anchorPositioned=!1),changed.has("open")&&this.open&&(this.popupHidden=!1),(changed.has("anchor")||changed.has("for"))&&(this.anchorPositioned=!1)}updated(changed){if(super.updated(changed),changed.has("trigger")&&(this.cancelPendingTransition(),!this.opensOn("hover")&&!this.opensOn("focus")&&(this.pinned=!1)),changed.has("showDelay")&&this.delayTimer.pendingDirection==="show"&&this.requestDelayedTransition(!0,!0),changed.has("hideDelay")&&this.delayTimer.pendingDirection==="hide"&&this.requestDelayedTransition(!1,!0),(changed.has("for")||changed.has("anchor")||changed.has("open"))&&this.syncAnchorIdentityObservation(),changed.has("for")&&this.syncInteractionTrigger(),this.directionChanged||changed.has("open")||changed.has("placement")||changed.has("positioningStrategy")||changed.has("topLayer")||changed.has("hoverBridge")||changed.has("trigger")||changed.has("distance")||changed.has("skidding")||changed.has("for")||changed.has("anchor")||changed.has("arrow")||changed.has("withoutArrow")||changed.has("arrowPlacement")||changed.has("arrowPadding")||changed.has("popupRole")){if(this.open&&this.isConnected?this.positionPopup():changed.has("open")&&this.invalidatePositioning(),changed.has("open"))if(this.open)this.isConnected&&(this.startLightDismiss(),this.activatePopoverOverlay());else{this.pinned=!1,this.openedByInteraction=!1,this.cancelPendingTransition(),this.positionedAnchor=void 0,this.stopLightDismiss(),this.suppressTriggerFocusOpen=!0;try{this.overlayHandle?.deactivate()}finally{this.suppressTriggerFocusOpen=!1}this.overlayHandle=void 0,this.virtualAnchor=void 0,this.returnFocusTo=void 0,this.virtualInteractionBoundary=void 0,this.syncInteractionTrigger()}this.isConnected&&this.syncTriggerA11y()}}firstUpdated(changed){super.firstUpdated(changed);const slot=this.triggerSlotElement;queueMicrotask(()=>{collectInitialSlotAssignment(slot,s=>this.collectTriggerFromSlot(s))})}connectedCallback(){if(this.disconnecting){this.reconnectedWhileDisconnecting=!0;return}if(super.connectedCallback(),this.connectionSequence=++popoverConnectionSequence,this.addEventListener("focusin",this.onSurfaceFocusIn),this.addEventListener("focusout",this.onSurfaceFocusOut),this.updateBrowserDerivedState(()=>this.reconcileInitialPopoverPeers()),this.syncAnchorIdentityObservation(),this.id||(this.id=this.generatedHostId),this.observeHostId(),this.syncInteractionTrigger(),this.hasUpdated&&this.open){const wasPreviouslyActivated=this.overlayHandle?.isActive()===!0;this.startLightDismiss(),wasPreviouslyActivated?this.overlayHandle.resume():this.activatePopoverOverlay(),this.popupHidden=!1,this.positionPopup()}}disconnectedCallback(){this.disconnecting=!0;try{this.teardownOnDisconnect(),super.disconnectedCallback()}finally{this.disconnecting=!1}this.reconnectedWhileDisconnecting&&(this.reconnectedWhileDisconnecting=!1,this.isConnected&&this.connectedCallback())}teardownOnDisconnect(){this.anchorIdentity.stop(),this.invalidatePositioning(),this.stopLightDismiss(),this.resetHostIdObserver(),this.overlayHandle?.suspend(),this.triggerElement?.removeEventListener("click",this.onTriggerClick),this.triggerElement?.removeEventListener("keydown",this.onExternalTriggerKeyDown),this.triggerElement&&this.unbindTriggerInteractions(this.triggerElement),this.releaseTriggerA11y(),this.triggerElement=void 0,this.removeEventListener("focusin",this.onSurfaceFocusIn),this.removeEventListener("focusout",this.onSurfaceFocusOut),this.cancelPendingTransition(),this.virtualInteractionBoundary=void 0,this.pinned=!1,this.openedByInteraction=!1,this.transitionToken++,this.cancelTransitionAnimation(),this.removeAttribute("data-closing"),this.popupHidden=!0}adoptedCallback(){super.adoptedCallback(),this.anchorIdentity.stop(),this.resetHostIdObserver(),this.releaseTriggerA11y()}syncAnchorIdentityObservation(){this.anchorIdentity.stop();const directAnchor=this.open?this.anchor??void 0:void 0;this.anchorIdentity.observe(this,directAnchor,this.for,()=>this.anchor,directAnchorRemoved=>{if(this.resolveInteractionTrigger()!==this.triggerElement&&this.syncInteractionTrigger(),!this.open)return;const nextAnchor=this.resolveAnchor();if(directAnchorRemoved&&!nextAnchor){this.forceClose({focusTrigger:!1});return}nextAnchor!==this.positionedAnchor&&this.positionPopup()})}resolveInteractionTrigger(){return resolveOverlayInteractionTrigger(this,this.virtualAnchor,this.slottedTrigger,this.for)}syncInteractionTrigger(){const next=this.resolveInteractionTrigger();if(next===this.triggerElement){this.syncTriggerA11y();return}const previous=this.triggerElement;if(previous?.removeEventListener("click",this.onTriggerClick),previous?.removeEventListener("keydown",this.onExternalTriggerKeyDown),previous&&this.unbindTriggerInteractions(previous),this.triggerElement=next,this.triggerUpgrades.disconnect(),this.triggerElement&&this.triggerElement!==this.slottedTrigger&&(this.triggerElement.addEventListener("click",this.onTriggerClick),this.triggerElement.addEventListener("keydown",this.onExternalTriggerKeyDown)),this.triggerElement&&this.bindTriggerInteractions(this.triggerElement),this.syncTriggerA11y(),this.open){if(previous&&next&&this.openedByInteraction&&!this.pinned&&![next,this].some(element=>element.matches(":hover"))&&!this.isWithinPopoverSurface(deepActiveElementIn(this.ownerDocument))||!this.resolveAnchor()){this.forceClose({focusTrigger:!1});return}this.updatePopoverRestoreFocusTarget(),this.positionPopup()}}activatePopoverOverlay(){!this.isConnected||this.overlayHandle?.isActive()||(this.overlayHandle=activateNonmodalOverlay({host:this,panel:()=>this.renderRoot.querySelector('[part~="popup"]'),onEscape:()=>{this.hide()},restoreFocusTo:this.virtualAnchor?this.returnFocusTo??null:this.accessibleTrigger}))}updatePopoverRestoreFocusTarget(){const target=this.virtualAnchor?this.returnFocusTo??null:this.accessibleTrigger;if(this.overlayHandle?.isActive()){this.overlayHandle.updateRestoreFocusTo(target);return}this.activatePopoverOverlay()}showAt(rect,options){const normalizedRect=normalizeVirtualRect(rect);if(!normalizedRect)return;const previousAnchor=this.virtualAnchor,previousReturnFocusTo=this.returnFocusTo,previousInteractionBoundary=this.virtualInteractionBoundary,bounds=new DOMRect(normalizedRect.x,normalizedRect.y,normalizedRect.width,normalizedRect.height);if(this.virtualAnchor={getBoundingClientRect:()=>bounds,contextElement:normalizedRect.contextElement},this.returnFocusTo=options?.returnFocusTo,this.virtualInteractionBoundary=options?.interactionBoundary,this.syncInteractionTrigger(),this.open){this.updatePopoverRestoreFocusTarget(),this.positionPopup();return}this.show(),!this.open&&(this.virtualAnchor=previousAnchor,this.returnFocusTo=previousReturnFocusTo,this.virtualInteractionBoundary=previousInteractionBoundary,this.syncInteractionTrigger())}resolveAnchor(){return resolveOverlayAnchor(this,{virtualAnchor:this.virtualAnchor,anchor:this.anchor,for:this.for,trigger:this.triggerElement})}positionPopup(){this.invalidatePositioning();const popup=this.renderRoot.querySelector('[part~="popup"]'),arrowElement=this.renderRoot.querySelector('[part~="arrow"]'),bridgeElement=this.renderRoot.querySelector('[part~="hover-bridge"]'),anchor=this.resolveAnchor();if(!this.open||!anchor||!popup){this.positionedAnchor=void 0,this.anchorPositioned=!1;return}anchor!==this.positionedAnchor&&(this.anchorPositioned=!1),this.startPositioning(this.positioningGeneration,anchor,popup,arrowElement,bridgeElement)}invalidatePositioning(){this.positioningGeneration++,this.cleanup?.(),this.cleanup=void 0}startPositioning(generation,anchor,popup,arrowElement,bridgeElement){this.placedTopLayer=syncTopLayerRelease(popup,this.placedTopLayer,this.topLayer);const operation=deferredPlaceReady(anchor,popup,{placement:rtlAwarePlacement(this.placement,this),strategy:this.topLayer?"fixed":this.resolvedPositioningStrategy,topLayer:this.topLayer,offset:finiteNumber(this.distance,this.defaultDistance),skidding:finiteNumber(this.skidding,0),sync:this.positioningSync,arrow:this.rendersArrow&&arrowElement?arrowElement:void 0,arrowPadding:Math.max(0,finiteNumber(this.arrowPadding,0)),hoverBridge:this.rendersHoverBridge&&bridgeElement?bridgeElement:void 0,onPlaced:({placement,arrow})=>{if(generation!==this.positioningGeneration)return;const becamePositioned=!this.anchorPositioned||this.positionedAnchor!==anchor;this.positionedAnchor=anchor,this.anchorPositioned=!0;const side=applyOverlayArrow(arrowElement,{placement,coords:arrow,enabled:this.rendersArrow,arrowPlacement:this.arrowPlacement,arrowPadding:Math.max(0,finiteNumber(this.arrowPadding,0)),rtl:this.effectiveDirection==="rtl",sizeProperty:"--arrow-size",fallbackSizeProperty:"--lr-overlay-arrow-size"});side!==this.resolvedSide&&(this.resolvedSide=side),this.updateComplete.then(()=>{generation!==this.positioningGeneration||!this.open||this.resolveAnchor()!==anchor||becamePositioned&&this.onPopupPositioned()})}});this.cleanup=operation,operation.ready.then(positioned=>{!positioned&&generation===this.positioningGeneration&&this.open&&this.forceClose({focusTrigger:!1})})}syncTriggerA11y(){const popup=this.renderRoot?.querySelector('[part~="popup"]')??null,contribution={attributes:{"aria-haspopup":this.triggerPopupRole==="none"?null:this.triggerPopupRole,"aria-expanded":this.open?"true":"false"},controls:popup?[popup]:[]},accessibleTrigger=this.accessibleTrigger;this.observeAccessibleTrigger(accessibleTrigger);const semanticTrigger=accessibleTrigger&&supportsTriggerExpansion(accessibleTrigger)?accessibleTrigger:null;this.accessibleTriggerAria?this.accessibleTriggerAria.update(semanticTrigger,contribution):this.accessibleTriggerAria=acquireAriaOwnership(semanticTrigger,contribution),this.overlayHandle?.isActive()&&!this.virtualAnchor&&this.overlayHandle.updateRestoreFocusTo(accessibleTrigger)}get accessibleTrigger(){const trigger=this.triggerElement;if(!trigger)return null;const resolved=resolveAccessibleTrigger(trigger);return resolved===trigger&&!trigger.hasAttribute("role")&&!trigger.matches("button, a[href], input, select, textarea, summary")?collectComposedFocusTargets(trigger,{includeRoot:!1,mode:"programmatic"}).elements[0]??trigger:resolved}observeAccessibleTrigger(target){this.accessibleTriggerObserver?.disconnect();const trigger=this.triggerElement;if(!trigger||!this.isConnected)return;const view=this.ownerDocument.defaultView;if(view?.MutationObserver){this.accessibleTriggerObserver??=new view.MutationObserver(()=>{this.isConnected&&this.syncTriggerA11y()});const roots=new Set([trigger]);trigger.shadowRoot&&roots.add(trigger.shadowRoot);let current=target;for(;current&&current!==trigger;){const root=current.getRootNode();if(root.nodeType!==11||!("host"in root))break;roots.add(root),current=root.host}for(const root of roots)this.accessibleTriggerObserver.observe(root,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["role","tabindex","disabled","href","type"]})}this.triggerUpgrades.observeElement(trigger)}releaseTriggerA11y(){this.accessibleTriggerObserver?.disconnect(),this.accessibleTriggerObserver=void 0,this.triggerUpgrades.disconnect(),this.accessibleTriggerAria?.release(),this.accessibleTriggerAria=void 0}collectTriggerFromSlot(slot){const next=slot.assignedElements({flatten:!0})[0];next!==this.slottedTrigger&&(this.slottedTrigger=next,this.syncInteractionTrigger())}requestInteractionClose(next){this.pinned||this.isWithinPopoverSurface(next)||this.hasFocusWithinSurface()||this.requestDelayedTransition(!1)}isWithinPopoverSurface(target){if(target===null||target.nodeType!==1)return!1;const element=target;if(composedContains(this,element))return!0;const popup=this.renderRoot?.querySelector('[part~="popup"]')??null;return popup&&composedContains(popup,element)?!0:this.triggerElement!=null&&composedContains(this.triggerElement,element)}hasFocusWithinSurface(){const active=deepActiveElementIn(this.ownerDocument);return active===null||this.triggerElement&&composedContains(this.triggerElement,active)?!1:this.isWithinPopoverSurface(active)}requestDelayedTransition(next,deferImmediate=!1){if(this.cancelPendingTransition(),next&&!this.canOpen)return;const commit=()=>{next?(this.openedByInteraction=!0,this.show()):this.hide()},delay=Math.max(0,finiteDuration(next?this.showDelay:this.hideDelay,DEFAULT_TRIGGER_DELAY)),view=this.ownerDocument.defaultView;if(!view||delay<=0&&!deferImmediate){commit();return}this.delayTimer.schedule(view,delay,next?"show":"hide",commit)}cancelPendingTransition(){this.delayTimer.cancel()}triggerNeedsOwnFocusListeners(trigger){return!composedContains(this,trigger)}bindTriggerInteractions(trigger){trigger.addEventListener("mouseenter",this.onTriggerPointerEnter),trigger.addEventListener("mouseleave",this.onTriggerPointerLeave),this.triggerNeedsOwnFocusListeners(trigger)&&(trigger.addEventListener("focusin",this.onSurfaceFocusIn),trigger.addEventListener("focusout",this.onSurfaceFocusOut))}unbindTriggerInteractions(trigger){trigger.removeEventListener("mouseenter",this.onTriggerPointerEnter),trigger.removeEventListener("mouseleave",this.onTriggerPointerLeave),trigger.removeEventListener("focusin",this.onSurfaceFocusIn),trigger.removeEventListener("focusout",this.onSurfaceFocusOut)}startLightDismiss(){const nextDocument=this.ownerDocument;this.lightDismissDocument!==nextDocument&&(this.stopLightDismiss(),nextDocument.addEventListener("pointerdown",this.onDocumentPointer),this.lightDismissDocument=nextDocument)}stopLightDismiss(){this.lightDismissDocument?.removeEventListener("pointerdown",this.onDocumentPointer),this.lightDismissDocument=void 0}observeHostId(){const ownerDocument=this.ownerDocument;if(this.hostIdObserver&&this.hostIdObserverDocument===ownerDocument)return;this.resetHostIdObserver();const MutationObserverCtor=ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor||!this.isConnected)return;const generation=this.hostIdObserverGeneration,observer=new MutationObserverCtor(()=>{this.hostIdObserver!==observer||this.hostIdObserverDocument!==ownerDocument||this.hostIdObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument||(this.id||(this.id=this.generatedHostId),this.syncTriggerA11y())});this.hostIdObserver=observer,this.hostIdObserverDocument=ownerDocument,observer.observe(this,{attributes:!0,attributeFilter:["id"]})}resetHostIdObserver(){this.hostIdObserverGeneration+=1,this.hostIdObserver?.disconnect(),this.hostIdObserver=void 0,this.hostIdObserverDocument=void 0}setOpen(next){if(this._open===next)return;const old=this._open;this._open=next,setCustomState(this.popoverInternals,"open",next),this.requestUpdate("open",old)}syncOpenAttribute(){this.toggleAttribute("open",this._open)}show(){return this._open||!this.canOpen?Promise.resolve():this.transitionGate.request(!0,()=>{if(this.emitCancelableLifecycle("lr-show").defaultPrevented){this.syncOpenAttribute();return}if(!this.closePopoverPeers()){this.syncOpenAttribute();return}return this.cancelTransitionAnimation(),this.removeAttribute("data-closing"),this.setOpen(!0),this.settleTransition("lr-after-show")})}hide(options){return this._open?this.transitionGate.request(!1,()=>{if(this.emitCancelableLifecycle("lr-hide").defaultPrevented){this.syncOpenAttribute();return}return this.forceClose(options)}):Promise.resolve()}closePopoverPeers(){if(this.virtualAnchor||this.localName!==tag("popover"))return!0;const root=this.getRootNode();for(const peer of root.querySelectorAll(tag("popover")))if(!(peer===this||!peer.open||peer.virtualAnchor)&&!(composedContains(peer,this)||this.triggerElement&&composedContains(peer,this.triggerElement))&&(peer.hide({focusTrigger:!1}),peer.open))return!1;return!0}reconcileInitialPopoverPeers(){if(!this.isConnected||!this._open||this.virtualAnchor||this.localName!==tag("popover"))return;const peers=[...this.getRootNode().querySelectorAll(tag("popover"))].filter(peer=>peer.isConnected&&peer._open&&!peer.virtualAnchor&&peer.connectionSequence>0);if(peers.reduce((latest,peer)=>!latest||peer.connectionSequence>latest.connectionSequence?peer:latest,void 0)!==this){this.closeForInitialPeerReconciliation();return}for(const peer of peers)peer!==this&&peer.closeForInitialPeerReconciliation()}closeForInitialPeerReconciliation(){this._open&&(this.transitionToken++,this.cancelTransitionAnimation(),this.removeAttribute("data-closing"),this.invalidatePositioning(),this.stopLightDismiss(),this.overlayHandle?.deactivate({restoreFocus:!1}),this.overlayHandle=void 0,this.positionedAnchor=void 0,this.anchorPositioned=!1,this.returnFocusTo=void 0,this.setOpen(!1),this.syncOpenAttribute())}forceClose(options){return this._open?(options?.focusTrigger===!1&&(this.overlayHandle?.deactivate({restoreFocus:!1}),this.overlayHandle=void 0),this.cancelTransitionAnimation(),this.isConnected&&this.setAttribute("data-closing",""),this.setOpen(!1),this.settleTransition("lr-after-hide")):Promise.resolve()}cancelTransitionAnimation(){this.transitionAnimation?.cancel(),this.transitionAnimation=void 0}emitCancelableLifecycle(name){return this.emit(name,null,{cancelable:!0})}emitSettledLifecycle(name){return this.emit(name)}async settleTransition(event){const token=++this.transitionToken,showing=event==="lr-after-show";return settleOverlayTransition({showing,updateComplete:()=>this.updateComplete,isCurrent:()=>this.transitionToken===token,readyToShow:async()=>{const positioned=await waitForDeferredPlacement(()=>this.cleanup);return this.transitionToken===token&&this.open&&positioned&&this.anchorPositioned},animate:async()=>{if(!this.isConnected)return;const popup=this.renderRoot.querySelector('[part~="popup"]'),offset="translateY(var(--lr-size-neg-0-25rem))",animation=popup?animateRegistered(this,popup,`${this.animationNamespace}.${showing?"show":"hide"}`,this.effectiveDirection,{keyframes:showing?[{opacity:0,transform:offset},{opacity:1,transform:"translateY(0)"}]:[{opacity:1,transform:"translateY(0)"},{opacity:0,transform:offset}],durationProperties:this.animationDurationProperties(showing),easingProperties:["--lr-easing-standard"]}):void 0;this.transitionAnimation=animation,await animation?.finished.catch(()=>{}),this.transitionToken===token&&this.cancelTransitionAnimation()},afterHide:()=>{this.removeAttribute("data-closing"),this.popupHidden=!0},settled:()=>{this.emitSettledLifecycle(event)}})}render(){const popupRole=this.popupSurfaceRole;return html`
1
+ import{__decorate}from"tslib";import{GlassScrollLayer}from"../../../internal/glass-scroll-layer.js";import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{hostAriaLabel,nextId,resolveAccessibleTrigger}from"../../../internal/a11y.js";import{collectInitialSlotAssignment}from"../../../internal/initial-slot-collection.js";import{collectComposedFocusTargets}from"../../../internal/focus-navigation.js";import{CustomElementUpgradeObserver}from"../../../internal/custom-element-upgrade-observer.js";import{acquireAriaOwnership}from"../../../internal/aria-ownership.js";import{tag}from"../../../internal/prefix.js";import{resolveEffectivePositioningStrategy}from"../../../internal/positioning-strategy.js";import{deferredPlaceReady,syncTopLayerRelease,waitForDeferredPlacement}from"../../../internal/anchored-overlay-runtime.js";import{rtlAwarePlacement}from"../../../internal/rtl.js";import{finiteDuration,finiteNumber}from"../../../internal/numbers.js";import{deepActiveElementIn}from"../../../internal/active-element.js";import{isKeyboardFocusEvent}from"../../../internal/focus-modality.js";import{literalSetConverter,omittedEmptyStringConverter,optionalLiteralSetConverter}from"../../../internal/converters.js";import{activateNonmodalOverlay,composedContains}from"../../../internal/nonmodal-overlay-manager.js";import{setCustomState}from"../../../internal/custom-states.js";import{attachInternalsSafely}from"../../../internal/element-internals.js";import{animateRegistered}from"../../../internal/registered-animation.js";import{applyOverlayArrow}from"./overlay-arrow.js";import{normalizeVirtualRect,OverlayAnchorIdentity,OverlayDelayTimer,OverlayTransitionGate,resolveOverlayAnchor,resolveOverlayInteractionTrigger,settleOverlayTransition}from"./overlay-shared.js";import{styles}from"./overlay.styles.js";import{glassPopoverStyles}from"./popover-glass.styles.js";import{LYRA_DEFAULT_menuLabel,LYRA_DEFAULT_popover}from"../../../internal/default-strings/shared.generated.js";const DEFAULT_DISTANCE=8,EXPANDABLE_TRIGGER_ROLES=new Set(["application","button","checkbox","combobox","gridcell","link","listbox","menuitem","row","rowheader","tab","treeitem","columnheader","menuitemcheckbox","menuitemradio","switch"]);function supportsTriggerExpansion(element){const role=element.getAttribute("role")?.trim().split(/\s+/)[0];return role?EXPANDABLE_TRIGGER_ROLES.has(role):element.matches("button, a[href], select, summary")?!0:element.localName==="input"&&["button","submit","reset","image","checkbox"].includes(element.type)}let popoverConnectionSequence=0;const POPUP_ROLE=literalSetConverter(["dialog","menu","none"],"dialog"),POPOVER_TRIGGER_KEYWORDS=["click","hover","focus","manual"];function normalizeTriggerList(next){const keywords=[];for(const token of String(next??"").trim().toLowerCase().split(/\s+/)){const keyword=POPOVER_TRIGGER_KEYWORDS.find(candidate=>candidate===token);keyword&&!keywords.includes(keyword)&&keywords.push(keyword)}return keywords.length>0?keywords.join(" "):"click"}const DEFAULT_TRIGGER_DELAY=0,POSITIONING_STRATEGY=optionalLiteralSetConverter(["absolute","fixed"]);class LyraPopover extends LyraElement{static{this.defaultStrings={...super.defaultStrings,menuLabel:LYRA_DEFAULT_menuLabel,popover:LYRA_DEFAULT_popover}}constructor(){super(),this._open=!1,this.placement="top",this.topLayer=!1,this.distance=8,this.skidding=0,this._for="",this.anchor=null,this.interactionBoundary=null,this.withoutArrow=!1,this.arrowPlacement="anchor",this.arrowPadding=0,this._trigger="click",this.showDelay=0,this.hideDelay=0,this.hoverBridge=!1,this.accessibleLabel="",this._popupRole="dialog",this._disabled=!1,this.openedByInteraction=!1,this.pinned=!1,this.suppressTriggerFocusOpen=!1,this.delayTimer=new OverlayDelayTimer,this.resolvedSide="bottom",this.anchorPositioned=!1,this.popupHidden=!0,this.disconnecting=!1,this.reconnectedWhileDisconnecting=!1,this.directionChanged=!1,this.anchorIdentity=new OverlayAnchorIdentity,this.triggerUpgrades=new CustomElementUpgradeObserver(()=>{this.isConnected&&this.syncTriggerA11y()}),this.positioningGeneration=0,this.generatedHostId=nextId("popover"),this.popupId=nextId("popover-popup"),this.hostIdObserverGeneration=0,this.transitionToken=0,this.transitionGate=new OverlayTransitionGate,this.connectionSequence=0,this.popoverInternals=attachInternalsSafely(this),this.onExternalTriggerKeyDown=event=>{this.onTriggerKeyDown(event)},this.onTriggerSlotChange=event=>{this.collectTriggerFromSlot(event.target)},this.onTriggerClick=()=>{if(!this.virtualAnchor&&(this.syncTriggerA11y(),!this.isManualTrigger)){if(this.cancelPendingTransition(),this.opensOn("click")&&!this.opensOn("hover")&&!this.opensOn("focus")){this.open?this.hide():this.show();return}if(this.open&&this.pinned){this.hide();return}this.open||(this.openedByInteraction=!1,this.show()),this.pinned=this.open}},this.onTriggerPointerEnter=()=>{this.opensOn("hover")&&this.requestDelayedTransition(!0)},this.onTriggerPointerLeave=event=>{this.opensOn("hover")&&this.requestInteractionClose(event.relatedTarget)},this.onPopupPointerEnter=()=>{!this.opensOn("hover")||!this.open||this.cancelPendingTransition()},this.onPopupPointerLeave=event=>{this.opensOn("hover")&&this.requestInteractionClose(event.relatedTarget)},this.onSurfaceFocusIn=event=>{!this.opensOn("focus")||this.suppressTriggerFocusOpen||(!this.open||this.triggerElement!=null&&event.composedPath().includes(this.triggerElement))&&!isKeyboardFocusEvent(event)||this.requestDelayedTransition(!0)},this.onSurfaceFocusOut=event=>{this.opensOn("focus")&&this.requestInteractionClose(event.relatedTarget)},this.onPopupClick=event=>{if(event.defaultPrevented)return;const path=event.composedPath(),hostIndex=path.indexOf(this);if(hostIndex<0)return;const closeAction=path.slice(0,hostIndex).find(target=>target.nodeType===1&&target.getAttribute("data-popover")==="close");if(!closeAction)return;event.stopPropagation();const state2=closeAction;state2.effectiveDisabled===!0||state2.disabled===!0||closeAction.hasAttribute("disabled")||closeAction.getAttribute("aria-disabled")?.trim().toLowerCase()==="true"||closeAction.hasAttribute("inert")||closeAction.closest("[inert]")||this.hide()},this.onDocumentPointer=event=>{this.overlayHandle?.isTopmost()&&(this.isInsideLightDismissBoundary(event.composedPath())||this.hide())},new GlassScrollLayer(this,'[part~="popup"]')}static{this.styles=[LyraElement.styles,styles,glassPopoverStyles]}get open(){return this._open}set open(next){const normalized=!!next&&this.canOpen;if(normalized!==this._open){if(!this.hasUpdated){this.setOpen(normalized),this.isConnected&&this.connectionSequence>0&&this.updateBrowserDerivedState(()=>this.reconcileInitialPopoverPeers());return}normalized?this.show():this.hide()}}get positioningStrategy(){return this._positioningStrategy??this.defaultPositioningStrategy}set positioningStrategy(next){const normalized=POSITIONING_STRATEGY.normalize(next)??this.defaultPositioningStrategy,old=this.positioningStrategy;this._positioningStrategy=normalized,normalized!==old&&(this.requestUpdate("positioningStrategy",old),this.onPositioningStrategyChanged(old,normalized))}onPositioningStrategyChanged(_previous,_next){}get for(){return this._for}set for(next){this._for=next??""}get trigger(){return this._trigger}set trigger(next){const normalized=normalizeTriggerList(next);if(normalized===this._trigger)return;const old=this._trigger;this._trigger=normalized,this.requestUpdate("trigger",old)}get triggerKeywords(){return new Set(this._trigger.split(" "))}get isManualTrigger(){return this.triggerKeywords.has("manual")}opensOn(keyword){return!this.isManualTrigger&&this.triggerKeywords.has(keyword)}get popupRole(){return this._popupRole}set popupRole(next){const normalized=POPUP_ROLE.normalize(next);if(normalized===this._popupRole)return;const old=this._popupRole;this._popupRole=normalized,this.requestUpdate("popupRole",old)}get disabled(){return this._disabled}set disabled(next){const normalized=!!next;if(normalized===this._disabled)return;const old=this._disabled;this._disabled=normalized,this.requestUpdate("disabled",old),normalized&&this.open&&(this.hasUpdated?this.hide():this.open=!1)}get defaultDistance(){return DEFAULT_DISTANCE}get defaultPositioningStrategy(){return"fixed"}get resolvedPositioningStrategy(){return resolveEffectivePositioningStrategy(this,this._positioningStrategy,this.defaultPositioningStrategy)}get positioningSync(){}get animationNamespace(){return"popover"}animationDurationProperties(showing){return[showing?"--show-duration":"--hide-duration","--lr-duration-fast"]}get popupPartNames(){return["popup","dialog","popup__popup"].join(" ")}get contentPartNames(){return["content","body"].join(" ")}get triggerPopupRole(){return this.popupRole}get popupSurfaceRole(){return this.popupRole==="none"?void 0:this.popupRole}get effectivePopupLabel(){return hostAriaLabel(this)??(this.accessibleLabel||this.localize(this.triggerPopupRole==="menu"?"menuLabel":"popover"))}get rendersArrow(){return!this.withoutArrow}get arrowPartNames(){return"arrow popup__arrow"}get rendersHoverBridge(){return this.hoverBridge&&this.opensOn("hover")&&this.open}get canOpen(){return!this.disabled}renderPopupContent(){return html`<slot></slot>`}onTriggerKeyDown(_event){}isInsideLightDismissBoundary(path){const boundary=this.virtualAnchor?this.virtualInteractionBoundary:this.interactionBoundary;return path.includes(this)||this.triggerElement!=null&&path.includes(this.triggerElement)||boundary!=null&&boundary.isConnected&&boundary.ownerDocument===this.ownerDocument&&path.includes(boundary)}onPopupPositioned(){this.openedByInteraction||this.overlayHandle?.focusAutofocus()}willUpdate(changed){super.willUpdate(changed);const direction=this.effectiveDirection;this.directionChanged=direction!==this.positioningDirection,this.positioningDirection=direction,this.anchorIdentity.lostAnchorProperty(changed,this.anchor)&&this.open&&!this.resolveAnchor()&&this.forceClose({focusTrigger:!1}),changed.has("open")&&!this.open&&(this.anchorPositioned=!1),changed.has("open")&&this.open&&(this.popupHidden=!1),(changed.has("anchor")||changed.has("for"))&&(this.anchorPositioned=!1)}updated(changed){if(super.updated(changed),changed.has("trigger")&&(this.cancelPendingTransition(),!this.opensOn("hover")&&!this.opensOn("focus")&&(this.pinned=!1)),changed.has("showDelay")&&this.delayTimer.pendingDirection==="show"&&this.requestDelayedTransition(!0,!0),changed.has("hideDelay")&&this.delayTimer.pendingDirection==="hide"&&this.requestDelayedTransition(!1,!0),(changed.has("for")||changed.has("anchor")||changed.has("open"))&&this.syncAnchorIdentityObservation(),changed.has("for")&&this.syncInteractionTrigger(),this.directionChanged||changed.has("open")||changed.has("placement")||changed.has("positioningStrategy")||changed.has("topLayer")||changed.has("hoverBridge")||changed.has("trigger")||changed.has("distance")||changed.has("skidding")||changed.has("for")||changed.has("anchor")||changed.has("arrow")||changed.has("withoutArrow")||changed.has("arrowPlacement")||changed.has("arrowPadding")||changed.has("popupRole")){if(this.open&&this.isConnected?this.positionPopup():changed.has("open")&&this.invalidatePositioning(),changed.has("open"))if(this.open)this.isConnected&&(this.startLightDismiss(),this.activatePopoverOverlay());else{this.pinned=!1,this.openedByInteraction=!1,this.cancelPendingTransition(),this.positionedAnchor=void 0,this.stopLightDismiss(),this.suppressTriggerFocusOpen=!0;try{this.overlayHandle?.deactivate()}finally{this.suppressTriggerFocusOpen=!1}this.overlayHandle=void 0,this.virtualAnchor=void 0,this.returnFocusTo=void 0,this.virtualInteractionBoundary=void 0,this.syncInteractionTrigger()}this.isConnected&&this.syncTriggerA11y()}}firstUpdated(changed){super.firstUpdated(changed);const slot=this.triggerSlotElement;queueMicrotask(()=>{collectInitialSlotAssignment(slot,s=>this.collectTriggerFromSlot(s))})}connectedCallback(){if(this.disconnecting){this.reconnectedWhileDisconnecting=!0;return}if(super.connectedCallback(),this.connectionSequence=++popoverConnectionSequence,this.addEventListener("focusin",this.onSurfaceFocusIn),this.addEventListener("focusout",this.onSurfaceFocusOut),this.updateBrowserDerivedState(()=>this.reconcileInitialPopoverPeers()),this.syncAnchorIdentityObservation(),this.id||(this.id=this.generatedHostId),this.observeHostId(),this.syncInteractionTrigger(),this.hasUpdated&&this.open){const wasPreviouslyActivated=this.overlayHandle?.isActive()===!0;this.startLightDismiss(),wasPreviouslyActivated?this.overlayHandle.resume():this.activatePopoverOverlay(),this.popupHidden=!1,this.positionPopup()}}disconnectedCallback(){this.disconnecting=!0;try{this.teardownOnDisconnect(),super.disconnectedCallback()}finally{this.disconnecting=!1}this.reconnectedWhileDisconnecting&&(this.reconnectedWhileDisconnecting=!1,this.isConnected&&this.connectedCallback())}teardownOnDisconnect(){this.anchorIdentity.stop(),this.invalidatePositioning(),this.stopLightDismiss(),this.resetHostIdObserver(),this.overlayHandle?.suspend(),this.triggerElement?.removeEventListener("click",this.onTriggerClick),this.triggerElement?.removeEventListener("keydown",this.onExternalTriggerKeyDown),this.triggerElement&&this.unbindTriggerInteractions(this.triggerElement),this.releaseTriggerA11y(),this.triggerElement=void 0,this.removeEventListener("focusin",this.onSurfaceFocusIn),this.removeEventListener("focusout",this.onSurfaceFocusOut),this.cancelPendingTransition(),this.virtualInteractionBoundary=void 0,this.pinned=!1,this.openedByInteraction=!1,this.transitionToken++,this.cancelTransitionAnimation(),this.removeAttribute("data-closing"),this.popupHidden=!0}adoptedCallback(){super.adoptedCallback(),this.anchorIdentity.stop(),this.resetHostIdObserver(),this.releaseTriggerA11y()}syncAnchorIdentityObservation(){this.anchorIdentity.stop();const directAnchor=this.open?this.anchor??void 0:void 0;this.anchorIdentity.observe(this,directAnchor,this.for,()=>this.anchor,directAnchorRemoved=>{if(this.resolveInteractionTrigger()!==this.triggerElement&&this.syncInteractionTrigger(),!this.open)return;const nextAnchor=this.resolveAnchor();if(directAnchorRemoved&&!nextAnchor){this.forceClose({focusTrigger:!1});return}nextAnchor!==this.positionedAnchor&&this.positionPopup()})}resolveInteractionTrigger(){return resolveOverlayInteractionTrigger(this,this.virtualAnchor,this.slottedTrigger,this.for)}syncInteractionTrigger(){if(!this.isConnected)return;const next=this.resolveInteractionTrigger();if(next===this.triggerElement){this.syncTriggerA11y();return}const previous=this.triggerElement;if(previous?.removeEventListener("click",this.onTriggerClick),previous?.removeEventListener("keydown",this.onExternalTriggerKeyDown),previous&&this.unbindTriggerInteractions(previous),this.triggerElement=next,this.triggerUpgrades.disconnect(),this.triggerElement&&this.triggerElement!==this.slottedTrigger&&(this.triggerElement.addEventListener("click",this.onTriggerClick),this.triggerElement.addEventListener("keydown",this.onExternalTriggerKeyDown)),this.triggerElement&&this.bindTriggerInteractions(this.triggerElement),this.syncTriggerA11y(),this.open){if(previous&&next&&this.openedByInteraction&&!this.pinned&&![next,this].some(element=>element.matches(":hover"))&&!this.isWithinPopoverSurface(deepActiveElementIn(this.ownerDocument))||!this.resolveAnchor()){this.forceClose({focusTrigger:!1});return}this.updatePopoverRestoreFocusTarget(),this.positionPopup()}}activatePopoverOverlay(){!this.isConnected||this.overlayHandle?.isActive()||(this.overlayHandle=activateNonmodalOverlay({host:this,panel:()=>this.renderRoot.querySelector('[part~="popup"]'),onEscape:()=>{this.hide()},restoreFocusTo:this.virtualAnchor?this.returnFocusTo??null:this.accessibleTrigger}))}updatePopoverRestoreFocusTarget(){const target=this.virtualAnchor?this.returnFocusTo??null:this.accessibleTrigger;if(this.overlayHandle?.isActive()){this.overlayHandle.updateRestoreFocusTo(target);return}this.activatePopoverOverlay()}showAt(rect,options){const normalizedRect=normalizeVirtualRect(rect);if(!normalizedRect)return;const previousAnchor=this.virtualAnchor,previousReturnFocusTo=this.returnFocusTo,previousInteractionBoundary=this.virtualInteractionBoundary,bounds=new DOMRect(normalizedRect.x,normalizedRect.y,normalizedRect.width,normalizedRect.height);if(this.virtualAnchor={getBoundingClientRect:()=>bounds,contextElement:normalizedRect.contextElement},this.returnFocusTo=options?.returnFocusTo,this.virtualInteractionBoundary=options?.interactionBoundary,this.syncInteractionTrigger(),this.open){this.updatePopoverRestoreFocusTarget(),this.positionPopup();return}this.show(),!this.open&&(this.virtualAnchor=previousAnchor,this.returnFocusTo=previousReturnFocusTo,this.virtualInteractionBoundary=previousInteractionBoundary,this.syncInteractionTrigger())}resolveAnchor(){return resolveOverlayAnchor(this,{virtualAnchor:this.virtualAnchor,anchor:this.anchor,for:this.for,trigger:this.triggerElement})}positionPopup(){this.invalidatePositioning();const popup=this.renderRoot.querySelector('[part~="popup"]'),arrowElement=this.renderRoot.querySelector('[part~="arrow"]'),bridgeElement=this.renderRoot.querySelector('[part~="hover-bridge"]'),anchor=this.resolveAnchor();if(!this.open||!anchor||!popup){this.positionedAnchor=void 0,this.anchorPositioned=!1;return}anchor!==this.positionedAnchor&&(this.anchorPositioned=!1),this.startPositioning(this.positioningGeneration,anchor,popup,arrowElement,bridgeElement)}invalidatePositioning(){this.positioningGeneration++,this.cleanup?.(),this.cleanup=void 0}startPositioning(generation,anchor,popup,arrowElement,bridgeElement){this.placedTopLayer=syncTopLayerRelease(popup,this.placedTopLayer,this.topLayer);const operation=deferredPlaceReady(anchor,popup,{placement:rtlAwarePlacement(this.placement,this),strategy:this.topLayer?"fixed":this.resolvedPositioningStrategy,topLayer:this.topLayer,offset:finiteNumber(this.distance,this.defaultDistance),skidding:finiteNumber(this.skidding,0),sync:this.positioningSync,arrow:this.rendersArrow&&arrowElement?arrowElement:void 0,arrowPadding:Math.max(0,finiteNumber(this.arrowPadding,0)),hoverBridge:this.rendersHoverBridge&&bridgeElement?bridgeElement:void 0,onPlaced:({placement,arrow})=>{if(generation!==this.positioningGeneration)return;const becamePositioned=!this.anchorPositioned||this.positionedAnchor!==anchor;this.positionedAnchor=anchor,this.anchorPositioned=!0;const side=applyOverlayArrow(arrowElement,{placement,coords:arrow,enabled:this.rendersArrow,arrowPlacement:this.arrowPlacement,arrowPadding:Math.max(0,finiteNumber(this.arrowPadding,0)),rtl:this.effectiveDirection==="rtl",sizeProperty:"--arrow-size",fallbackSizeProperty:"--lr-overlay-arrow-size"});side!==this.resolvedSide&&(this.resolvedSide=side),this.updateComplete.then(()=>{generation!==this.positioningGeneration||!this.open||this.resolveAnchor()!==anchor||becamePositioned&&this.onPopupPositioned()})}});this.cleanup=operation,operation.ready.then(positioned=>{!positioned&&generation===this.positioningGeneration&&this.open&&this.forceClose({focusTrigger:!1})})}syncTriggerA11y(){const popup=this.renderRoot?.querySelector('[part~="popup"]')??null,contribution={attributes:{"aria-haspopup":this.triggerPopupRole==="none"?null:this.triggerPopupRole,"aria-expanded":this.open?"true":"false"},controls:popup?[popup]:[]},accessibleTrigger=this.accessibleTrigger;this.observeAccessibleTrigger(accessibleTrigger);const semanticTrigger=accessibleTrigger&&supportsTriggerExpansion(accessibleTrigger)?accessibleTrigger:null;this.accessibleTriggerAria?this.accessibleTriggerAria.update(semanticTrigger,contribution):this.accessibleTriggerAria=acquireAriaOwnership(semanticTrigger,contribution),this.overlayHandle?.isActive()&&!this.virtualAnchor&&this.overlayHandle.updateRestoreFocusTo(accessibleTrigger)}get accessibleTrigger(){const trigger=this.triggerElement;if(!trigger)return null;const resolved=resolveAccessibleTrigger(trigger);return resolved===trigger&&!trigger.hasAttribute("role")&&!trigger.matches("button, a[href], input, select, textarea, summary")?collectComposedFocusTargets(trigger,{includeRoot:!1,mode:"programmatic"}).elements[0]??trigger:resolved}observeAccessibleTrigger(target){this.accessibleTriggerObserver?.disconnect();const trigger=this.triggerElement;if(!trigger||!this.isConnected)return;const view=this.ownerDocument.defaultView;if(view?.MutationObserver){this.accessibleTriggerObserver??=new view.MutationObserver(()=>{this.isConnected&&this.syncTriggerA11y()});const roots=new Set([trigger]);trigger.shadowRoot&&roots.add(trigger.shadowRoot);let current=target;for(;current&&current!==trigger;){const root=current.getRootNode();if(root.nodeType!==11||!("host"in root))break;roots.add(root),current=root.host}for(const root of roots)this.accessibleTriggerObserver.observe(root,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["role","tabindex","disabled","href","type"]})}this.triggerUpgrades.observeElement(trigger)}releaseTriggerA11y(){this.accessibleTriggerObserver?.disconnect(),this.accessibleTriggerObserver=void 0,this.triggerUpgrades.disconnect(),this.accessibleTriggerAria?.release(),this.accessibleTriggerAria=void 0}collectTriggerFromSlot(slot){const next=slot.assignedElements({flatten:!0})[0];next!==this.slottedTrigger&&(this.slottedTrigger=next,this.syncInteractionTrigger())}requestInteractionClose(next){this.pinned||this.isWithinPopoverSurface(next)||this.hasFocusWithinSurface()||this.requestDelayedTransition(!1)}isWithinPopoverSurface(target){if(target===null||target.nodeType!==1)return!1;const element=target;if(composedContains(this,element))return!0;const popup=this.renderRoot?.querySelector('[part~="popup"]')??null;return popup&&composedContains(popup,element)?!0:this.triggerElement!=null&&composedContains(this.triggerElement,element)}hasFocusWithinSurface(){const active=deepActiveElementIn(this.ownerDocument);return active===null||this.triggerElement&&composedContains(this.triggerElement,active)?!1:this.isWithinPopoverSurface(active)}requestDelayedTransition(next,deferImmediate=!1){if(this.cancelPendingTransition(),next&&!this.canOpen)return;const commit=()=>{next?(this.openedByInteraction=!0,this.show()):this.hide()},delay=Math.max(0,finiteDuration(next?this.showDelay:this.hideDelay,DEFAULT_TRIGGER_DELAY)),view=this.ownerDocument.defaultView;if(!view||delay<=0&&!deferImmediate){commit();return}this.delayTimer.schedule(view,delay,next?"show":"hide",commit)}cancelPendingTransition(){this.delayTimer.cancel()}triggerNeedsOwnFocusListeners(trigger){return!composedContains(this,trigger)}bindTriggerInteractions(trigger){trigger.addEventListener("mouseenter",this.onTriggerPointerEnter),trigger.addEventListener("mouseleave",this.onTriggerPointerLeave),this.triggerNeedsOwnFocusListeners(trigger)&&(trigger.addEventListener("focusin",this.onSurfaceFocusIn),trigger.addEventListener("focusout",this.onSurfaceFocusOut))}unbindTriggerInteractions(trigger){trigger.removeEventListener("mouseenter",this.onTriggerPointerEnter),trigger.removeEventListener("mouseleave",this.onTriggerPointerLeave),trigger.removeEventListener("focusin",this.onSurfaceFocusIn),trigger.removeEventListener("focusout",this.onSurfaceFocusOut)}startLightDismiss(){const nextDocument=this.ownerDocument;this.lightDismissDocument!==nextDocument&&(this.stopLightDismiss(),nextDocument.addEventListener("pointerdown",this.onDocumentPointer),this.lightDismissDocument=nextDocument)}stopLightDismiss(){this.lightDismissDocument?.removeEventListener("pointerdown",this.onDocumentPointer),this.lightDismissDocument=void 0}observeHostId(){const ownerDocument=this.ownerDocument;if(this.hostIdObserver&&this.hostIdObserverDocument===ownerDocument)return;this.resetHostIdObserver();const MutationObserverCtor=ownerDocument.defaultView?.MutationObserver;if(!MutationObserverCtor||!this.isConnected)return;const generation=this.hostIdObserverGeneration,observer=new MutationObserverCtor(()=>{this.hostIdObserver!==observer||this.hostIdObserverDocument!==ownerDocument||this.hostIdObserverGeneration!==generation||!this.isConnected||this.ownerDocument!==ownerDocument||(this.id||(this.id=this.generatedHostId),this.syncTriggerA11y())});this.hostIdObserver=observer,this.hostIdObserverDocument=ownerDocument,observer.observe(this,{attributes:!0,attributeFilter:["id"]})}resetHostIdObserver(){this.hostIdObserverGeneration+=1,this.hostIdObserver?.disconnect(),this.hostIdObserver=void 0,this.hostIdObserverDocument=void 0}setOpen(next){if(this._open===next)return;const old=this._open;this._open=next,setCustomState(this.popoverInternals,"open",next),this.requestUpdate("open",old)}syncOpenAttribute(){this.toggleAttribute("open",this._open)}show(){return this._open||!this.canOpen?Promise.resolve():this.transitionGate.request(!0,()=>{if(this.emitCancelableLifecycle("lr-show").defaultPrevented){this.syncOpenAttribute();return}if(!this.closePopoverPeers()){this.syncOpenAttribute();return}return this.cancelTransitionAnimation(),this.removeAttribute("data-closing"),this.setOpen(!0),this.settleTransition("lr-after-show")})}hide(options){return this._open?this.transitionGate.request(!1,()=>{if(this.emitCancelableLifecycle("lr-hide").defaultPrevented){this.syncOpenAttribute();return}return this.forceClose(options)}):Promise.resolve()}closePopoverPeers(){if(this.virtualAnchor||this.localName!==tag("popover"))return!0;const root=this.getRootNode();for(const peer of root.querySelectorAll(tag("popover")))if(!(peer===this||!peer.open||peer.virtualAnchor)&&!(composedContains(peer,this)||this.triggerElement&&composedContains(peer,this.triggerElement))&&(peer.hide({focusTrigger:!1}),peer.open))return!1;return!0}reconcileInitialPopoverPeers(){if(!this.isConnected||!this._open||this.virtualAnchor||this.localName!==tag("popover"))return;const peers=[...this.getRootNode().querySelectorAll(tag("popover"))].filter(peer=>peer.isConnected&&peer._open&&!peer.virtualAnchor&&peer.connectionSequence>0);if(peers.reduce((latest,peer)=>!latest||peer.connectionSequence>latest.connectionSequence?peer:latest,void 0)!==this){this.closeForInitialPeerReconciliation();return}for(const peer of peers)peer!==this&&peer.closeForInitialPeerReconciliation()}closeForInitialPeerReconciliation(){this._open&&(this.transitionToken++,this.cancelTransitionAnimation(),this.removeAttribute("data-closing"),this.invalidatePositioning(),this.stopLightDismiss(),this.overlayHandle?.deactivate({restoreFocus:!1}),this.overlayHandle=void 0,this.positionedAnchor=void 0,this.anchorPositioned=!1,this.returnFocusTo=void 0,this.setOpen(!1),this.syncOpenAttribute())}forceClose(options){return this._open?(options?.focusTrigger===!1&&(this.overlayHandle?.deactivate({restoreFocus:!1}),this.overlayHandle=void 0),this.cancelTransitionAnimation(),this.isConnected&&this.setAttribute("data-closing",""),this.setOpen(!1),this.settleTransition("lr-after-hide")):Promise.resolve()}cancelTransitionAnimation(){this.transitionAnimation?.cancel(),this.transitionAnimation=void 0}emitCancelableLifecycle(name){return this.emit(name,null,{cancelable:!0})}emitSettledLifecycle(name){return this.emit(name)}async settleTransition(event){const token=++this.transitionToken,showing=event==="lr-after-show";return settleOverlayTransition({showing,updateComplete:()=>this.updateComplete,isCurrent:()=>this.transitionToken===token,readyToShow:async()=>{const positioned=await waitForDeferredPlacement(()=>this.cleanup);return this.transitionToken===token&&this.open&&positioned&&this.anchorPositioned},animate:async()=>{if(!this.isConnected)return;const popup=this.renderRoot.querySelector('[part~="popup"]'),offset="translateY(var(--lr-size-neg-0-25rem))",animation=popup?animateRegistered(this,popup,`${this.animationNamespace}.${showing?"show":"hide"}`,this.effectiveDirection,{keyframes:showing?[{opacity:0,transform:offset},{opacity:1,transform:"translateY(0)"}]:[{opacity:1,transform:"translateY(0)"},{opacity:0,transform:offset}],durationProperties:this.animationDurationProperties(showing),easingProperties:["--lr-easing-standard"]}):void 0;this.transitionAnimation=animation,await animation?.finished.catch(()=>{}),this.transitionToken===token&&this.cancelTransitionAnimation()},afterHide:()=>{this.removeAttribute("data-closing"),this.popupHidden=!0},settled:()=>{this.emitSettledLifecycle(event)}})}render(){const popupRole=this.popupSurfaceRole;return html`
2
2
  <span part="trigger" @click=${this.onTriggerClick} @keydown=${this.onTriggerKeyDown}>
3
3
  <slot name="trigger" @slotchange=${this.onTriggerSlotChange}></slot>
4
4
  </span>
@@ -261,7 +261,7 @@ selectedEdgeIds:readonly string[];
261
261
  dimmedNodeIds:readonly string[];
262
262
  /** Same contract as `dimmedNodeIds`, for edges. An edge's dimming key is the same `linkKey()`
263
263
  * value (`LyraGraphEdge.id`, else `` `${source}->${target}` ``) `selectedEdgeIds` already uses. */
264
- dimmedEdgeIds:readonly string[];private readonly arrowMarkerId;private loading;private loadFailed;private loadLibrary;private loadGeneration;private containerSize;private simNodes;private simLinks;private simNodeById;private danglingLinks;private lastPositionById;private lastHiddenNodeCount;private activeGraphItem;private graphLiveText;private readonly announcements;private graphAnnouncementsReady;private pendingGraphItemFocus;private isMounting;private authorRole;private syncingGraphHostRole;private simulation?;private chargeForce?;private linkForce?;private d3?;private zoomedEl?;private gEl?;private zoomBehavior?;private boundNodeEls;private nodeEls;private nodeHitEls;private nodeLabelEls;private expandIndicatorEls;private lastKeyActivateIndex;private lastKeyActivateTime;private lastActivation?;private lastAppliedFocusNodeId;private focusHaloEl?;private communityHullEls;private communityHullHitEls;private communityLabelEls;private canvasEl?;private canvasCtx?;private pickCanvas?;private pickCtx?;private hostResizeObserver?;private hostResizeObserverDocument?;private canvasDprQuery?;private canvasDrawRafId?;private canvasDrawRafOwner?;private visible;private intersectionObserver?;private canvasDrawPending;private pickDirty;private canvasCamera;private canvasTooltipEl?;private pickItems;private canvasDragNode?;private canvasPointerId?;private canvasPointerDownAt?;private canvasPointerDownId?;private pendingHover?;private canvasHover?;private hoverRafId?;private hoverRafOwner?;private svgHoverNodeId?;private canvasScene?;private canvasSceneHasEdgeLabels;private cameraTweenId?;private cameraTweenFrameOwner?;private cameraTweenResolve?;private isCameraTweening;private viewportChangeRafId?;private viewportChangeRafOwner?;private linkEls;private linkHitEls;private linkLabelEls;private linkLabelHiddenByLength;private edgeLabelWidthCache;private danglingLinkEls;private edgeLabelMeasureCanvas?;private edgeLabelMeasureCtx?;private linkPaintProbe?;private readonly linkPaintVisibilityCache;private readonly resolvedCssColorCache;private reducedMotion;constructor();attributeChangedCallback(name:string,oldValue:string|null,value:string|null):void;private hostOwnsGraphSemantics;private syncGraphHostRole;private get ownerWindow();private computedStyle;connectedCallback():void;disconnectedCallback():void;adoptedCallback():void;private scheduleViewportChange;private nodeRadius;private safeLinkWidth;private isInteractiveLink;private navigableLinksCache?;private navigableLinks;private lengthInPixels;private get requestedWidth();private get requestedHeight();private get safeWidth();private get safeHeight();private recordContainerSize;private measureHostBox;private syncRequestedHeightVar;private get safeMinZoom();private get safeMaxZoom();private get effectiveZoomBounds();private get safeEdgeLabelMinZoom();private get resolvedNodeLabelsMode();private canvasNodeLabelsVisible;private get safeSeed();private get safeChargeStrength();private get safeLinkDistance();private nodeTypeIndex?;private nodeTypeEntry;private resolveNodeType;private nodeShape;private labeledNodeTypes;private nodeFill;private visibleNodes;private resolveLinksAgainst;private communityMembers;private visibleCommunitiesCache?;private visibleCommunities;private communityHull;private onCommunityClick;private cameraTransitionMs;private cancelCameraTween;private isApplyingZoomTransform;private applyZoomTransform;private tweenCamera;
264
+ dimmedEdgeIds:readonly string[];private readonly arrowMarkerId;private loading;private loadFailed;private loadLibrary;private loadGeneration;private containerSize;private simNodes;private simLinks;private simNodeById;private danglingLinks;private lastPositionById;private lastHiddenNodeCount;private activeGraphItem;private graphLiveText;private readonly announcements;private graphAnnouncementsReady;private pendingGraphItemFocus;private isMounting;private authorRole;private syncingGraphHostRole;private simulation?;private chargeForce?;private linkForce?;private d3?;private detachedGraphChanges;private zoomedEl?;private gEl?;private zoomBehavior?;private boundNodeEls;private nodeEls;private nodeHitEls;private nodeLabelEls;private expandIndicatorEls;private lastKeyActivateIndex;private lastKeyActivateTime;private lastActivation?;private lastAppliedFocusNodeId;private focusHaloEl?;private communityHullEls;private communityHullHitEls;private communityLabelEls;private canvasEl?;private canvasCtx?;private pickCanvas?;private pickCtx?;private hostResizeObserver?;private hostResizeObserverDocument?;private canvasDprQuery?;private canvasDrawRafId?;private canvasDrawRafOwner?;private visible;private intersectionObserver?;private canvasDrawPending;private pickDirty;private canvasCamera;private canvasTooltipEl?;private pickItems;private canvasDragNode?;private canvasPointerId?;private canvasPointerDownAt?;private canvasPointerDownId?;private pendingHover?;private canvasHover?;private hoverRafId?;private hoverRafOwner?;private svgHoverNodeId?;private canvasScene?;private canvasSceneHasEdgeLabels;private cameraTweenId?;private cameraTweenFrameOwner?;private cameraTweenResolve?;private isCameraTweening;private viewportChangeRafId?;private viewportChangeRafOwner?;private linkEls;private linkHitEls;private linkLabelEls;private linkLabelHiddenByLength;private edgeLabelWidthCache;private danglingLinkEls;private edgeLabelMeasureCanvas?;private edgeLabelMeasureCtx?;private linkPaintProbe?;private readonly linkPaintVisibilityCache;private readonly resolvedCssColorCache;private reducedMotion;constructor();attributeChangedCallback(name:string,oldValue:string|null,value:string|null):void;private hostOwnsGraphSemantics;private syncGraphHostRole;private get ownerWindow();private computedStyle;connectedCallback():void;disconnectedCallback():void;adoptedCallback():void;private scheduleViewportChange;private nodeRadius;private safeLinkWidth;private isInteractiveLink;private navigableLinksCache?;private navigableLinks;private lengthInPixels;private get requestedWidth();private get requestedHeight();private get safeWidth();private get safeHeight();private recordContainerSize;private measureHostBox;private syncRequestedHeightVar;private get safeMinZoom();private get safeMaxZoom();private get effectiveZoomBounds();private get safeEdgeLabelMinZoom();private get resolvedNodeLabelsMode();private canvasNodeLabelsVisible;private get safeSeed();private get safeChargeStrength();private get safeLinkDistance();private nodeTypeIndex?;private nodeTypeEntry;private resolveNodeType;private nodeShape;private labeledNodeTypes;private nodeFill;private visibleNodes;private resolveLinksAgainst;private communityMembers;private visibleCommunitiesCache?;private visibleCommunities;private communityHull;private onCommunityClick;private cameraTransitionMs;private cancelCameraTween;private isApplyingZoomTransform;private applyZoomTransform;private tweenCamera;
265
265
  /** Animates the camera so `id` centers in the viewport (the `width` x `height` viewBox), at
266
266
  * `options.zoom` (clamped to `[minZoom, maxZoom]`) or the current scale when omitted. Resolves
267
267
  * `true` on arrival; `false` for an id with no matching entry in `simNodes` -- there's nothing
@@ -1,4 +1,4 @@
1
- import{__decorate}from"tslib";import{collectionSupport,publicCollectionTruncation}from"../../../internal/collection-snapshot.js";import{html,nothing,svg}from"lit";import{property,state,query}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{fitTransform}from"../../../internal/fit-transform.js";import{specialistTokens}from"../../../internal/specialist-host-tokens.styles.js";import{nextId,srOnly}from"../../../internal/a11y.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{isRtl}from"../../../internal/rtl.js";import{literalSetConverter}from"../../../internal/converters.js";import{resolveCssTokenLength}from"../../../internal/css-token-length.js";import{styles}from"./graph.styles.js";import{loadD3}from"./graph-loader.js";import{convexHull,hullPathD,hullCentroidX,hullTopY}from"./graph-hull.js";import{EXPAND_BADGE_OFFSET,EXPAND_BADGE_R,drawGraphScene,drawPickingScene,pickColorToIndex,shapeHalfSide}from"./graph-canvas.js";import{layeredLayout}from"../../../internal/layered-layout.js";import{finiteNumber,finiteRange,finiteInteger,extent}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{sanitizeCssColor}from"../../../internal/safe-css.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{shadowFocusTarget}from"../../../internal/active-element.js";import{ThemeWatcher}from"../../../internal/theme-watcher.js";import{devWarnOnce}from"../../../internal/dev-warning.js";import{copyGraphLinkIdentity,graphLengthConverter,graphLinkIdentity,normalizeGraphModel}from"./graph-model.js";import{canonicalIdentityList}from"../retrieval-identity.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import"../../overlays/skeleton/skeleton.class.js";import{LYRA_DEFAULT_graphCommunity,LYRA_DEFAULT_graphDataList,LYRA_DEFAULT_graphDataListLimit,LYRA_DEFAULT_graphDiagram,LYRA_DEFAULT_graphEdgeLimit,LYRA_DEFAULT_graphExpandableItem,LYRA_DEFAULT_graphItemAnnouncement,LYRA_DEFAULT_graphLink,LYRA_DEFAULT_graphMissingLibrary,LYRA_DEFAULT_graphNode,LYRA_DEFAULT_graphNodeFocused,LYRA_DEFAULT_graphNodeLimit,LYRA_DEFAULT_graphNodesHidden,LYRA_DEFAULT_graphSelectionCount,LYRA_DEFAULT_graphTypedNode}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_loading,LYRA_DEFAULT_noData}from"../../../internal/default-strings/shared.generated.js";const GRAPH_LAYOUT=literalSetConverter(["force","layered"],"force"),STUB_OFFSET_PX=14,EDGE_LABEL_OFFSET_PX=4,DEFAULT_EDGE_LABEL_FONT_PX=10,EDGE_LABEL_LENGTH_GATE_RATIO=.85,EDGE_LABEL_WIDTH_CACHE_MAX=512,EXPAND_KEY_INTERVAL_MS=500,FOCUS_HALO_PADDING=6,HULL_PADDING=24,NODE_LABEL_MIN_ZOOM=.5,NODE_HIT_SEGMENT_HALF=.5;function ownGraphText(value,property2){const descriptor=getOwnDataDescriptor(value,property2);return descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR||typeof descriptor.value!="string"?void 0:descriptor.value}function ownGraphValue(value,property2){const descriptor=getOwnDataDescriptor(value,property2);return descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR?void 0:descriptor.value}function mulberry32(seed){let a=seed>>>0;return()=>{a=a+1831565813|0;let t=Math.imul(a^a>>>15,a|1);return t=t+Math.imul(t^t>>>7,t|61)^t,((t^t>>>14)>>>0)/4294967296}}function hashNodeSeed(seed,id){let h=seed>>>0;for(let i=0;i<id.length;i++)h=Math.imul(h^id.charCodeAt(i),2654435761),h^=h>>>15;return h>>>0}const MIN_RADIUS=6,MAX_RADIUS=24;function sanitizeNodeColor(color){return sanitizeCssColor(color)}function normalizeLinkDash(dash){if(!(!dash?.length||dash.some(value=>!Number.isFinite(value)||value<0)))return dash.join(" ")}function categoricalPaletteColor(index){return`var(--lr-graph-cat-${index%8+1})`}function squarePath(r){const s=shapeHalfSide(r);return`M ${-s} ${-s} L ${s} ${-s} L ${s} ${s} L ${-s} ${s} Z`}function diamondPath(r){const d=shapeHalfSide(r)*Math.SQRT2;return`M 0 ${-d} L ${d} 0 L 0 ${d} L ${-d} 0 Z`}function sameIds(a,b){return a===b?!0:!a||!b||a.length!==b.length?!1:a.every((id,index)=>id===b[index])}const identitySets=new WeakMap;function identitySet(values){const ids=canonicalIdentityList(values);let set=identitySets.get(ids);return set||identitySets.set(ids,set=new Set(ids)),set}class LyraGraph extends LyraElement{static{this.defaultStrings={...super.defaultStrings,graphCommunity:LYRA_DEFAULT_graphCommunity,graphDataList:LYRA_DEFAULT_graphDataList,graphDataListLimit:LYRA_DEFAULT_graphDataListLimit,graphDiagram:LYRA_DEFAULT_graphDiagram,graphEdgeLimit:LYRA_DEFAULT_graphEdgeLimit,graphExpandableItem:LYRA_DEFAULT_graphExpandableItem,graphItemAnnouncement:LYRA_DEFAULT_graphItemAnnouncement,graphLink:LYRA_DEFAULT_graphLink,graphMissingLibrary:LYRA_DEFAULT_graphMissingLibrary,graphNode:LYRA_DEFAULT_graphNode,graphNodeFocused:LYRA_DEFAULT_graphNodeFocused,graphNodeLimit:LYRA_DEFAULT_graphNodeLimit,graphNodesHidden:LYRA_DEFAULT_graphNodesHidden,graphSelectionCount:LYRA_DEFAULT_graphSelectionCount,graphTypedNode:LYRA_DEFAULT_graphTypedNode,loading:LYRA_DEFAULT_loading,noData:LYRA_DEFAULT_noData}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["nodes","edges","nodeTypes","hiddenTypes","communities","selectedNodeIds","selectedEdgeIds","dimmedNodeIds","dimmedEdgeIds"])}static get observedAttributes(){return[...new Set([...super.observedAttributes,"role"])]}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change"])}get graphModel(){const sources=this.normalizedGraphSources;return(!sources||sources[0]!==this.nodes||sources[1]!==this.edges||sources[2]!==this.nodeTypes||sources[3]!==this.communities)&&(this.normalizedGraphSources=[this.nodes,this.edges,this.nodeTypes,this.communities],this.normalizedGraphModel=normalizeGraphModel(this.nodes,this.edges,this.nodeTypes,this.communities)),this.normalizedGraphModel}get layout(){return this._layout}set layout(next){const normalized=GRAPH_LAYOUT.normalize(next),old=this._layout;old!==normalized&&(this._layout=normalized,this.requestUpdate("layout",old))}constructor(){super(),this.nodes=[],this.edges=[],this.nodeTypes=[],this.hiddenTypes=[],this.communities=[],this._layout="force",this.renderer="svg",this.fitTo="none",this.width=800,this.height=600,this.chargeStrength=-300,this.edgeDistance=100,this.minZoom=.1,this.maxZoom=8,this.label=null,this.accessibleLabel=null,this.withEdgeLabels=!1,this.edgeLabelMinZoom=.6,this.focusNodeId=null,this.selectionMode="none",this.selectedNodeIds=[],this.selectedEdgeIds=[],this.dimmedNodeIds=[],this.dimmedEdgeIds=[],this.arrowMarkerId=nextId("graph-arrow"),this.loading=!0,this.loadFailed=!1,this.loadLibrary=loadD3,this.loadGeneration=0,this.containerSize=null,this.simNodes=[],this.simLinks=[],this.simNodeById=new Map,this.danglingLinks=[],this.lastPositionById=new Map,this.lastHiddenNodeCount=0,this.activeGraphItem=0,this.graphLiveText="",this.announcements=new AnnouncementSinkController(this,{eager:["polite","assertive"]}),this.graphAnnouncementsReady=!1,this.isMounting=!0,this.authorRole=null,this.syncingGraphHostRole=!1,this.boundNodeEls=new WeakSet,this.nodeEls=[],this.nodeHitEls=[],this.nodeLabelEls=[],this.expandIndicatorEls=[],this.lastKeyActivateIndex=null,this.lastKeyActivateTime=0,this.lastAppliedFocusNodeId=null,this.communityHullEls=[],this.communityHullHitEls=[],this.communityLabelEls=[],this.visible=!0,this.canvasDrawPending=!1,this.pickDirty=!0,this.canvasCamera={k:1,x:0,y:0},this.pickItems=[],this.canvasSceneHasEdgeLabels=!1,this.isCameraTweening=!1,this.linkEls=[],this.linkHitEls=[],this.linkLabelEls=[],this.linkLabelHiddenByLength=[],this.edgeLabelWidthCache=new Map,this.danglingLinkEls=[],this.linkPaintVisibilityCache=new Map,this.resolvedCssColorCache=new Map,this.reducedMotion=!1,this.isApplyingZoomTransform=!1,this.onCanvasDprChange=()=>{this.watchCanvasDpr(),this.markCanvasDirty()},this.onCanvasPointerDown=e=>{if(e.button!==0||(this.canvasPointerDownAt={x:e.clientX,y:e.clientY},this.canvasPointerDownId=e.pointerId,this.layout==="layered"))return;const hit=this.hitTest(e.clientX,e.clientY);if(hit?.kind==="node"){this.canvasDragNode=hit.node,this.canvasPointerId=e.pointerId;try{this.canvasEl.setPointerCapture(e.pointerId)}catch{}hit.node.fx=hit.node.x,hit.node.fy=hit.node.y,this.simulation?.alphaTarget(.3).restart()}},this.onCanvasPointerMove=e=>{if(this.canvasDragNode&&this.canvasPointerId===e.pointerId){const node=this.simNodeById.get(this.canvasDragNode.id);if(node){const rect=this.canvasEl.getBoundingClientRect();node.fx=(e.clientX-rect.left-this.canvasCamera.x)/this.canvasCamera.k,node.fy=(e.clientY-rect.top-this.canvasCamera.y)/this.canvasCamera.k,this.markCanvasDirty()}return}if(this.pendingHover={x:e.clientX,y:e.clientY},this.hoverRafId!=null)return;const frameOwner=this.ownerWindow;frameOwner&&(this.hoverRafOwner=frameOwner,this.hoverRafId=frameOwner.requestAnimationFrame(()=>{if(this.hoverRafId=void 0,this.hoverRafOwner=void 0,!this.isConnected||this.ownerWindow!==frameOwner)return;const pending=this.pendingHover;if(this.pendingHover=void 0,!pending||this.canvasHoverSuppressed()||this.pickDirty&&this.simulationIsTicking())return;const hit=this.hitTest(pending.x,pending.y);this.updateCanvasTooltip(hit,pending.x,pending.y),this.updateCanvasHover(hit)}))},this.onCanvasPointerUp=e=>{this.finishCanvasNodeDrag(e.pointerId);const down=this.takeCanvasPointerDown(e.pointerId);if(!down||Math.hypot(e.clientX-down.x,e.clientY-down.y)>5)return;const hit=this.hitTest(e.clientX,e.clientY);if(!hit){this.clearSelection();return}hit.kind==="node"?this.onNodeClick(hit.node,e):hit.kind==="link"?this.onLinkClick(hit.link,e):this.onCommunityClick(hit.entry.community)},this.onCanvasPointerCancel=e=>{this.finishCanvasNodeDrag(e.pointerId),this.takeCanvasPointerDown(e.pointerId)},this.onCanvasLostPointerCapture=e=>{this.finishCanvasNodeDrag(e.pointerId,!1),this.takeCanvasPointerDown(e.pointerId)},this.onCanvasPointerLeave=()=>{this.pendingHover=void 0,this.hoverRafId!=null&&(this.hoverRafOwner?.cancelAnimationFrame(this.hoverRafId),this.hoverRafId=void 0,this.hoverRafOwner=void 0),this.updateCanvasTooltip(void 0,0,0),this.canvasHoverSuppressed()?this.canvasHover=void 0:this.updateCanvasHover(void 0)},this.onCanvasDblClick=e=>{const hit=this.hitTest(e.clientX,e.clientY),node=hit?.kind==="node"?hit.node:this.nodeAtCanvasPoint(e.clientX,e.clientY);node&&(e.stopImmediatePropagation(),this.emit("lr-node-expand",{nodeId:node.id}))},this.isDragging=!1,this.isPanning=!1,new ThemeWatcher(this,()=>{const reduced=prefersReducedMotion(this);reduced!==this.reducedMotion&&(this.reducedMotion=reduced,reduced?this.simulation?.stop():this.safeSeed==null&&this.simulation?.restart()),this.linkPaintVisibilityCache.clear(),this.resolvedCssColorCache.clear(),this.renderer==="canvas"&&this.markCanvasDirty()},["(prefers-reduced-motion: reduce)"])}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value),name==="role"&&oldValue!==value&&!this.syncingGraphHostRole&&(this.authorRole=value)}hostOwnsGraphSemantics(){return this.hasAttribute("aria-label")}syncGraphHostRole(){if(this.authorRole===null){this.syncingGraphHostRole=!0;try{this.hostOwnsGraphSemantics()?this.setAttribute("role","group"):this.removeAttribute("role")}finally{this.syncingGraphHostRole=!1}}}get ownerWindow(){return this.ownerDocument.defaultView??void 0}computedStyle(element=this){const view=this.ownerWindow;return view?view.getComputedStyle(element):"style"in element?element.style:this.style}connectedCallback(){super.connectedCallback(),this.reducedMotion=prefersReducedMotion(this);const IntersectionObserverCtor=this.ownerWindow?.IntersectionObserver;if(IntersectionObserverCtor&&(this.intersectionObserver=new IntersectionObserverCtor(entries=>{const wasVisible=this.visible;this.visible=entries[0]?.isIntersecting??!0,this.visible&&!wasVisible&&this.canvasDrawPending&&(this.canvasDrawPending=!1,this.scheduleCanvasDraw())}),this.intersectionObserver.observe(this)),this.fitTo==="container"&&(this.syncHostResizeObserver(),this.measureHostBox()),this.d3){!this.reducedMotion&&this.safeSeed==null&&this.simulation?.restart(),this.renderer==="canvas"&&this.canvasEl&&this.canvasEl===this.zoomedEl&&(this.ensureCanvasOwnerRealm(),this.syncHostResizeObserver(),this.watchCanvasDpr(),this.markCanvasDirty());return}const generation=++this.loadGeneration;this.loadLibrary().then(async mods=>{try{await this.updateComplete}catch{return}if(await new Promise(resolve=>this.updateBrowserDerivedState(resolve)),!(generation!==this.loadGeneration||!this.isConnected)){if(this.loading=!1,!mods){this.loadFailed=!0;return}this.loadFailed=!1,this.d3=mods,this.rebuildSimulation()}})}disconnectedCallback(){super.disconnectedCallback(),this.loadGeneration+=1,this.simulation?.stop(),this.finishCanvasNodeDrag(void 0,!0,!1),this.takeCanvasPointerDown(),this.cancelCameraTween(),this.intersectionObserver?.disconnect(),this.intersectionObserver=void 0,this.hostResizeObserver?.disconnect(),this.hostResizeObserver=void 0,this.hostResizeObserverDocument=void 0,this.canvasDprQuery?.removeEventListener("change",this.onCanvasDprChange),this.canvasDprQuery=void 0,this.canvasDrawRafId!=null&&(this.canvasDrawRafOwner?.cancelAnimationFrame(this.canvasDrawRafId),this.canvasDrawRafId=void 0,this.canvasDrawRafOwner=void 0),this.hoverRafId!=null&&(this.hoverRafOwner?.cancelAnimationFrame(this.hoverRafId),this.hoverRafId=void 0,this.hoverRafOwner=void 0),this.pendingHover=void 0,this.canvasHover=void 0,this.canvasTooltipEl?.setAttribute("hidden",""),this.pendingGraphItemFocus=void 0,this.viewportChangeRafId!=null&&(this.viewportChangeRafOwner?.cancelAnimationFrame(this.viewportChangeRafId),this.viewportChangeRafId=void 0,this.viewportChangeRafOwner=void 0)}adoptedCallback(){super.adoptedCallback(),this.announcements.adopted(),this.ensureCanvasOwnerRealm()}scheduleViewportChange(){if(this.viewportChangeRafId!=null)return;const frameOwner=this.ownerWindow;frameOwner&&(this.viewportChangeRafOwner=frameOwner,this.viewportChangeRafId=frameOwner.requestAnimationFrame(()=>{if(this.viewportChangeRafId=void 0,this.viewportChangeRafOwner=void 0,!this.isConnected||this.ownerWindow!==frameOwner)return;const transform=this.renderer==="canvas"||!this.d3||!this.zoomedEl?this.canvasCamera:this.d3.zoomTransform(this.zoomedEl);this.emit("lr-viewport-change",{zoom:transform.k,x:transform.x,y:transform.y,k:transform.k})}))}nodeRadius(n){const r=n.radius??(MIN_RADIUS+MAX_RADIUS)/2;return Number.isFinite(r)?Math.min(MAX_RADIUS,Math.max(MIN_RADIUS,r)):(MIN_RADIUS+MAX_RADIUS)/2}safeLinkWidth(link){return finiteRange(link.width??1.5,1.5,0)}isInteractiveLink(link,resolveColor,defaultPaint){if(this.safeLinkWidth(link)<=0)return!1;const effectivePaint=sanitizeNodeColor(link.color)??defaultPaint,color=effectivePaint?resolveColor(effectivePaint).trim().toLowerCase():void 0;if(!color)return!0;if(color==="transparent"||/^#[\da-f]{4}$/.test(color)&&color.endsWith("0")||/^#[\da-f]{8}$/.test(color)&&color.endsWith("00")||/\/\s*0(?:\.0+)?%?\s*\)$/.test(color)||/^(?:rgba|hsla)\(/.test(color)&&/,\s*0(?:\.0+)?\s*\)$/.test(color))return!1;const cached=this.linkPaintVisibilityCache.get(color);if(cached!==void 0)return cached;this.linkPaintProbe??=this.ownerDocument.createElement("canvas"),this.linkPaintProbe.width=1,this.linkPaintProbe.height=1;const context=this.linkPaintProbe.getContext("2d",{willReadFrequently:!0});if(!context)return!0;let visible=!0;try{context.clearRect(0,0,1,1),context.fillStyle="rgb(1 2 3)",context.fillStyle=color,context.fillRect(0,0,1,1),visible=context.getImageData(0,0,1,1).data[3]!==0}catch{visible=!0}return this.linkPaintVisibilityCache.set(color,visible),visible}navigableLinks(){return this.navigableLinksCache||(this.navigableLinksCache=this.simLinks.length?this.withCanvasColorResolver(resolveColor=>{const computed=this.computedStyle(),defaultPaint=computed.getPropertyValue("--lr-graph-edge-color").trim()||computed.getPropertyValue("--lr-color-border").trim();return this.simLinks.filter(link=>this.isInteractiveLink(link,resolveColor,defaultPaint))}):[]),this.navigableLinksCache}lengthInPixels(value){return typeof value=="string"?resolveCssTokenLength(value,{host:this})??Number.NaN:value}get requestedWidth(){return finiteRange(this.lengthInPixels(this.width),800,1)}get requestedHeight(){return finiteRange(this.lengthInPixels(this.height),600,1)}get safeWidth(){const requested=this.requestedWidth,measured=this.fitTo==="container"&&this.containerSize;return measured?finiteRange(measured.width,requested,1):requested}get safeHeight(){const requested=this.requestedHeight,measured=this.fitTo==="container"&&this.containerSize;return measured?finiteRange(measured.height,requested,1):requested}recordContainerSize(width,height){const w=Math.round(finiteRange(width,0,0)),h=Math.round(finiteRange(height,0,0));return w<=0||h<=0||this.containerSize?.width===w&&this.containerSize?.height===h?!1:(this.containerSize={width:w,height:h},!0)}measureHostBox(){return this.isConnected?(this.syncRequestedHeightVar(),this.recordContainerSize(this.clientWidth,this.clientHeight)):!1}syncRequestedHeightVar(){this.style.setProperty("--_lr-graph-requested-height",`${this.requestedHeight}px`)}get safeMinZoom(){return finiteRange(this.minZoom,.1,.001,1e3)}get safeMaxZoom(){return finiteRange(this.maxZoom,8,.001,1e3)}get effectiveZoomBounds(){const min=this.safeMinZoom,max=this.safeMaxZoom;return Object.freeze({min:Math.min(min,max),max:Math.max(min,max)})}get safeEdgeLabelMinZoom(){return finiteRange(this.edgeLabelMinZoom,.6,.001,1e3)}get resolvedNodeLabelsMode(){return this.nodeLabels??(this.renderer==="canvas"?"zoom":"always")}canvasNodeLabelsVisible(){const mode=this.resolvedNodeLabelsMode;return mode==="none"?!1:mode==="zoom"?this.canvasCamera.k>=NODE_LABEL_MIN_ZOOM:!0}get safeSeed(){return this.seed==null?void 0:finiteInteger(this.seed,0)}get safeChargeStrength(){return finiteNumber(this.chargeStrength,-300)}get safeLinkDistance(){return finiteRange(this.edgeDistance,100,0)}nodeTypeEntry(node){const types=this.graphModel.nodeTypes;if(this.nodeTypeIndex?.[0]!==types){const labeled=this.labeledNodeTypes();this.nodeTypeIndex=[types,new Map(types.map((type,index)=>{const slot=labeled.indexOf(type);return[type.id,[type,slot<0?index:slot]]}))]}return node.type==null?void 0:this.nodeTypeIndex[1].get(node.type)}resolveNodeType(node){return this.nodeTypeEntry(node)?.[0]}nodeShape(node){return this.resolveNodeType(node)?.shape??"circle"}labeledNodeTypes(){return this.graphModel.nodeTypes.filter(candidate=>typeof candidate?.label=="string"&&candidate.label.trim().length>0)}nodeFill(node){const ownColor=sanitizeNodeColor(node.color);if(ownColor)return ownColor;const entry=this.nodeTypeEntry(node);if(entry)return sanitizeNodeColor(entry[0].color)||categoricalPaletteColor(entry[1])}visibleNodes(){const hiddenTypes=canonicalIdentityList(this.hiddenTypes);if(!hiddenTypes.length)return this.graphModel.nodes;const hidden=new Set(hiddenTypes);return this.graphModel.nodes.filter(n=>n.type==null||!hidden.has(n.type))}resolveLinksAgainst(byId){const nodeExists=new Set(this.graphModel.nodes.map(n=>n.id)),resolved=[],dangling=[];for(const l of this.graphModel.links){const source=byId.get(l.source);if(!source)continue;const target=byId.get(l.target);target?resolved.push(copyGraphLinkIdentity(l,{...l,source,target})):nodeExists.has(l.target)||dangling.push(copyGraphLinkIdentity(l,{...l,source,target:{id:l.target,x:source.x,y:source.y},dangling:!0}))}return{resolved,dangling}}communityMembers(community){const idSet=new Set(community.memberIds);return this.simNodes.filter(n=>idSet.has(n.id)||n.communityId===community.id)}visibleCommunities(){return this.visibleCommunitiesCache||(this.visibleCommunitiesCache=this.graphModel.communities.map(community=>({community,members:this.communityMembers(community)})).filter(entry=>entry.members.length>0)),this.visibleCommunitiesCache}communityHull(members){return convexHull(members.map(n=>({x:n.x??0,y:n.y??0})))}onCommunityClick(community){this.emit("lr-community-activate",{communityId:community.id})}cameraTransitionMs(){const parsed=parseFloat(this.computedStyle().getPropertyValue("--lr-transition-base"));return Number.isFinite(parsed)?parsed:180}cancelCameraTween(){this.cameraTweenId!=null&&(this.cameraTweenFrameOwner?.cancelAnimationFrame(this.cameraTweenId),this.cameraTweenId=void 0,this.cameraTweenFrameOwner=void 0),this.isCameraTweening=!1;const resolve=this.cameraTweenResolve;resolve&&(this.cameraTweenResolve=void 0,resolve(!1))}applyZoomTransform(transform){if(!(!this.d3||!this.zoomedEl||!this.zoomBehavior)){this.isApplyingZoomTransform=!0;try{this.zoomBehavior.transform(this.d3.select(this.zoomedEl),transform)}finally{this.isApplyingZoomTransform=!1}}}tweenCamera(computeTarget){return new Promise(resolve=>{if(!this.d3||!this.zoomedEl||!this.zoomBehavior){resolve(!1);return}this.cancelCameraTween(),this.cameraTweenResolve=resolve,this.isCameraTweening=!0;const frameOwner=this.ownerWindow;if(!frameOwner){this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!1);return}if(prefersReducedMotion(this)){this.applyZoomTransform(computeTarget()),this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!0);return}const current=this.d3.zoomTransform(this.zoomedEl),duration=this.cameraTransitionMs(),start=frameOwner.performance.now(),startK=current.k,startX=current.x,startY=current.y,step=now=>{if(this.cameraTweenResolve!==resolve)return;if(!this.isConnected||this.ownerWindow!==frameOwner){this.cameraTweenId=void 0,this.cameraTweenFrameOwner=void 0,this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!1);return}const t=!prefersReducedMotion(this)&&duration>0?Math.min(1,(now-start)/duration):1,target=computeTarget(),targetK=target.k,targetX=target.x,targetY=target.y;this.applyZoomTransform(this.d3.zoomIdentity.translate(startX+(targetX-startX)*t,startY+(targetY-startY)*t).scale(startK+(targetK-startK)*t)),t<1?(this.cameraTweenFrameOwner=frameOwner,this.cameraTweenId=frameOwner.requestAnimationFrame(step)):(this.cameraTweenId=void 0,this.cameraTweenFrameOwner=void 0,this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!0))};this.cameraTweenFrameOwner=frameOwner,this.cameraTweenId=frameOwner.requestAnimationFrame(step)})}async focusNode(id,options){const node=this.simNodes.find(n=>n.id===id);if(!node||!this.d3||!this.zoomedEl||!this.zoomBehavior)return!1;const current=this.d3.zoomTransform(this.zoomedEl),bounds=this.effectiveZoomBounds,k=finiteRange(options?.zoom??current.k,current.k,bounds.min,bounds.max),arrived=await this.tweenCamera(()=>this.d3.zoomIdentity.translate(this.safeWidth/2-k*(node.x??0),this.safeHeight/2-k*(node.y??0)).scale(k));return arrived&&(this.graphLiveText=this.localize("graphNodeFocused",void 0,{label:this.nodeAccessibleText(node)})),arrived}fit(options){if(!this.d3||!this.zoomedEl||!this.zoomBehavior||!this.simNodes.length)return;const padding=finiteRange(options?.padding??24,24,0);this.tweenCamera(()=>{const fitPoints=[];for(const n of this.simNodes){const r=this.nodeRadius(n);fitPoints.push({x:(n.x??0)-r,y:(n.y??0)-r}),fitPoints.push({x:(n.x??0)+r,y:(n.y??0)+r})}for(const entry of this.visibleCommunities())for(const p of this.communityHull(entry.members))fitPoints.push({x:p.x-HULL_PADDING,y:p.y-HULL_PADDING}),fitPoints.push({x:p.x+HULL_PADDING,y:p.y+HULL_PADDING});const{minX,maxX,minY,maxY}=extent(fitPoints,point=>point.x,point=>point.y),bounds=this.effectiveZoomBounds,transform=fitTransform({minX,minY,maxX,maxY},{width:this.safeWidth,height:this.safeHeight},padding,bounds);return this.d3.zoomIdentity.translate(transform.x,transform.y).scale(transform.zoom)})}updateFocusHalo(){if(!this.focusHaloEl)return;const node=this.focusNodeId!=null?this.simNodes.find(n=>n.id===this.focusNodeId):void 0;node?(this.focusHaloEl.setAttribute("cx",String(node.x??0)),this.focusHaloEl.setAttribute("cy",String(node.y??0)),this.focusHaloEl.setAttribute("r",String(this.nodeRadius(node)+FOCUS_HALO_PADDING)),this.focusHaloEl.removeAttribute("hidden")):this.focusHaloEl.setAttribute("hidden","")}setUpCanvasSurface(){this.canvasCtx=this.canvasEl.getContext("2d")??void 0,this.ensureCanvasOwnerRealm(),this.syncHostResizeObserver(),this.watchCanvasDpr(),this.canvasTooltipEl=this.renderRoot.querySelector('[part="tooltip"]')??void 0,this.bindCanvasPointer(),this.bindCanvasZoom()}ensureCanvasOwnerRealm(){const ownerDocument=this.ownerDocument;this.edgeLabelMeasureCanvas?.ownerDocument!==ownerDocument&&(this.edgeLabelMeasureCanvas=void 0,this.edgeLabelMeasureCtx=void 0,this.edgeLabelWidthCache.clear()),!(!this.pickCanvas&&this.renderer!=="canvas")&&this.pickCanvas?.ownerDocument!==ownerDocument&&(this.pickCanvas=ownerDocument.createElement("canvas"),this.pickCtx=this.pickCanvas.getContext("2d",{willReadFrequently:!0}),this.pickDirty=!0)}syncHostResizeObserver(){if(this.renderer!=="canvas"&&this.fitTo!=="container"){this.hostResizeObserver?.disconnect(),this.hostResizeObserver=void 0,this.hostResizeObserverDocument=void 0;return}this.hostResizeObserver&&this.hostResizeObserverDocument===this.ownerDocument||this.watchHostResize()}watchHostResize(){this.hostResizeObserver?.disconnect();const ResizeObserverCtor=this.ownerWindow?.ResizeObserver;if(!ResizeObserverCtor){this.hostResizeObserver=void 0,this.hostResizeObserverDocument=void 0;return}this.hostResizeObserver=new ResizeObserverCtor(entries=>{const box=entries[entries.length-1]?.contentRect;this.fitTo==="container"&&box&&this.recordContainerSize(box.width,box.height),this.renderer==="canvas"&&this.canvasEl&&this.markCanvasDirty()}),this.hostResizeObserverDocument=this.ownerDocument,this.hostResizeObserver.observe(this)}watchCanvasDpr(){this.canvasDprQuery?.removeEventListener("change",this.onCanvasDprChange);const view=this.ownerWindow;if(!view?.matchMedia){this.canvasDprQuery=void 0;return}this.canvasDprQuery=view.matchMedia(`(resolution: ${view.devicePixelRatio}dppx)`),this.canvasDprQuery.addEventListener("change",this.onCanvasDprChange)}markCanvasDirty(){this.canvasScene=void 0,this.pickDirty=!0,this.scheduleCanvasDraw()}markCanvasCameraDirty(){this.pickDirty=!0,this.scheduleCanvasDraw()}scheduleCanvasDraw(){if(!this.visible){this.canvasDrawPending=!0;return}if(this.canvasDrawRafId!=null)return;const frameOwner=this.ownerWindow;frameOwner&&(this.canvasDrawRafOwner=frameOwner,this.canvasDrawRafId=frameOwner.requestAnimationFrame(()=>{this.canvasDrawRafId=void 0,this.canvasDrawRafOwner=void 0,!(!this.isConnected||this.ownerWindow!==frameOwner)&&this.drawCanvas()}))}resolveCssColorWithProbe(value,probe){const cached=this.resolvedCssColorCache.get(value);if(cached!==void 0)return cached;probe.style.color="",probe.style.color=value;const result=getComputedStyle(probe).color.trim()||getComputedStyle(this).color||"transparent";return this.resolvedCssColorCache.set(value,result),result}createCanvasColorProbe(){const probe=this.ownerDocument.createElement("span");return probe.setAttribute("aria-hidden","true"),probe.style.position="absolute",probe.style.inlineSize="0",probe.style.blockSize="0",probe.style.overflow="hidden",probe.style.visibility="hidden",probe.style.pointerEvents="none",this.renderRoot.append(probe),probe}withCanvasColorResolver(callback){let probe;try{return callback(value=>{const cached=this.resolvedCssColorCache.get(value);return cached!==void 0?cached:(probe??=this.createCanvasColorProbe(),this.resolveCssColorWithProbe(value,probe))})}finally{probe?.remove()}}buildCanvasScene(cs){return this.withCanvasColorResolver(resolveColor=>{const hullFillDefault=cs.getPropertyValue("--lr-graph-hull-fill").trim()||cs.getPropertyValue("--lr-color-brand").trim(),hulls=this.visibleCommunities().map(entry=>({d:hullPathD(this.communityHull(entry.members)),fill:resolveColor(sanitizeNodeColor(entry.community.color)??hullFillDefault)})),linkColorDefault=cs.getPropertyValue("--lr-graph-edge-color").trim()||cs.getPropertyValue("--lr-color-border").trim(),links=this.simLinks.map(l=>{const coords=this.linkCoordinates(l),own=sanitizeNodeColor(l.color);return{x1:coords.x1,y1:coords.y1,x2:coords.x2,y2:coords.y2,color:resolveColor(own??linkColorDefault),width:this.safeLinkWidth(l),dash:l.dash,directed:l.directed,selected:this.isSelected("link",this.linkKey(l)),dimmed:this.isDimmed("link",this.linkKey(l))}}),edgeLabels=this.withEdgeLabels&&this.canvasCamera.k>=this.safeEdgeLabelMinZoom?this.simLinks.flatMap(l=>{const label=ownGraphText(l,"label");if(!label)return[];const pos=this.edgeLabelPosition(l),coords=this.linkCoordinates(l),edgeLength=Math.hypot(coords.x2-coords.x1,coords.y2-coords.y1);return this.edgeLabelWidth(label)>edgeLength*EDGE_LABEL_LENGTH_GATE_RATIO?[]:[{x:pos.x,y:pos.y,text:label}]}):[],nodeFillDefault=cs.getPropertyValue("--lr-graph-node-fill").trim()||cs.getPropertyValue("--lr-color-brand").trim(),nodes=this.simNodes.map(n=>{const fill=this.nodeFill(n);return{x:n.x??0,y:n.y??0,r:this.nodeRadius(n),shape:this.nodeShape(n),fill:resolveColor(fill??nodeFillDefault),selected:this.isSelected("node",n.id),dimmed:this.isDimmed("node",n.id)}}),nodeLabels=this.simNodes.flatMap(n=>{const label=ownGraphText(n,"label");return label?[{x:(n.x??0)+this.nodeRadius(n)+2,y:n.y??0,text:label}]:[]}),expandIndicators=this.simNodes.filter(n=>n.expandable).map(n=>({x:n.x??0,y:n.y??0,r:this.nodeRadius(n)})),focusNode=this.focusNodeId!=null?this.simNodes.find(n=>n.id===this.focusNodeId):void 0,scene={hulls,links,edgeLabels,nodes,nodeLabels,expandIndicators,focusHalo:focusNode?{x:focusNode.x??0,y:focusNode.y??0,r:this.nodeRadius(focusNode)+FOCUS_HALO_PADDING}:void 0,showNodeLabels:this.canvasNodeLabelsVisible(),haloColor:resolveColor(this.ownerWindow?.matchMedia?.("(forced-colors: active)").matches?"CanvasText":cs.getPropertyValue("--lr-graph-focus-halo-color").trim()||cs.getPropertyValue("--lr-color-brand").trim()),selectedColor:resolveColor(cs.getPropertyValue("--lr-graph-selected-color").trim()||cs.getPropertyValue("--lr-color-success").trim()),dimmedOpacity:(()=>{const value=Number(cs.getPropertyValue("--lr-graph-dimmed-opacity").trim());return Number.isFinite(value)?Math.min(1,Math.max(0,value)):.35})(),hullOpacity:(()=>{const value=Number(cs.getPropertyValue("--lr-graph-hull-opacity").trim());return Number.isFinite(value)?Math.min(1,Math.max(0,value)):.12})(),labelColor:resolveColor(cs.getPropertyValue("--lr-color-text").trim()),labelHaloColor:resolveColor(cs.getPropertyValue("--lr-graph-edge-label-halo").trim()||cs.getPropertyValue("--lr-color-surface").trim()),expandBadgeFill:resolveColor(cs.getPropertyValue("--lr-color-surface").trim()),expandBadgeStroke:resolveColor(cs.getPropertyValue("--lr-color-border-strong").trim()),font:`${this.edgeLabelFontPx()}px ${cs.getPropertyValue("--lr-font").trim()||"sans-serif"}`,borderWidths:["thin","medium","thick"].map((size,index)=>resolveCssTokenLength(cs.getPropertyValue(`--lr-border-width-${size}`).trim(),{host:this})??index+1)};return this.updateCanvasFocus(scene),scene})}updateCanvasFocus(scene){const index=shadowFocusTarget(this)?.getAttribute("part")==="cursor-item"?this.normalizedGraphItem():-1,node=index>=0&&index<this.linkIndexBase()?this.simNodes[index]:void 0,link=index>=this.linkIndexBase()&&index<this.communityIndexBase()?this.navigableLinks()[index-this.linkIndexBase()]:void 0,community=index>=this.communityIndexBase()?this.visibleCommunities()[index-this.communityIndexBase()]:void 0;scene.keyboardFocusRing=node?{x:node.x??0,y:node.y??0,r:this.nodeRadius(node)+4}:void 0,scene.keyboardFocusLink=link?{...this.linkCoordinates(link),width:this.safeLinkWidth(link)}:void 0,scene.keyboardFocusHull=community?{d:hullPathD(this.communityHull(community.members))}:void 0}drawCanvas(){if(!this.canvasEl||!this.canvasCtx)return;const dpr=this.ownerWindow?.devicePixelRatio||1,w=this.canvasEl.clientWidth||this.safeWidth,h=this.canvasEl.clientHeight||this.safeHeight,backingW=Math.round(w*dpr),backingH=Math.round(h*dpr);(this.canvasEl.width!==backingW||this.canvasEl.height!==backingH)&&(this.canvasEl.width=backingW,this.canvasEl.height=backingH);const ctx=this.canvasCtx;ctx.setTransform(dpr,0,0,dpr,0,0),ctx.clearRect(0,0,w,h);const edgeLabelsVisible=this.withEdgeLabels&&this.canvasCamera.k>=this.safeEdgeLabelMinZoom,nodeLabelsVisible=this.canvasNodeLabelsVisible();(!this.canvasScene||this.canvasScene.showNodeLabels!==nodeLabelsVisible||this.canvasSceneHasEdgeLabels!==edgeLabelsVisible)&&(this.canvasScene=this.buildCanvasScene(this.computedStyle()),this.canvasSceneHasEdgeLabels=edgeLabelsVisible),this.updateCanvasFocus(this.canvasScene),drawGraphScene(ctx,this.canvasCamera,this.canvasScene)}rebuildPickItems(){this.pickItems=[...this.visibleCommunities().map(entry=>({kind:"hull",entry})),...this.navigableLinks().map(link=>({kind:"link",link})),...this.simNodes.map(node=>({kind:"node",node}))]}redrawPickCanvas(){if(!this.pickCtx||!this.canvasEl||!this.pickCanvas)return;(this.pickCanvas.width!==this.canvasEl.width||this.pickCanvas.height!==this.canvasEl.height)&&(this.pickCanvas.width=this.canvasEl.width,this.pickCanvas.height=this.canvasEl.height),this.rebuildPickItems();const dpr=this.ownerWindow?.devicePixelRatio||1;this.pickCtx.setTransform(dpr,0,0,dpr,0,0),drawPickingScene(this.pickCtx,this.canvasCamera,{hulls:this.pickItems.filter(i=>i.kind==="hull").map(i=>({d:hullPathD(this.communityHull(i.entry.members))})),links:this.pickItems.filter(i=>i.kind==="link").map(i=>{const c=this.linkCoordinates(i.link);return{x1:c.x1,y1:c.y1,x2:c.x2,y2:c.y2,width:this.safeLinkWidth(i.link)}}),nodes:this.pickItems.filter(i=>i.kind==="node").map(i=>({x:i.node.x??0,y:i.node.y??0,r:this.nodeRadius(i.node)+2,shape:this.nodeShape(i.node)}))}),this.pickDirty=!1}hitTest(clientX,clientY){if(!this.canvasEl||!this.pickCtx)return;this.pickDirty&&this.redrawPickCanvas();const rect=this.canvasEl.getBoundingClientRect(),dpr=this.ownerWindow?.devicePixelRatio||1,px=Math.round((clientX-rect.left)*dpr),py=Math.round((clientY-rect.top)*dpr);if(px<0||py<0||px>=this.pickCtx.canvas.width||py>=this.pickCtx.canvas.height)return;const data=this.pickCtx.getImageData(px,py,1,1).data,index=pickColorToIndex(data[0],data[1],data[2]);return index>=0?this.pickItems[index]:void 0}bindCanvasZoom(){if(!this.d3||!this.canvasEl)return;const bounds=this.effectiveZoomBounds,zoomBehavior=this.d3.zoom().scaleExtent([bounds.min,bounds.max]).on("start",()=>{this.isApplyingZoomTransform||(this.isPanning=!0,this.cancelCameraTween())}).on("zoom",event=>{this.canvasCamera={k:event.transform.k,x:event.transform.x,y:event.transform.y},this.markCanvasCameraDirty(),this.scheduleViewportChange()}).on("end",()=>{this.isPanning=!1});this.zoomBehavior=zoomBehavior,this.d3.select(this.canvasEl).call(zoomBehavior)}bindCanvasPointer(){const canvas=this.canvasEl;canvas.addEventListener("pointerdown",this.onCanvasPointerDown),canvas.addEventListener("pointermove",this.onCanvasPointerMove),canvas.addEventListener("pointerup",this.onCanvasPointerUp),canvas.addEventListener("pointercancel",this.onCanvasPointerCancel),canvas.addEventListener("lostpointercapture",this.onCanvasLostPointerCapture),canvas.addEventListener("pointerleave",this.onCanvasPointerLeave),canvas.addEventListener("dblclick",this.onCanvasDblClick)}simulationIsTicking(){return this.simulation!=null&&this.simulation.alpha()>this.simulation.alphaMin()}finishCanvasNodeDrag(pointerId,releaseCapture=!0,redraw=!0){const activePointerId=this.canvasPointerId;if(activePointerId==null||pointerId!=null&&pointerId!==activePointerId)return;const node=this.canvasDragNode&&this.simNodeById.get(this.canvasDragNode.id);if(this.canvasDragNode=void 0,this.canvasPointerId=void 0,this.simulation?.alphaTarget(0),node&&(node.fx=null,node.fy=null),releaseCapture&&this.canvasEl)try{this.canvasEl.releasePointerCapture(activePointerId)}catch{}redraw?this.markCanvasDirty():(this.canvasScene=void 0,this.pickDirty=!0)}takeCanvasPointerDown(pointerId){if(pointerId!=null&&this.canvasPointerDownId!==pointerId)return;const down=this.canvasPointerDownAt;return this.canvasPointerDownAt=void 0,this.canvasPointerDownId=void 0,down}canvasHoverSuppressed(){return!!this.canvasDragNode||this.isDragging||this.isPanning||this.isCameraTweening}updateCanvasHover(hit){const next=hit?.kind==="node"?{kind:"node",id:hit.node.id}:hit?.kind==="link"?{kind:"link",id:this.linkKey(hit.link),detail:this.linkHoverDetail(hit.link)}:void 0,previous=this.canvasHover;previous?.kind===next?.kind&&previous?.id===next?.id||(this.canvasHover=next,previous?.kind==="node"?this.emit("lr-node-leave",{nodeId:previous.id}):previous?.kind==="link"&&this.emitEdgeHover("leave",previous.detail),!(!this.isConnected||this.renderer!=="canvas"||this.canvasHover!==next)&&(next?.kind==="node"?this.emit("lr-node-enter",{nodeId:next.id}):next?.kind==="link"&&this.emitEdgeHover("enter",next.detail)))}nodeAtCanvasPoint(clientX,clientY){if(!this.canvasEl)return;const rect=this.canvasEl.getBoundingClientRect(),worldX=(clientX-rect.left-this.canvasCamera.x)/this.canvasCamera.k,worldY=(clientY-rect.top-this.canvasCamera.y)/this.canvasCamera.k;let closest,closestDistance=1/0;for(const node of this.simNodes){const distance=Math.hypot((node.x??0)-worldX,(node.y??0)-worldY);distance<=this.nodeRadius(node)+2/this.canvasCamera.k&&distance<closestDistance&&(closest=node,closestDistance=distance)}return closest}updateCanvasTooltip(hit,clientX,clientY){if(!this.canvasTooltipEl)return;if(!hit||hit.kind==="hull"){this.canvasTooltipEl.setAttribute("hidden","");return}const rect=this.canvasEl.getBoundingClientRect();this.canvasTooltipEl.textContent=hit.kind==="node"?this.nodeTooltipText(hit.node):this.linkTooltipText(hit.link);let left=clientX-rect.left,top=clientY-rect.top;this.canvasTooltipEl.style.left=`${left}px`,this.canvasTooltipEl.style.top=`${top}px`,this.canvasTooltipEl.removeAttribute("hidden");const tooltipRect=this.canvasTooltipEl.getBoundingClientRect(),view=this.ownerWindow;if(!view)return;const minLeft=Math.max(0,rect.left),maxRight=Math.min(view.innerWidth,rect.right),minTop=Math.max(0,rect.top),maxBottom=Math.min(view.innerHeight,rect.bottom);tooltipRect.right>maxRight&&(left-=tooltipRect.right-maxRight),tooltipRect.left<minLeft&&(left+=minLeft-tooltipRect.left),tooltipRect.bottom>maxBottom&&(top-=tooltipRect.bottom-maxBottom),tooltipRect.top<minTop&&(top+=minTop-tooltipRect.top),this.canvasTooltipEl.style.left=`${left}px`,this.canvasTooltipEl.style.top=`${top}px`}isSelected(kind,id){return identitySet(kind==="node"?this.selectedNodeIds:this.selectedEdgeIds).has(id)}paintedCurrent(kind,id){return this.selectionMode==="none"&&this.isSelected(kind,id)?"true":nothing}isDimmed(kind,id){return identitySet(kind==="node"?this.dimmedNodeIds:this.dimmedEdgeIds).has(id)}linkKey(link){return graphLinkIdentity(link)}emitSelectionIntent(kind,id,toggle){if(this.selectionMode==="none")return;const selected=this.isSelected(kind,id),time=this.ownerWindow?.performance.now()??0,repeat=this.lastActivation?.id===id&&time-this.lastActivation.time<=EXPAND_KEY_INTERVAL_MS;if(this.lastActivation={id,time},this.selectionMode==="single"||!toggle){if(this.selectionMode==="single"&&selected){repeat||this.emit("lr-selection-change",{selectedNodeIds:[],selectedEdgeIds:[]});return}this.emit("lr-selection-change",kind==="node"?{selectedNodeIds:[id],selectedEdgeIds:[]}:{selectedNodeIds:[],selectedEdgeIds:[id]});return}const selectedNodeIds=canonicalIdentityList(this.selectedNodeIds),selectedLinkIds=canonicalIdentityList(this.selectedEdgeIds),nodeIds=kind==="node"?selected?selectedNodeIds.filter(x=>x!==id):[...selectedNodeIds,id]:selectedNodeIds,linkIds=kind==="link"?selected?selectedLinkIds.filter(x=>x!==id):[...selectedLinkIds,id]:selectedLinkIds;this.emit("lr-selection-change",{selectedNodeIds:nodeIds,selectedEdgeIds:linkIds})}clearSelection(){this.selectionMode!=="none"&&(!canonicalIdentityList(this.selectedNodeIds).length&&!canonicalIdentityList(this.selectedEdgeIds).length||this.emit("lr-selection-change",{selectedNodeIds:[],selectedEdgeIds:[]}))}willUpdate(changed){super.willUpdate(changed),changed.has("height")&&this.syncRequestedHeightVar(),changed.has("fitTo")&&this.fitTo!=="container"&&(this.containerSize=null),this.fitTo==="container"&&!this.containerSize&&this.measureHostBox();const cursorOnly=changed.size>0&&[...changed.keys()].every(key=>key==="activeGraphItem"||key==="graphLiveText");cursorOnly||this.resolvedCssColorCache.clear(),cursorOnly||(this.navigableLinksCache=void 0),this.syncGraphHostRole();const wasMounting=this.isMounting;this.isMounting=!1;const hiddenTypesChanged=changed.has("hiddenTypes")&&!sameIds(canonicalIdentityList(changed.get("hiddenTypes")??[]),canonicalIdentityList(this.hiddenTypes)),structureChanged=this.d3&&(changed.has("nodes")||changed.has("edges")||hiddenTypesChanged||changed.has("layout")||this.layout==="layered"&&changed.has("edgeDistance")),graphItemsChanged=!!(structureChanged||changed.has("simNodes")||changed.has("communities")),activePart=shadowFocusTarget(this)?.getAttribute("part")??"",hadGraphItemFocus=graphItemsChanged&&["node","link","hull","cursor-item"].includes(activePart),previousIndex=this.normalizedGraphItem(),previousIdentity=graphItemsChanged?this.graphItemIdentity(previousIndex):void 0;if(structureChanged){this.rebuildSimulation(),this.renderer==="svg"&&this.simNodes.length+this.simLinks.length>1e3&&devWarnOnce("lr-graph-svg-scale",'<lr-graph>: renderer="svg" draws every node and link as DOM; use renderer="canvas" above about 1,000 of them.');const hovered=this.svgHoverNodeId;hovered!=null&&!this.simNodeById.has(hovered)&&(this.svgHoverNodeId=void 0,this.emit("lr-node-leave",{nodeId:hovered})),this.canvasHover?.kind==="node"&&!this.simNodeById.has(this.canvasHover.id)&&this.updateCanvasHover(void 0),this.navigableLinksCache=void 0}if(graphItemsChanged){this.visibleCommunitiesCache=void 0;const retainedIndex=previousIdentity?this.graphItemIndex(previousIdentity):-1,nextIndex=retainedIndex>=0?retainedIndex:this.normalizedGraphItem(previousIndex);this.activeGraphItem=nextIndex>=0?nextIndex:0,hadGraphItemFocus&&(this.pendingGraphItemFocus=nextIndex>=0?nextIndex:"base",nextIndex>=0&&(this.graphLiveText=this.graphItemAnnouncement(nextIndex)))}const selectedNodeIdsChanged=changed.has("selectedNodeIds")&&!sameIds(changed.get("selectedNodeIds"),this.selectedNodeIds),selectedLinkIdsChanged=changed.has("selectedEdgeIds")&&!sameIds(changed.get("selectedEdgeIds"),this.selectedEdgeIds);(selectedNodeIdsChanged||selectedLinkIdsChanged)&&!wasMounting&&(this.graphLiveText=this.localize("graphSelectionCount",void 0,{count:getNumberFormat(this.effectiveLocale).format(canonicalIdentityList(this.selectedNodeIds).length+canonicalIdentityList(this.selectedEdgeIds).length)}))}updated(changed){super.updated(changed),this.setAttribute("aria-busy",String(this.loading));const announceGraphText=this.graphAnnouncementsReady&&changed.has("graphLiveText")&&this.graphLiveText!=="";if(!this.loading&&!this.loadFailed&&(this.graphAnnouncementsReady=!0),announceGraphText&&this.announcements.announcePolite(this.graphLiveText),changed.has("loadFailed")&&changed.get("loadFailed")!==void 0&&this.loadFailed&&this.announcements.announceAssertive(this.localize("graphMissingLibrary")),(changed.has("fitTo")||changed.has("renderer"))&&this.syncHostResizeObserver(),!this.d3)return;!changed.has("nodes")&&!changed.has("edges")&&!changed.has("hiddenTypes")&&((changed.has("width")||changed.has("height")||changed.has("containerSize")||changed.has("fitTo"))&&(this.simulation?.force("center",this.d3.forceCenter(this.safeWidth/2,this.safeHeight/2)),this.simulation?.alpha(.1).restart()),(changed.has("chargeStrength")||changed.has("edgeDistance"))&&(changed.has("chargeStrength")&&this.chargeForce?.strength(this.safeChargeStrength),changed.has("edgeDistance")&&this.linkForce?.distance(this.safeLinkDistance),this.simulation?.alpha(.3).restart())),this.applyInteractions(changed);const cursorOnly=changed.size>0&&[...changed.keys()].every(key=>key==="activeGraphItem"||key==="graphLiveText");this.renderer==="canvas"&&cursorOnly?this.scheduleCanvasDraw():this.applyCanvasInteractions(),this.focusNodeId==null?this.lastAppliedFocusNodeId=null:this.focusNodeId!==this.lastAppliedFocusNodeId&&this.simNodes.some(n=>n.id===this.focusNodeId)&&(this.lastAppliedFocusNodeId=this.focusNodeId,this.focusNode(this.focusNodeId)),this.updateFocusHalo();const pendingFocus=this.pendingGraphItemFocus;pendingFocus!==void 0&&(this.pendingGraphItemFocus=void 0,pendingFocus==="base"?this.renderRoot.querySelector('[part="canvas"], [part="svg"]')?.focus():this.focusGraphItemElement(pendingFocus))}applyInteractions(changed){if(!this.d3||this.renderer!=="svg")return;const svgEl=this.renderRoot.querySelector("svg");if(svgEl&&svgEl!==this.zoomedEl){this.syncHostResizeObserver(),this.canvasHover=void 0,this.zoomedEl=svgEl,this.gEl=this.renderRoot.querySelector("g"),this.focusHaloEl=this.renderRoot.querySelector('[part="focus-halo"]');const bounds=this.effectiveZoomBounds,zoomBehavior=this.d3.zoom().scaleExtent([bounds.min,bounds.max]).on("start",()=>{this.isApplyingZoomTransform||(this.isPanning=!0,this.cancelCameraTween())}).on("zoom",event=>{this.gEl?.setAttribute("transform",event.transform.toString()),this.updateHitAreaZoomScale(event.transform.k),this.updateEdgeLabelZoomGate(event.transform.k),this.updateNodeLabelZoomGate(event.transform.k),this.scheduleViewportChange()}).on("end",()=>{this.isPanning=!1});this.zoomBehavior=zoomBehavior,this.d3.select(svgEl).call(zoomBehavior),this.updateHitAreaZoomScale(1),this.updateEdgeLabelZoomGate(1),this.updateNodeLabelZoomGate(1)}else if(this.zoomBehavior&&(changed.has("minZoom")||changed.has("maxZoom"))){const bounds=this.effectiveZoomBounds;this.zoomBehavior.scaleExtent([bounds.min,bounds.max])}if(changed.has("nodeLabels")&&this.zoomedEl&&this.updateNodeLabelZoomGate(this.d3.zoomTransform(this.zoomedEl).k),!(changed.has("simNodes")||changed.has("simLinks")||changed.has("nodeTypes")||changed.has("withEdgeLabels")||changed.has("nodeLabels")||changed.has("communities")))return;const nodeEls=Array.from(this.renderRoot.querySelectorAll('[part="node"]'));this.nodeEls=nodeEls,this.nodeHitEls=Array.from(this.renderRoot.querySelectorAll('[data-hit-area="node"]')),this.nodeLabelEls=nodeEls.map(el=>el.parentElement?.querySelector('[part="label"]')??null),this.expandIndicatorEls=nodeEls.map(el=>el.parentElement?.querySelector('[part="expand-indicator"]')??null),this.linkEls=Array.from(this.renderRoot.querySelectorAll('[part="link"]:not([data-dangling])')),this.linkHitEls=Array.from(this.renderRoot.querySelectorAll('[data-hit-area="link"]')),this.linkLabelEls=this.linkEls.map(el=>el.parentElement?.querySelector('[part="link-label"]')??null),this.linkLabelHiddenByLength=[],this.danglingLinkEls=Array.from(this.renderRoot.querySelectorAll('[part="link"][data-dangling]')),this.communityHullEls=Array.from(this.renderRoot.querySelectorAll('[part="hull"]')),this.communityHullHitEls=Array.from(this.renderRoot.querySelectorAll('[data-hit-area="hull"]')),this.communityLabelEls=Array.from(this.renderRoot.querySelectorAll('[part="community-label"]')),this.layout!=="layered"&&nodeEls.forEach((el,i)=>{const id=this.simNodes[i]?.id;if(id!=null)for(const dragTarget of[el,this.nodeHitEls[i]])!dragTarget||this.boundNodeEls.has(dragTarget)||(this.boundNodeEls.add(dragTarget),this.d3.select(dragTarget).call(this.d3.drag().on("start",event=>{this.isDragging=!0,event.sourceEvent?.stopPropagation(),event.active||this.simulation?.alphaTarget(.3).restart();const n=this.simNodeById.get(id);n&&(n.fx=n.x,n.fy=n.y)}).on("drag",event=>{const n=this.simNodeById.get(id);n&&(n.fx=event.x,n.fy=event.y)}).on("end",event=>{this.isDragging=!1,event.active||this.simulation?.alphaTarget(0);const n=this.simNodeById.get(id);n&&(n.fx=null,n.fy=null)})))})}updateHitAreaZoomScale(zoom){const safeZoom=finiteRange(zoom,1,Number.EPSILON);this.gEl?.style.setProperty("--_lr-graph-hit-area-scale",String(1/safeZoom))}applyCanvasInteractions(){if(this.renderer!=="canvas"||!this.canvasEl)return;this.canvasEl!==this.zoomedEl&&(this.zoomedEl=this.canvasEl,this.setUpCanvasSurface());const bounds=this.effectiveZoomBounds;this.zoomBehavior?.scaleExtent([bounds.min,bounds.max]),this.markCanvasDirty()}onTick(){for(const l of this.danglingLinks){const source=l.source,target=l.target;target.x=(source.x??0)+STUB_OFFSET_PX,target.y=(source.y??0)+STUB_OFFSET_PX}for(const n of this.simNodes)n.x!=null&&n.y!=null&&this.lastPositionById.set(n.id,{x:n.x,y:n.y});this.simNodes.forEach((n,i)=>{const el=this.nodeEls[i];el&&(el.tagName==="circle"?(el.setAttribute("cx",String(n.x??0)),el.setAttribute("cy",String(n.y??0))):el.setAttribute("transform",`translate(${n.x??0},${n.y??0})`));const hit=this.nodeHitEls[i];hit&&(hit.setAttribute("x1",String((n.x??0)-NODE_HIT_SEGMENT_HALF)),hit.setAttribute("y1",String(n.y??0)),hit.setAttribute("x2",String((n.x??0)+NODE_HIT_SEGMENT_HALF)),hit.setAttribute("y2",String(n.y??0)));const label=this.nodeLabelEls[i];label&&(label.setAttribute("x",String((n.x??0)+this.nodeRadius(n)+2)),label.setAttribute("y",String(n.y??0)))}),this.simLinks.forEach((l,i)=>{const line=this.linkEls[i],coordinates=this.linkCoordinates(l);for(const target of[line,this.linkHitEls[i]])target&&(target.setAttribute("x1",String(coordinates.x1)),target.setAttribute("y1",String(coordinates.y1)),target.setAttribute("x2",String(coordinates.x2)),target.setAttribute("y2",String(coordinates.y2)))}),this.withEdgeLabels&&this.simLinks.forEach((l,i)=>{const labelEl=this.linkLabelEls[i];if(!labelEl)return;const label=ownGraphText(l,"label"),pos=this.edgeLabelPosition(l);labelEl.setAttribute("x",String(pos.x)),labelEl.setAttribute("y",String(pos.y));const{x1,y1,x2,y2}=this.linkCoordinates(l),edgeLength=Math.hypot(x2-x1,y2-y1),tooLong=this.edgeLabelWidth(label??"")>edgeLength*EDGE_LABEL_LENGTH_GATE_RATIO;this.linkLabelHiddenByLength[i]!==tooLong&&(this.linkLabelHiddenByLength[i]=tooLong,labelEl.setAttribute("visibility",tooLong?"hidden":"visible"))}),this.simNodes.forEach((n,i)=>{const indicator=this.expandIndicatorEls[i];indicator&&indicator.setAttribute("transform",`translate(${n.x??0},${n.y??0})`)}),this.danglingLinks.forEach((l,i)=>{const line=this.danglingLinkEls[i];if(!line)return;const coordinates=this.linkCoordinates(l);line.setAttribute("x1",String(coordinates.x1)),line.setAttribute("y1",String(coordinates.y1)),line.setAttribute("x2",String(coordinates.x2)),line.setAttribute("y2",String(coordinates.y2))}),this.updateFocusHalo(),this.visibleCommunities().forEach((entry,i)=>{const hullEl=this.communityHullEls[i],hullHitEl=this.communityHullHitEls[i],labelEl=this.communityLabelEls[i];if(!hullEl&&!hullHitEl&&!labelEl)return;const hull=this.communityHull(entry.members);hullEl&&hullEl.setAttribute("d",hullPathD(hull)),hullHitEl&&hullHitEl.setAttribute("d",hullPathD(hull)),labelEl&&(labelEl.setAttribute("x",String(hullCentroidX(hull))),labelEl.setAttribute("y",String(hullTopY(hull)-HULL_PADDING)))}),this.renderer==="canvas"&&this.markCanvasDirty(),this.scheduleViewportChange()}rebuildSimulation(){if(!this.d3)return;this.simulation?.stop(),this.boundNodeEls=new WeakSet;const liveIds=new Set(this.graphModel.nodes.map(n=>n.id));for(const id of this.lastPositionById.keys())liveIds.has(id)||this.lastPositionById.delete(id);const visible=this.visibleNodes();if(this.layout==="layered"){this.rebuildLayeredLayout(visible);return}const prevById=new Map(this.simNodes.map(n=>[n.id,n])),nodes=visible.map(n=>{const prev=prevById.get(n.id);if(prev)return{...prev,...n};const remembered=this.lastPositionById.get(n.id);return remembered?{...n,x:remembered.x,y:remembered.y}:{...n}}),byId=new Map(nodes.map(n=>[n.id,n])),{resolved:resolvedLinks,dangling:danglingLinks}=this.resolveLinksAgainst(byId),links=resolvedLinks;this.danglingLinks=danglingLinks;const seedForSpawn=this.safeSeed,incidentLinks=new Map;if(nodes.some(n=>n.x!=null))for(const l of resolvedLinks)for(const id of new Set([l.source.id,l.target.id])){const incident=incidentLinks.get(id);incident?incident.push(l):incidentLinks.set(id,[l])}for(const n of nodes){if(n.x!=null&&n.y!=null)continue;const neighborLink=incidentLinks.get(n.id)?.find(l=>{const source2=l.source,target2=l.target;return source2.id===n.id&&target2.x!=null||target2.id===n.id&&source2.x!=null});if(!neighborLink)continue;const source=neighborLink.source,target=neighborLink.target,neighbor=source.id===n.id?target:source,jitterRadius=this.safeLinkDistance/2,angle=seedForSpawn!=null?hashNodeSeed(seedForSpawn,n.id)/4294967296*Math.PI*2:Math.random()*Math.PI*2;n.x=(neighbor.x??0)+Math.cos(angle)*jitterRadius,n.y=(neighbor.y??0)+Math.sin(angle)*jitterRadius}if(seedForSpawn!=null)for(const n of nodes){if(n.x!=null&&n.y!=null)continue;const rng=mulberry32(hashNodeSeed(seedForSpawn,n.id));n.x=rng()*this.safeWidth,n.y=rng()*this.safeHeight}this.linkForce=this.d3.forceLink(links).distance(this.safeLinkDistance),this.chargeForce=this.d3.forceManyBody().strength(this.safeChargeStrength);const simulation=this.d3.forceSimulation(nodes).force("link",this.linkForce).force("charge",this.chargeForce).force("center",this.d3.forceCenter(this.safeWidth/2,this.safeHeight/2)).force("collide",this.d3.forceCollide().radius(n=>this.nodeRadius(n)+10)).on("tick",()=>this.onTick());if(this.simulation=simulation,prefersReducedMotion(this)||this.safeSeed!=null){const pinnedForSettle=new Set;for(const n of nodes)(prevById.has(n.id)||this.lastPositionById.has(n.id))&&n.x!=null&&n.y!=null&&n.fx==null&&n.fy==null&&(n.fx=n.x,n.fy=n.y,pinnedForSettle.add(n.id));for(simulation.stop();simulation.alpha()>simulation.alphaMin();)simulation.tick();for(const n of nodes)pinnedForSettle.has(n.id)&&(n.fx=null,n.fy=null)}this.simNodes=nodes,this.simNodeById=byId,this.simLinks=links;for(const n of nodes)n.x!=null&&n.y!=null&&this.lastPositionById.set(n.id,{x:n.x,y:n.y});this.announceHiddenNodeCount(nodes.length)}announceHiddenNodeCount(visibleNodeCount){const totalNodeCount=this.graphModel.nodes.length,hiddenNodeCount=totalNodeCount-visibleNodeCount;totalNodeCount>0&&(hiddenNodeCount>0||this.lastHiddenNodeCount>0)&&(this.graphLiveText=this.localize("graphNodesHidden",void 0,{hidden:getNumberFormat(this.effectiveLocale).format(hiddenNodeCount),total:getNumberFormat(this.effectiveLocale).format(totalNodeCount)})),this.lastHiddenNodeCount=hiddenNodeCount}rebuildLayeredLayout(visible){const boxes=visible.map(n=>{const r=this.nodeRadius(n);return{id:n.id,width:r*2,height:r*2}}),visibleIds=new Set(visible.map(n=>n.id)),edges=this.graphModel.links.filter(l=>visibleIds.has(l.source)&&visibleIds.has(l.target)).map(l=>({source:l.source,target:l.target})),{positions:raw}=layeredLayout({nodes:boxes,edges,options:{gapX:12,gapY:this.safeLinkDistance}}),bounds=extent(raw.values(),point=>point.x,point=>point.y),offsetX=raw.size?this.safeWidth/2-(bounds.minX+(bounds.maxX-bounds.minX)/2):this.safeWidth/2,offsetY=raw.size?this.safeHeight/2-(bounds.minY+(bounds.maxY-bounds.minY)/2):this.safeHeight/2,nodes=visible.map(n=>{const p=raw.get(n.id);return{...n,x:p.x+offsetX,y:p.y+offsetY}}),byId=new Map(nodes.map(n=>[n.id,n])),{resolved,dangling}=this.resolveLinksAgainst(byId);this.danglingLinks=dangling,this.simulation=void 0,this.simNodes=nodes,this.simNodeById=byId,this.simLinks=resolved;for(const n of nodes)n.x!=null&&n.y!=null&&this.lastPositionById.set(n.id,{x:n.x,y:n.y});this.announceHiddenNodeCount(nodes.length)}onNodeClick(node,e){const detail={nodeId:node.id,x:node.x??0,y:node.y??0};this.emit("lr-node-activate",{...detail}),this.emitSelectionIntent("node",node.id,!!(e?.ctrlKey||e?.metaKey))}getNodePosition(id){const node=this.simNodes.find(candidate=>candidate.id===id);if(!(!node||!Number.isFinite(node.x)||!Number.isFinite(node.y)))return{x:node.x,y:node.y}}onLinkClick(link,e){const source=typeof link.source=="object"?link.source.id:String(link.source),target=typeof link.target=="object"?link.target.id:String(link.target);this.emit("lr-edge-activate",{sourceNodeId:source,targetNodeId:target,...link.id?{edgeId:link.id}:{}}),this.emitSelectionIntent("link",this.linkKey(link),!!(e?.ctrlKey||e?.metaKey))}onNodeEnter(node,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.setAttribute("data-hovered",""),this.svgHoverNodeId=node.id,this.emit("lr-node-enter",{nodeId:node.id}))}onNodeLeave(node,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.removeAttribute("data-hovered"),this.svgHoverNodeId=void 0,this.emit("lr-node-leave",{nodeId:node.id}))}onNodeDblClick(node,e){e.stopPropagation(),this.emit("lr-node-expand",{nodeId:node.id})}onLinkEnter(link,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.setAttribute("data-hovered",""),this.emitEdgeHover("enter",this.linkHoverDetail(link)))}linkHoverDetail(link){const source=typeof link.source=="object"?link.source.id:String(link.source),target=typeof link.target=="object"?link.target.id:String(link.target);return{sourceNodeId:source,targetNodeId:target,...link.id?{edgeId:link.id}:{}}}onLinkLeave(link,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.removeAttribute("data-hovered"),this.emitEdgeHover("leave",this.linkHoverDetail(link)))}emitEdgeHover(phase,detail){this.emit(phase==="enter"?"lr-edge-enter":"lr-edge-leave",{...detail})}nodeAccessibleText(node){let text=ownGraphText(node,"accessibleLabel")||ownGraphText(node,"label")||node.id;const type=this.resolveNodeType(node),typeLabel=type?ownGraphText(type,"label"):void 0;return typeLabel!==void 0&&(text=this.localize("graphTypedNode",void 0,{label:text,type:typeLabel})),node.expandable&&(text=this.localize("graphExpandableItem",void 0,{item:text})),text}boundedGraphText(value){if(typeof value!="string")return"";const normalized=value.replace(/\s+/g," ").trim();return normalized.length>512?`${normalized.slice(0,512)}…`:normalized}nodeTooltipText(node){return this.boundedGraphText(ownGraphText(node,"description")||ownGraphText(node,"label")||ownGraphText(node,"accessibleLabel")||node.id)}linkAccessibleText(link){const accessibleLabel=ownGraphText(link,"accessibleLabel");if(accessibleLabel)return accessibleLabel;const sourceValue=ownGraphValue(link,"source"),targetValue=ownGraphValue(link,"target"),source=sourceValue!==null&&typeof sourceValue=="object"?this.nodeAccessibleText(sourceValue):typeof sourceValue=="string"?sourceValue:"",target=targetValue!==null&&typeof targetValue=="object"?this.nodeAccessibleText(targetValue):typeof targetValue=="string"?targetValue:"";return ownGraphText(link,"label")||this.localize("graphLink",void 0,{source,target})}linkTooltipText(link){return this.boundedGraphText(ownGraphText(link,"description")||ownGraphText(link,"label")||ownGraphText(link,"accessibleLabel")||this.linkAccessibleText(link))}linkCoordinates(link){const source=link.source,target=link.target,x1=source.x??0,y1=source.y??0,targetX=target.x??0,targetY=target.y??0;if(!link.directed||link.dangling)return{x1,y1,x2:targetX,y2:targetY};const dx=targetX-x1,dy=targetY-y1,distance=Math.hypot(dx,dy);if(distance===0)return{x1,y1,x2:targetX,y2:targetY};const inset=Math.min(this.nodeRadius(target),distance);return{x1,y1,x2:targetX-dx/distance*inset,y2:targetY-dy/distance*inset}}edgeLabelPosition(link){const{x1,y1,x2,y2}=this.linkCoordinates(link),dx=x2-x1,dy=y2-y1,len=Math.hypot(dx,dy),mx=(x1+x2)/2,my=(y1+y2)/2;return len===0?{x:mx,y:my}:{x:mx+-dy/len*EDGE_LABEL_OFFSET_PX,y:my+dx/len*EDGE_LABEL_OFFSET_PX}}edgeLabelFontPx(){const raw=this.computedStyle().getPropertyValue("--lr-font-size-2xs").trim();return resolveCssTokenLength(raw,{host:this})??DEFAULT_EDGE_LABEL_FONT_PX}edgeLabelContext(){return this.edgeLabelMeasureCanvas?.ownerDocument!==this.ownerDocument&&(this.edgeLabelMeasureCanvas=this.ownerDocument.createElement("canvas"),this.edgeLabelMeasureCtx=this.edgeLabelMeasureCanvas.getContext("2d")),this.edgeLabelMeasureCtx??null}edgeLabelWidth(text){const cached=this.edgeLabelWidthCache.get(text);if(cached!=null)return cached;const ctx=this.edgeLabelContext();let width;if(ctx){const fontFamily=this.computedStyle().getPropertyValue("--lr-font").trim()||"sans-serif";ctx.font=`${this.edgeLabelFontPx()}px ${fontFamily}`,width=ctx.measureText(text).width}else width=text.length*this.edgeLabelFontPx()*.6;if(this.edgeLabelWidthCache.size>=EDGE_LABEL_WIDTH_CACHE_MAX){const oldest=this.edgeLabelWidthCache.keys().next().value;oldest!==void 0&&this.edgeLabelWidthCache.delete(oldest)}return this.edgeLabelWidthCache.set(text,width),width}updateEdgeLabelZoomGate(k){this.gEl&&(k<this.safeEdgeLabelMinZoom?this.gEl.setAttribute("data-edge-labels-hidden",""):this.gEl.removeAttribute("data-edge-labels-hidden"))}updateNodeLabelZoomGate(k){this.gEl&&(this.resolvedNodeLabelsMode==="zoom"&&k<NODE_LABEL_MIN_ZOOM?this.gEl.setAttribute("data-node-labels-hidden",""):this.gEl.removeAttribute("data-node-labels-hidden"))}linkIndexBase(){return this.simNodes.length}communityIndexBase(){return this.linkIndexBase()+this.navigableLinks().length}graphItemCount(){return this.communityIndexBase()+this.visibleCommunities().length}normalizedGraphItem(index=this.activeGraphItem){const count=this.graphItemCount();return count?Math.min(Math.max(index,0),count-1):-1}graphItemIdentity(index){if(index<0)return;if(index<this.linkIndexBase()){const node=this.simNodes[index];return node?{kind:"node",id:node.id}:void 0}if(index<this.communityIndexBase()){const link=this.navigableLinks()[index-this.linkIndexBase()];return link?{kind:"link",id:this.linkKey(link)}:void 0}const community=this.visibleCommunities()[index-this.communityIndexBase()]?.community;return community?{kind:"community",id:community.id}:void 0}graphItemIndex(identity){if(identity.kind==="node")return this.simNodes.findIndex(node=>node.id===identity.id);if(identity.kind==="link"){const index2=this.navigableLinks().findIndex(link=>this.linkKey(link)===identity.id);return index2<0?-1:this.linkIndexBase()+index2}const index=this.visibleCommunities().findIndex(entry=>entry.community.id===identity.id);return index<0?-1:this.communityIndexBase()+index}communityText(community){return ownGraphText(community,"label")??community.id}graphItemText(index){if(index<this.linkIndexBase()){const node=this.simNodes[index];return node?this.localize("graphNode",void 0,{label:this.nodeTooltipText(node)}):""}if(index<this.communityIndexBase()){const link=this.navigableLinks()[index-this.linkIndexBase()];return link?this.linkTooltipText(link):""}const entry=this.visibleCommunities()[index-this.communityIndexBase()];return entry?this.localize("graphCommunity",void 0,{label:this.communityText(entry.community),count:getNumberFormat(this.effectiveLocale).format(entry.members.length)}):""}graphItemAnnouncement(index){return this.localize("graphItemAnnouncement",void 0,{item:this.graphItemText(index),index:getNumberFormat(this.effectiveLocale).format(index+1),total:getNumberFormat(this.effectiveLocale).format(this.graphItemCount())})}onGraphItemFocus(index){this.normalizedGraphItem(index)<0||(this.activeGraphItem=index,this.graphLiveText=this.graphItemAnnouncement(index))}focusGraphItem(index){const normalized=this.normalizedGraphItem(index);normalized<0||(this.activeGraphItem=normalized,this.graphLiveText=this.graphItemAnnouncement(normalized),this.updateComplete.then(()=>this.focusGraphItemElement(normalized)))}focusGraphItemElement(index){if(this.renderer==="canvas"){this.renderRoot.querySelector('[part="cursor-item"]')?.focus(),this.scheduleCanvasDraw();return}[...this.renderRoot.querySelectorAll('[part="node"]'),...this.renderRoot.querySelectorAll('[part="link"][tabindex]'),...this.renderRoot.querySelectorAll('[part="hull"]')][index]?.focus()}onGraphKeyDown(e,index,activate){if(e.key==="Enter"||e.key===" "){if(e.preventDefault(),e.repeat)return;if(this.onGraphItemFocus(index),activate(e),index<this.simNodes.length){const now=this.ownerWindow?.performance.now()??0;if(this.lastKeyActivateIndex===index&&now-this.lastKeyActivateTime<=EXPAND_KEY_INTERVAL_MS){const node=this.simNodes[index];node&&this.emit("lr-node-expand",{nodeId:node.id}),this.lastKeyActivateIndex=null}else this.lastKeyActivateIndex=index,this.lastKeyActivateTime=now}return}const count=this.graphItemCount();if(!count)return;const rtl=isRtl(this),forwardKey=rtl?"ArrowLeft":"ArrowRight",backwardKey=rtl?"ArrowRight":"ArrowLeft";let next=index;if(e.key===forwardKey||e.key==="ArrowDown")next=Math.min(count-1,index+1);else if(e.key===backwardKey||e.key==="ArrowUp")next=Math.max(0,index-1);else if(e.key==="Home")next=0;else if(e.key==="End")next=count-1;else return;e.preventDefault(),this.focusGraphItem(next)}render(){const nodeLimit=publicCollectionTruncation(this,"nodes"),edgeLimit=publicCollectionTruncation(this,"edges"),limitNotices=html`${nodeLimit?html`<p part="limit" role="note">${this.localize("graphNodeLimit",void 0,{shown:getNumberFormat(this.effectiveLocale).format(nodeLimit.retained),total:getNumberFormat(this.effectiveLocale).format(nodeLimit.source)})}</p>`:nothing}${edgeLimit?html`<p part="limit" role="note">${this.localize("graphEdgeLimit",void 0,{shown:getNumberFormat(this.effectiveLocale).format(edgeLimit.retained),total:getNumberFormat(this.effectiveLocale).format(edgeLimit.source)})}</p>`:nothing}`;if(this.loading)return html`
1
+ import{__decorate}from"tslib";import{collectionSupport,publicCollectionTruncation}from"../../../internal/collection-snapshot.js";import{html,nothing,svg}from"lit";import{property,state,query}from"lit/decorators.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{fitTransform}from"../../../internal/fit-transform.js";import{specialistTokens}from"../../../internal/specialist-host-tokens.styles.js";import{nextId,srOnly}from"../../../internal/a11y.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{isRtl}from"../../../internal/rtl.js";import{literalSetConverter}from"../../../internal/converters.js";import{resolveCssTokenLength}from"../../../internal/css-token-length.js";import{styles}from"./graph.styles.js";import{loadD3}from"./graph-loader.js";import{convexHull,hullPathD,hullCentroidX,hullTopY}from"./graph-hull.js";import{EXPAND_BADGE_OFFSET,EXPAND_BADGE_R,drawGraphScene,drawPickingScene,pickColorToIndex,shapeHalfSide}from"./graph-canvas.js";import{layeredLayout}from"../../../internal/layered-layout.js";import{finiteNumber,finiteRange,finiteInteger,extent}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{sanitizeCssColor}from"../../../internal/safe-css.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{shadowFocusTarget}from"../../../internal/active-element.js";import{ThemeWatcher}from"../../../internal/theme-watcher.js";import{devWarnOnce}from"../../../internal/dev-warning.js";import{copyGraphLinkIdentity,graphLengthConverter,graphLinkIdentity,normalizeGraphModel}from"./graph-model.js";import{canonicalIdentityList}from"../retrieval-identity.js";import{AnnouncementSinkController}from"../../../internal/announcer.js";import"../../overlays/skeleton/skeleton.class.js";import{LYRA_DEFAULT_graphCommunity,LYRA_DEFAULT_graphDataList,LYRA_DEFAULT_graphDataListLimit,LYRA_DEFAULT_graphDiagram,LYRA_DEFAULT_graphEdgeLimit,LYRA_DEFAULT_graphExpandableItem,LYRA_DEFAULT_graphItemAnnouncement,LYRA_DEFAULT_graphLink,LYRA_DEFAULT_graphMissingLibrary,LYRA_DEFAULT_graphNode,LYRA_DEFAULT_graphNodeFocused,LYRA_DEFAULT_graphNodeLimit,LYRA_DEFAULT_graphNodesHidden,LYRA_DEFAULT_graphSelectionCount,LYRA_DEFAULT_graphTypedNode}from"../../../internal/default-strings/retrieval.generated.js";import{LYRA_DEFAULT_loading,LYRA_DEFAULT_noData}from"../../../internal/default-strings/shared.generated.js";const GRAPH_LAYOUT=literalSetConverter(["force","layered"],"force"),STUB_OFFSET_PX=14,EDGE_LABEL_OFFSET_PX=4,DEFAULT_EDGE_LABEL_FONT_PX=10,EDGE_LABEL_LENGTH_GATE_RATIO=.85,EDGE_LABEL_WIDTH_CACHE_MAX=512,EXPAND_KEY_INTERVAL_MS=500,FOCUS_HALO_PADDING=6,HULL_PADDING=24,NODE_LABEL_MIN_ZOOM=.5,NODE_HIT_SEGMENT_HALF=.5;function ownGraphText(value,property2){const descriptor=getOwnDataDescriptor(value,property2);return descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR||typeof descriptor.value!="string"?void 0:descriptor.value}function ownGraphValue(value,property2){const descriptor=getOwnDataDescriptor(value,property2);return descriptor===MISSING_OWN_DATA_DESCRIPTOR||descriptor===UNSAFE_OWN_DATA_DESCRIPTOR?void 0:descriptor.value}function mulberry32(seed){let a=seed>>>0;return()=>{a=a+1831565813|0;let t=Math.imul(a^a>>>15,a|1);return t=t+Math.imul(t^t>>>7,t|61)^t,((t^t>>>14)>>>0)/4294967296}}function hashNodeSeed(seed,id){let h=seed>>>0;for(let i=0;i<id.length;i++)h=Math.imul(h^id.charCodeAt(i),2654435761),h^=h>>>15;return h>>>0}const MIN_RADIUS=6,MAX_RADIUS=24;function sanitizeNodeColor(color){return sanitizeCssColor(color)}function normalizeLinkDash(dash){if(!(!dash?.length||dash.some(value=>!Number.isFinite(value)||value<0)))return dash.join(" ")}function categoricalPaletteColor(index){return`var(--lr-graph-cat-${index%8+1})`}function squarePath(r){const s=shapeHalfSide(r);return`M ${-s} ${-s} L ${s} ${-s} L ${s} ${s} L ${-s} ${s} Z`}function diamondPath(r){const d=shapeHalfSide(r)*Math.SQRT2;return`M 0 ${-d} L ${d} 0 L 0 ${d} L ${-d} 0 Z`}function sameIds(a,b){return a===b?!0:!a||!b||a.length!==b.length?!1:a.every((id,index)=>id===b[index])}const identitySets=new WeakMap;function identitySet(values){const ids=canonicalIdentityList(values);let set=identitySets.get(ids);return set||identitySets.set(ids,set=new Set(ids)),set}class LyraGraph extends LyraElement{static{this.defaultStrings={...super.defaultStrings,graphCommunity:LYRA_DEFAULT_graphCommunity,graphDataList:LYRA_DEFAULT_graphDataList,graphDataListLimit:LYRA_DEFAULT_graphDataListLimit,graphDiagram:LYRA_DEFAULT_graphDiagram,graphEdgeLimit:LYRA_DEFAULT_graphEdgeLimit,graphExpandableItem:LYRA_DEFAULT_graphExpandableItem,graphItemAnnouncement:LYRA_DEFAULT_graphItemAnnouncement,graphLink:LYRA_DEFAULT_graphLink,graphMissingLibrary:LYRA_DEFAULT_graphMissingLibrary,graphNode:LYRA_DEFAULT_graphNode,graphNodeFocused:LYRA_DEFAULT_graphNodeFocused,graphNodeLimit:LYRA_DEFAULT_graphNodeLimit,graphNodesHidden:LYRA_DEFAULT_graphNodesHidden,graphSelectionCount:LYRA_DEFAULT_graphSelectionCount,graphTypedNode:LYRA_DEFAULT_graphTypedNode,loading:LYRA_DEFAULT_loading,noData:LYRA_DEFAULT_noData}}static{this.collectionSupport=collectionSupport}static{this.ownedCollectionProperties=Object.freeze(["nodes","edges","nodeTypes","hiddenTypes","communities","selectedNodeIds","selectedEdgeIds","dimmedNodeIds","dimmedEdgeIds"])}static get observedAttributes(){return[...new Set([...super.observedAttributes,"role"])]}static{this.styles=[LyraElement.styles,specialistTokens,styles,srOnly]}static{this.immutableEventDetails=Object.freeze(["lr-selection-change"])}get graphModel(){const sources=this.normalizedGraphSources;return(!sources||sources[0]!==this.nodes||sources[1]!==this.edges||sources[2]!==this.nodeTypes||sources[3]!==this.communities)&&(this.normalizedGraphSources=[this.nodes,this.edges,this.nodeTypes,this.communities],this.normalizedGraphModel=normalizeGraphModel(this.nodes,this.edges,this.nodeTypes,this.communities)),this.normalizedGraphModel}get layout(){return this._layout}set layout(next){const normalized=GRAPH_LAYOUT.normalize(next),old=this._layout;old!==normalized&&(this._layout=normalized,this.requestUpdate("layout",old))}constructor(){super(),this.nodes=[],this.edges=[],this.nodeTypes=[],this.hiddenTypes=[],this.communities=[],this._layout="force",this.renderer="svg",this.fitTo="none",this.width=800,this.height=600,this.chargeStrength=-300,this.edgeDistance=100,this.minZoom=.1,this.maxZoom=8,this.label=null,this.accessibleLabel=null,this.withEdgeLabels=!1,this.edgeLabelMinZoom=.6,this.focusNodeId=null,this.selectionMode="none",this.selectedNodeIds=[],this.selectedEdgeIds=[],this.dimmedNodeIds=[],this.dimmedEdgeIds=[],this.arrowMarkerId=nextId("graph-arrow"),this.loading=!0,this.loadFailed=!1,this.loadLibrary=loadD3,this.loadGeneration=0,this.containerSize=null,this.simNodes=[],this.simLinks=[],this.simNodeById=new Map,this.danglingLinks=[],this.lastPositionById=new Map,this.lastHiddenNodeCount=0,this.activeGraphItem=0,this.graphLiveText="",this.announcements=new AnnouncementSinkController(this,{eager:["polite","assertive"]}),this.graphAnnouncementsReady=!1,this.isMounting=!0,this.authorRole=null,this.syncingGraphHostRole=!1,this.detachedGraphChanges=new Map,this.boundNodeEls=new WeakSet,this.nodeEls=[],this.nodeHitEls=[],this.nodeLabelEls=[],this.expandIndicatorEls=[],this.lastKeyActivateIndex=null,this.lastKeyActivateTime=0,this.lastAppliedFocusNodeId=null,this.communityHullEls=[],this.communityHullHitEls=[],this.communityLabelEls=[],this.visible=!0,this.canvasDrawPending=!1,this.pickDirty=!0,this.canvasCamera={k:1,x:0,y:0},this.pickItems=[],this.canvasSceneHasEdgeLabels=!1,this.isCameraTweening=!1,this.linkEls=[],this.linkHitEls=[],this.linkLabelEls=[],this.linkLabelHiddenByLength=[],this.edgeLabelWidthCache=new Map,this.danglingLinkEls=[],this.linkPaintVisibilityCache=new Map,this.resolvedCssColorCache=new Map,this.reducedMotion=!1,this.isApplyingZoomTransform=!1,this.onCanvasDprChange=()=>{this.watchCanvasDpr(),this.markCanvasDirty()},this.onCanvasPointerDown=e=>{if(e.button!==0||(this.canvasPointerDownAt={x:e.clientX,y:e.clientY},this.canvasPointerDownId=e.pointerId,this.layout==="layered"))return;const hit=this.hitTest(e.clientX,e.clientY);if(hit?.kind==="node"){this.canvasDragNode=hit.node,this.canvasPointerId=e.pointerId;try{this.canvasEl.setPointerCapture(e.pointerId)}catch{}hit.node.fx=hit.node.x,hit.node.fy=hit.node.y,this.simulation?.alphaTarget(.3).restart()}},this.onCanvasPointerMove=e=>{if(this.canvasDragNode&&this.canvasPointerId===e.pointerId){const node=this.simNodeById.get(this.canvasDragNode.id);if(node){const rect=this.canvasEl.getBoundingClientRect();node.fx=(e.clientX-rect.left-this.canvasCamera.x)/this.canvasCamera.k,node.fy=(e.clientY-rect.top-this.canvasCamera.y)/this.canvasCamera.k,this.markCanvasDirty()}return}if(this.pendingHover={x:e.clientX,y:e.clientY},this.hoverRafId!=null)return;const frameOwner=this.ownerWindow;frameOwner&&(this.hoverRafOwner=frameOwner,this.hoverRafId=frameOwner.requestAnimationFrame(()=>{if(this.hoverRafId=void 0,this.hoverRafOwner=void 0,!this.isConnected||this.ownerWindow!==frameOwner)return;const pending=this.pendingHover;if(this.pendingHover=void 0,!pending||this.canvasHoverSuppressed()||this.pickDirty&&this.simulationIsTicking())return;const hit=this.hitTest(pending.x,pending.y);this.updateCanvasTooltip(hit,pending.x,pending.y),this.updateCanvasHover(hit)}))},this.onCanvasPointerUp=e=>{this.finishCanvasNodeDrag(e.pointerId);const down=this.takeCanvasPointerDown(e.pointerId);if(!down||Math.hypot(e.clientX-down.x,e.clientY-down.y)>5)return;const hit=this.hitTest(e.clientX,e.clientY);if(!hit){this.clearSelection();return}hit.kind==="node"?this.onNodeClick(hit.node,e):hit.kind==="link"?this.onLinkClick(hit.link,e):this.onCommunityClick(hit.entry.community)},this.onCanvasPointerCancel=e=>{this.finishCanvasNodeDrag(e.pointerId),this.takeCanvasPointerDown(e.pointerId)},this.onCanvasLostPointerCapture=e=>{this.finishCanvasNodeDrag(e.pointerId,!1),this.takeCanvasPointerDown(e.pointerId)},this.onCanvasPointerLeave=()=>{this.pendingHover=void 0,this.hoverRafId!=null&&(this.hoverRafOwner?.cancelAnimationFrame(this.hoverRafId),this.hoverRafId=void 0,this.hoverRafOwner=void 0),this.updateCanvasTooltip(void 0,0,0),this.canvasHoverSuppressed()?this.canvasHover=void 0:this.updateCanvasHover(void 0)},this.onCanvasDblClick=e=>{const hit=this.hitTest(e.clientX,e.clientY),node=hit?.kind==="node"?hit.node:this.nodeAtCanvasPoint(e.clientX,e.clientY);node&&(e.stopImmediatePropagation(),this.emit("lr-node-expand",{nodeId:node.id}))},this.isDragging=!1,this.isPanning=!1,new ThemeWatcher(this,()=>{const reduced=prefersReducedMotion(this);reduced!==this.reducedMotion&&(this.reducedMotion=reduced,reduced?this.simulation?.stop():this.safeSeed==null&&this.simulation?.restart()),this.linkPaintVisibilityCache.clear(),this.resolvedCssColorCache.clear(),this.renderer==="canvas"&&this.markCanvasDirty()},["(prefers-reduced-motion: reduce)"])}attributeChangedCallback(name,oldValue,value){super.attributeChangedCallback(name,oldValue,value),name==="role"&&oldValue!==value&&!this.syncingGraphHostRole&&(this.authorRole=value)}hostOwnsGraphSemantics(){return this.hasAttribute("aria-label")}syncGraphHostRole(){if(this.authorRole===null){this.syncingGraphHostRole=!0;try{this.hostOwnsGraphSemantics()?this.setAttribute("role","group"):this.removeAttribute("role")}finally{this.syncingGraphHostRole=!1}}}get ownerWindow(){return this.ownerDocument.defaultView??void 0}computedStyle(element=this){const view=this.ownerWindow;return view?view.getComputedStyle(element):"style"in element?element.style:this.style}connectedCallback(){if(super.connectedCallback(),this.detachedGraphChanges.size){for(const[key,previous]of this.detachedGraphChanges)this.requestUpdate(key,previous);this.detachedGraphChanges.clear(),this.requestUpdate()}this.reducedMotion=prefersReducedMotion(this);const IntersectionObserverCtor=this.ownerWindow?.IntersectionObserver;if(IntersectionObserverCtor&&(this.intersectionObserver=new IntersectionObserverCtor(entries=>{const wasVisible=this.visible;this.visible=entries[0]?.isIntersecting??!0,this.visible&&!wasVisible&&this.canvasDrawPending&&(this.canvasDrawPending=!1,this.scheduleCanvasDraw())}),this.intersectionObserver.observe(this)),this.fitTo==="container"&&(this.syncHostResizeObserver(),this.measureHostBox()),this.d3){!this.reducedMotion&&this.safeSeed==null&&this.simulation?.restart(),this.renderer==="canvas"&&this.canvasEl&&this.canvasEl===this.zoomedEl&&(this.ensureCanvasOwnerRealm(),this.syncHostResizeObserver(),this.watchCanvasDpr(),this.markCanvasDirty());return}const generation=++this.loadGeneration;this.loadLibrary().then(async mods=>{try{await this.updateComplete}catch{return}if(await new Promise(resolve=>this.updateBrowserDerivedState(resolve)),!(generation!==this.loadGeneration||!this.isConnected)){if(this.loading=!1,!mods){this.loadFailed=!0;return}this.loadFailed=!1,this.d3=mods,this.rebuildSimulation()}})}disconnectedCallback(){super.disconnectedCallback(),this.loadGeneration+=1,this.simulation?.stop(),this.finishCanvasNodeDrag(void 0,!0,!1),this.takeCanvasPointerDown(),this.cancelCameraTween(),this.intersectionObserver?.disconnect(),this.intersectionObserver=void 0,this.hostResizeObserver?.disconnect(),this.hostResizeObserver=void 0,this.hostResizeObserverDocument=void 0,this.canvasDprQuery?.removeEventListener("change",this.onCanvasDprChange),this.canvasDprQuery=void 0,this.canvasDrawRafId!=null&&(this.canvasDrawRafOwner?.cancelAnimationFrame(this.canvasDrawRafId),this.canvasDrawRafId=void 0,this.canvasDrawRafOwner=void 0),this.hoverRafId!=null&&(this.hoverRafOwner?.cancelAnimationFrame(this.hoverRafId),this.hoverRafId=void 0,this.hoverRafOwner=void 0),this.pendingHover=void 0,this.canvasHover=void 0,this.canvasTooltipEl?.setAttribute("hidden",""),this.pendingGraphItemFocus=void 0,this.viewportChangeRafId!=null&&(this.viewportChangeRafOwner?.cancelAnimationFrame(this.viewportChangeRafId),this.viewportChangeRafId=void 0,this.viewportChangeRafOwner=void 0)}adoptedCallback(){super.adoptedCallback(),this.announcements.adopted(),this.ensureCanvasOwnerRealm()}scheduleViewportChange(){if(this.viewportChangeRafId!=null)return;const frameOwner=this.ownerWindow;frameOwner&&(this.viewportChangeRafOwner=frameOwner,this.viewportChangeRafId=frameOwner.requestAnimationFrame(()=>{if(this.viewportChangeRafId=void 0,this.viewportChangeRafOwner=void 0,!this.isConnected||this.ownerWindow!==frameOwner)return;const transform=this.renderer==="canvas"||!this.d3||!this.zoomedEl?this.canvasCamera:this.d3.zoomTransform(this.zoomedEl);this.emit("lr-viewport-change",{zoom:transform.k,x:transform.x,y:transform.y,k:transform.k})}))}nodeRadius(n){const r=n.radius??(MIN_RADIUS+MAX_RADIUS)/2;return Number.isFinite(r)?Math.min(MAX_RADIUS,Math.max(MIN_RADIUS,r)):(MIN_RADIUS+MAX_RADIUS)/2}safeLinkWidth(link){return finiteRange(link.width??1.5,1.5,0)}isInteractiveLink(link,resolveColor,defaultPaint){if(this.safeLinkWidth(link)<=0)return!1;const effectivePaint=sanitizeNodeColor(link.color)??defaultPaint,color=effectivePaint?resolveColor(effectivePaint).trim().toLowerCase():void 0;if(!color)return!0;if(color==="transparent"||/^#[\da-f]{4}$/.test(color)&&color.endsWith("0")||/^#[\da-f]{8}$/.test(color)&&color.endsWith("00")||/\/\s*0(?:\.0+)?%?\s*\)$/.test(color)||/^(?:rgba|hsla)\(/.test(color)&&/,\s*0(?:\.0+)?\s*\)$/.test(color))return!1;const cached=this.linkPaintVisibilityCache.get(color);if(cached!==void 0)return cached;this.linkPaintProbe??=this.ownerDocument.createElement("canvas"),this.linkPaintProbe.width=1,this.linkPaintProbe.height=1;const context=this.linkPaintProbe.getContext("2d",{willReadFrequently:!0});if(!context)return!0;let visible=!0;try{context.clearRect(0,0,1,1),context.fillStyle="rgb(1 2 3)",context.fillStyle=color,context.fillRect(0,0,1,1),visible=context.getImageData(0,0,1,1).data[3]!==0}catch{visible=!0}return this.linkPaintVisibilityCache.set(color,visible),visible}navigableLinks(){return this.navigableLinksCache||(this.navigableLinksCache=this.simLinks.length?this.withCanvasColorResolver(resolveColor=>{const computed=this.computedStyle(),defaultPaint=computed.getPropertyValue("--lr-graph-edge-color").trim()||computed.getPropertyValue("--lr-color-border").trim();return this.simLinks.filter(link=>this.isInteractiveLink(link,resolveColor,defaultPaint))}):[]),this.navigableLinksCache}lengthInPixels(value){return typeof value=="string"?resolveCssTokenLength(value,{host:this})??Number.NaN:value}get requestedWidth(){return finiteRange(this.lengthInPixels(this.width),800,1)}get requestedHeight(){return finiteRange(this.lengthInPixels(this.height),600,1)}get safeWidth(){const requested=this.requestedWidth,measured=this.fitTo==="container"&&this.containerSize;return measured?finiteRange(measured.width,requested,1):requested}get safeHeight(){const requested=this.requestedHeight,measured=this.fitTo==="container"&&this.containerSize;return measured?finiteRange(measured.height,requested,1):requested}recordContainerSize(width,height){const w=Math.round(finiteRange(width,0,0)),h=Math.round(finiteRange(height,0,0));return w<=0||h<=0||this.containerSize?.width===w&&this.containerSize?.height===h?!1:(this.containerSize={width:w,height:h},!0)}measureHostBox(){return this.isConnected?(this.syncRequestedHeightVar(),this.recordContainerSize(this.clientWidth,this.clientHeight)):!1}syncRequestedHeightVar(){this.style.setProperty("--_lr-graph-requested-height",`${this.requestedHeight}px`)}get safeMinZoom(){return finiteRange(this.minZoom,.1,.001,1e3)}get safeMaxZoom(){return finiteRange(this.maxZoom,8,.001,1e3)}get effectiveZoomBounds(){const min=this.safeMinZoom,max=this.safeMaxZoom;return Object.freeze({min:Math.min(min,max),max:Math.max(min,max)})}get safeEdgeLabelMinZoom(){return finiteRange(this.edgeLabelMinZoom,.6,.001,1e3)}get resolvedNodeLabelsMode(){return this.nodeLabels??(this.renderer==="canvas"?"zoom":"always")}canvasNodeLabelsVisible(){const mode=this.resolvedNodeLabelsMode;return mode==="none"?!1:mode==="zoom"?this.canvasCamera.k>=NODE_LABEL_MIN_ZOOM:!0}get safeSeed(){return this.seed==null?void 0:finiteInteger(this.seed,0)}get safeChargeStrength(){return finiteNumber(this.chargeStrength,-300)}get safeLinkDistance(){return finiteRange(this.edgeDistance,100,0)}nodeTypeEntry(node){const types=this.graphModel.nodeTypes;if(this.nodeTypeIndex?.[0]!==types){const labeled=this.labeledNodeTypes();this.nodeTypeIndex=[types,new Map(types.map((type,index)=>{const slot=labeled.indexOf(type);return[type.id,[type,slot<0?index:slot]]}))]}return node.type==null?void 0:this.nodeTypeIndex[1].get(node.type)}resolveNodeType(node){return this.nodeTypeEntry(node)?.[0]}nodeShape(node){return this.resolveNodeType(node)?.shape??"circle"}labeledNodeTypes(){return this.graphModel.nodeTypes.filter(candidate=>typeof candidate?.label=="string"&&candidate.label.trim().length>0)}nodeFill(node){const ownColor=sanitizeNodeColor(node.color);if(ownColor)return ownColor;const entry=this.nodeTypeEntry(node);if(entry)return sanitizeNodeColor(entry[0].color)||categoricalPaletteColor(entry[1])}visibleNodes(){const hiddenTypes=canonicalIdentityList(this.hiddenTypes);if(!hiddenTypes.length)return this.graphModel.nodes;const hidden=new Set(hiddenTypes);return this.graphModel.nodes.filter(n=>n.type==null||!hidden.has(n.type))}resolveLinksAgainst(byId){const nodeExists=new Set(this.graphModel.nodes.map(n=>n.id)),resolved=[],dangling=[];for(const l of this.graphModel.links){const source=byId.get(l.source);if(!source)continue;const target=byId.get(l.target);target?resolved.push(copyGraphLinkIdentity(l,{...l,source,target})):nodeExists.has(l.target)||dangling.push(copyGraphLinkIdentity(l,{...l,source,target:{id:l.target,x:source.x,y:source.y},dangling:!0}))}return{resolved,dangling}}communityMembers(community){const idSet=new Set(community.memberIds);return this.simNodes.filter(n=>idSet.has(n.id)||n.communityId===community.id)}visibleCommunities(){return this.visibleCommunitiesCache||(this.visibleCommunitiesCache=this.graphModel.communities.map(community=>({community,members:this.communityMembers(community)})).filter(entry=>entry.members.length>0)),this.visibleCommunitiesCache}communityHull(members){return convexHull(members.map(n=>({x:n.x??0,y:n.y??0})))}onCommunityClick(community){this.emit("lr-community-activate",{communityId:community.id})}cameraTransitionMs(){const parsed=parseFloat(this.computedStyle().getPropertyValue("--lr-transition-base"));return Number.isFinite(parsed)?parsed:180}cancelCameraTween(){this.cameraTweenId!=null&&(this.cameraTweenFrameOwner?.cancelAnimationFrame(this.cameraTweenId),this.cameraTweenId=void 0,this.cameraTweenFrameOwner=void 0),this.isCameraTweening=!1;const resolve=this.cameraTweenResolve;resolve&&(this.cameraTweenResolve=void 0,resolve(!1))}applyZoomTransform(transform){if(!(!this.d3||!this.zoomedEl||!this.zoomBehavior)){this.isApplyingZoomTransform=!0;try{this.zoomBehavior.transform(this.d3.select(this.zoomedEl),transform)}finally{this.isApplyingZoomTransform=!1}}}tweenCamera(computeTarget){return new Promise(resolve=>{if(!this.d3||!this.zoomedEl||!this.zoomBehavior){resolve(!1);return}this.cancelCameraTween(),this.cameraTweenResolve=resolve,this.isCameraTweening=!0;const frameOwner=this.ownerWindow;if(!frameOwner){this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!1);return}if(prefersReducedMotion(this)){this.applyZoomTransform(computeTarget()),this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!0);return}const current=this.d3.zoomTransform(this.zoomedEl),duration=this.cameraTransitionMs(),start=frameOwner.performance.now(),startK=current.k,startX=current.x,startY=current.y,step=now=>{if(this.cameraTweenResolve!==resolve)return;if(!this.isConnected||this.ownerWindow!==frameOwner){this.cameraTweenId=void 0,this.cameraTweenFrameOwner=void 0,this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!1);return}const t=!prefersReducedMotion(this)&&duration>0?Math.min(1,(now-start)/duration):1,target=computeTarget(),targetK=target.k,targetX=target.x,targetY=target.y;this.applyZoomTransform(this.d3.zoomIdentity.translate(startX+(targetX-startX)*t,startY+(targetY-startY)*t).scale(startK+(targetK-startK)*t)),t<1?(this.cameraTweenFrameOwner=frameOwner,this.cameraTweenId=frameOwner.requestAnimationFrame(step)):(this.cameraTweenId=void 0,this.cameraTweenFrameOwner=void 0,this.isCameraTweening=!1,this.cameraTweenResolve=void 0,resolve(!0))};this.cameraTweenFrameOwner=frameOwner,this.cameraTweenId=frameOwner.requestAnimationFrame(step)})}async focusNode(id,options){const node=this.simNodes.find(n=>n.id===id);if(!node||!this.d3||!this.zoomedEl||!this.zoomBehavior)return!1;const current=this.d3.zoomTransform(this.zoomedEl),bounds=this.effectiveZoomBounds,k=finiteRange(options?.zoom??current.k,current.k,bounds.min,bounds.max),arrived=await this.tweenCamera(()=>this.d3.zoomIdentity.translate(this.safeWidth/2-k*(node.x??0),this.safeHeight/2-k*(node.y??0)).scale(k));return arrived&&(this.graphLiveText=this.localize("graphNodeFocused",void 0,{label:this.nodeAccessibleText(node)})),arrived}fit(options){if(!this.d3||!this.zoomedEl||!this.zoomBehavior||!this.simNodes.length)return;const padding=finiteRange(options?.padding??24,24,0);this.tweenCamera(()=>{const fitPoints=[];for(const n of this.simNodes){const r=this.nodeRadius(n);fitPoints.push({x:(n.x??0)-r,y:(n.y??0)-r}),fitPoints.push({x:(n.x??0)+r,y:(n.y??0)+r})}for(const entry of this.visibleCommunities())for(const p of this.communityHull(entry.members))fitPoints.push({x:p.x-HULL_PADDING,y:p.y-HULL_PADDING}),fitPoints.push({x:p.x+HULL_PADDING,y:p.y+HULL_PADDING});const{minX,maxX,minY,maxY}=extent(fitPoints,point=>point.x,point=>point.y),bounds=this.effectiveZoomBounds,transform=fitTransform({minX,minY,maxX,maxY},{width:this.safeWidth,height:this.safeHeight},padding,bounds);return this.d3.zoomIdentity.translate(transform.x,transform.y).scale(transform.zoom)})}updateFocusHalo(){if(!this.focusHaloEl)return;const node=this.focusNodeId!=null?this.simNodes.find(n=>n.id===this.focusNodeId):void 0;node?(this.focusHaloEl.setAttribute("cx",String(node.x??0)),this.focusHaloEl.setAttribute("cy",String(node.y??0)),this.focusHaloEl.setAttribute("r",String(this.nodeRadius(node)+FOCUS_HALO_PADDING)),this.focusHaloEl.removeAttribute("hidden")):this.focusHaloEl.setAttribute("hidden","")}setUpCanvasSurface(){this.canvasCtx=this.canvasEl.getContext("2d")??void 0,this.ensureCanvasOwnerRealm(),this.syncHostResizeObserver(),this.watchCanvasDpr(),this.canvasTooltipEl=this.renderRoot.querySelector('[part="tooltip"]')??void 0,this.bindCanvasPointer(),this.bindCanvasZoom()}ensureCanvasOwnerRealm(){const ownerDocument=this.ownerDocument;this.edgeLabelMeasureCanvas?.ownerDocument!==ownerDocument&&(this.edgeLabelMeasureCanvas=void 0,this.edgeLabelMeasureCtx=void 0,this.edgeLabelWidthCache.clear()),!(!this.pickCanvas&&this.renderer!=="canvas")&&this.pickCanvas?.ownerDocument!==ownerDocument&&(this.pickCanvas=ownerDocument.createElement("canvas"),this.pickCtx=this.pickCanvas.getContext("2d",{willReadFrequently:!0}),this.pickDirty=!0)}syncHostResizeObserver(){if(this.renderer!=="canvas"&&this.fitTo!=="container"){this.hostResizeObserver?.disconnect(),this.hostResizeObserver=void 0,this.hostResizeObserverDocument=void 0;return}this.hostResizeObserver&&this.hostResizeObserverDocument===this.ownerDocument||this.watchHostResize()}watchHostResize(){this.hostResizeObserver?.disconnect();const ResizeObserverCtor=this.ownerWindow?.ResizeObserver;if(!ResizeObserverCtor){this.hostResizeObserver=void 0,this.hostResizeObserverDocument=void 0;return}this.hostResizeObserver=new ResizeObserverCtor(entries=>{const box=entries[entries.length-1]?.contentRect;this.fitTo==="container"&&box&&this.recordContainerSize(box.width,box.height),this.renderer==="canvas"&&this.canvasEl&&this.markCanvasDirty()}),this.hostResizeObserverDocument=this.ownerDocument,this.hostResizeObserver.observe(this)}watchCanvasDpr(){this.canvasDprQuery?.removeEventListener("change",this.onCanvasDprChange);const view=this.ownerWindow;if(!view?.matchMedia){this.canvasDprQuery=void 0;return}this.canvasDprQuery=view.matchMedia(`(resolution: ${view.devicePixelRatio}dppx)`),this.canvasDprQuery.addEventListener("change",this.onCanvasDprChange)}markCanvasDirty(){this.canvasScene=void 0,this.pickDirty=!0,this.scheduleCanvasDraw()}markCanvasCameraDirty(){this.pickDirty=!0,this.scheduleCanvasDraw()}scheduleCanvasDraw(){if(!this.visible){this.canvasDrawPending=!0;return}if(this.canvasDrawRafId!=null)return;const frameOwner=this.ownerWindow;frameOwner&&(this.canvasDrawRafOwner=frameOwner,this.canvasDrawRafId=frameOwner.requestAnimationFrame(()=>{this.canvasDrawRafId=void 0,this.canvasDrawRafOwner=void 0,!(!this.isConnected||this.ownerWindow!==frameOwner)&&this.drawCanvas()}))}resolveCssColorWithProbe(value,probe){const cached=this.resolvedCssColorCache.get(value);if(cached!==void 0)return cached;probe.style.color="",probe.style.color=value;const result=getComputedStyle(probe).color.trim()||getComputedStyle(this).color||"transparent";return this.resolvedCssColorCache.set(value,result),result}createCanvasColorProbe(){const probe=this.ownerDocument.createElement("span");return probe.setAttribute("aria-hidden","true"),probe.style.position="absolute",probe.style.inlineSize="0",probe.style.blockSize="0",probe.style.overflow="hidden",probe.style.visibility="hidden",probe.style.pointerEvents="none",this.renderRoot.append(probe),probe}withCanvasColorResolver(callback){let probe;try{return callback(value=>{const cached=this.resolvedCssColorCache.get(value);return cached!==void 0?cached:(probe??=this.createCanvasColorProbe(),this.resolveCssColorWithProbe(value,probe))})}finally{probe?.remove()}}buildCanvasScene(cs){return this.withCanvasColorResolver(resolveColor=>{const hullFillDefault=cs.getPropertyValue("--lr-graph-hull-fill").trim()||cs.getPropertyValue("--lr-color-brand").trim(),hulls=this.visibleCommunities().map(entry=>({d:hullPathD(this.communityHull(entry.members)),fill:resolveColor(sanitizeNodeColor(entry.community.color)??hullFillDefault)})),linkColorDefault=cs.getPropertyValue("--lr-graph-edge-color").trim()||cs.getPropertyValue("--lr-color-border").trim(),links=this.simLinks.map(l=>{const coords=this.linkCoordinates(l),own=sanitizeNodeColor(l.color);return{x1:coords.x1,y1:coords.y1,x2:coords.x2,y2:coords.y2,color:resolveColor(own??linkColorDefault),width:this.safeLinkWidth(l),dash:l.dash,directed:l.directed,selected:this.isSelected("link",this.linkKey(l)),dimmed:this.isDimmed("link",this.linkKey(l))}}),edgeLabels=this.withEdgeLabels&&this.canvasCamera.k>=this.safeEdgeLabelMinZoom?this.simLinks.flatMap(l=>{const label=ownGraphText(l,"label");if(!label)return[];const pos=this.edgeLabelPosition(l),coords=this.linkCoordinates(l),edgeLength=Math.hypot(coords.x2-coords.x1,coords.y2-coords.y1);return this.edgeLabelWidth(label)>edgeLength*EDGE_LABEL_LENGTH_GATE_RATIO?[]:[{x:pos.x,y:pos.y,text:label}]}):[],nodeFillDefault=cs.getPropertyValue("--lr-graph-node-fill").trim()||cs.getPropertyValue("--lr-color-brand").trim(),nodes=this.simNodes.map(n=>{const fill=this.nodeFill(n);return{x:n.x??0,y:n.y??0,r:this.nodeRadius(n),shape:this.nodeShape(n),fill:resolveColor(fill??nodeFillDefault),selected:this.isSelected("node",n.id),dimmed:this.isDimmed("node",n.id)}}),nodeLabels=this.simNodes.flatMap(n=>{const label=ownGraphText(n,"label");return label?[{x:(n.x??0)+this.nodeRadius(n)+2,y:n.y??0,text:label}]:[]}),expandIndicators=this.simNodes.filter(n=>n.expandable).map(n=>({x:n.x??0,y:n.y??0,r:this.nodeRadius(n)})),focusNode=this.focusNodeId!=null?this.simNodes.find(n=>n.id===this.focusNodeId):void 0,scene={hulls,links,edgeLabels,nodes,nodeLabels,expandIndicators,focusHalo:focusNode?{x:focusNode.x??0,y:focusNode.y??0,r:this.nodeRadius(focusNode)+FOCUS_HALO_PADDING}:void 0,showNodeLabels:this.canvasNodeLabelsVisible(),haloColor:resolveColor(this.ownerWindow?.matchMedia?.("(forced-colors: active)").matches?"CanvasText":cs.getPropertyValue("--lr-graph-focus-halo-color").trim()||cs.getPropertyValue("--lr-color-brand").trim()),selectedColor:resolveColor(cs.getPropertyValue("--lr-graph-selected-color").trim()||cs.getPropertyValue("--lr-color-success").trim()),dimmedOpacity:(()=>{const value=Number(cs.getPropertyValue("--lr-graph-dimmed-opacity").trim());return Number.isFinite(value)?Math.min(1,Math.max(0,value)):.35})(),hullOpacity:(()=>{const value=Number(cs.getPropertyValue("--lr-graph-hull-opacity").trim());return Number.isFinite(value)?Math.min(1,Math.max(0,value)):.12})(),labelColor:resolveColor(cs.getPropertyValue("--lr-color-text").trim()),labelHaloColor:resolveColor(cs.getPropertyValue("--lr-graph-edge-label-halo").trim()||cs.getPropertyValue("--lr-color-surface").trim()),expandBadgeFill:resolveColor(cs.getPropertyValue("--lr-color-surface").trim()),expandBadgeStroke:resolveColor(cs.getPropertyValue("--lr-color-border-strong").trim()),font:`${this.edgeLabelFontPx()}px ${cs.getPropertyValue("--lr-font").trim()||"sans-serif"}`,borderWidths:["thin","medium","thick"].map((size,index)=>resolveCssTokenLength(cs.getPropertyValue(`--lr-border-width-${size}`).trim(),{host:this})??index+1)};return this.updateCanvasFocus(scene),scene})}updateCanvasFocus(scene){const index=shadowFocusTarget(this)?.getAttribute("part")==="cursor-item"?this.normalizedGraphItem():-1,node=index>=0&&index<this.linkIndexBase()?this.simNodes[index]:void 0,link=index>=this.linkIndexBase()&&index<this.communityIndexBase()?this.navigableLinks()[index-this.linkIndexBase()]:void 0,community=index>=this.communityIndexBase()?this.visibleCommunities()[index-this.communityIndexBase()]:void 0;scene.keyboardFocusRing=node?{x:node.x??0,y:node.y??0,r:this.nodeRadius(node)+4}:void 0,scene.keyboardFocusLink=link?{...this.linkCoordinates(link),width:this.safeLinkWidth(link)}:void 0,scene.keyboardFocusHull=community?{d:hullPathD(this.communityHull(community.members))}:void 0}drawCanvas(){if(!this.canvasEl||!this.canvasCtx)return;const dpr=this.ownerWindow?.devicePixelRatio||1,w=this.canvasEl.clientWidth||this.safeWidth,h=this.canvasEl.clientHeight||this.safeHeight,backingW=Math.round(w*dpr),backingH=Math.round(h*dpr);(this.canvasEl.width!==backingW||this.canvasEl.height!==backingH)&&(this.canvasEl.width=backingW,this.canvasEl.height=backingH);const ctx=this.canvasCtx;ctx.setTransform(dpr,0,0,dpr,0,0),ctx.clearRect(0,0,w,h);const edgeLabelsVisible=this.withEdgeLabels&&this.canvasCamera.k>=this.safeEdgeLabelMinZoom,nodeLabelsVisible=this.canvasNodeLabelsVisible();(!this.canvasScene||this.canvasScene.showNodeLabels!==nodeLabelsVisible||this.canvasSceneHasEdgeLabels!==edgeLabelsVisible)&&(this.canvasScene=this.buildCanvasScene(this.computedStyle()),this.canvasSceneHasEdgeLabels=edgeLabelsVisible),this.updateCanvasFocus(this.canvasScene),drawGraphScene(ctx,this.canvasCamera,this.canvasScene)}rebuildPickItems(){this.pickItems=[...this.visibleCommunities().map(entry=>({kind:"hull",entry})),...this.navigableLinks().map(link=>({kind:"link",link})),...this.simNodes.map(node=>({kind:"node",node}))]}redrawPickCanvas(){if(!this.pickCtx||!this.canvasEl||!this.pickCanvas)return;(this.pickCanvas.width!==this.canvasEl.width||this.pickCanvas.height!==this.canvasEl.height)&&(this.pickCanvas.width=this.canvasEl.width,this.pickCanvas.height=this.canvasEl.height),this.rebuildPickItems();const dpr=this.ownerWindow?.devicePixelRatio||1;this.pickCtx.setTransform(dpr,0,0,dpr,0,0),drawPickingScene(this.pickCtx,this.canvasCamera,{hulls:this.pickItems.filter(i=>i.kind==="hull").map(i=>({d:hullPathD(this.communityHull(i.entry.members))})),links:this.pickItems.filter(i=>i.kind==="link").map(i=>{const c=this.linkCoordinates(i.link);return{x1:c.x1,y1:c.y1,x2:c.x2,y2:c.y2,width:this.safeLinkWidth(i.link)}}),nodes:this.pickItems.filter(i=>i.kind==="node").map(i=>({x:i.node.x??0,y:i.node.y??0,r:this.nodeRadius(i.node)+2,shape:this.nodeShape(i.node)}))}),this.pickDirty=!1}hitTest(clientX,clientY){if(!this.canvasEl||!this.pickCtx)return;this.pickDirty&&this.redrawPickCanvas();const rect=this.canvasEl.getBoundingClientRect(),dpr=this.ownerWindow?.devicePixelRatio||1,px=Math.round((clientX-rect.left)*dpr),py=Math.round((clientY-rect.top)*dpr);if(px<0||py<0||px>=this.pickCtx.canvas.width||py>=this.pickCtx.canvas.height)return;const data=this.pickCtx.getImageData(px,py,1,1).data,index=pickColorToIndex(data[0],data[1],data[2]);return index>=0?this.pickItems[index]:void 0}bindCanvasZoom(){if(!this.d3||!this.canvasEl)return;const bounds=this.effectiveZoomBounds,zoomBehavior=this.d3.zoom().scaleExtent([bounds.min,bounds.max]).on("start",()=>{this.isApplyingZoomTransform||(this.isPanning=!0,this.cancelCameraTween())}).on("zoom",event=>{this.canvasCamera={k:event.transform.k,x:event.transform.x,y:event.transform.y},this.markCanvasCameraDirty(),this.scheduleViewportChange()}).on("end",()=>{this.isPanning=!1});this.zoomBehavior=zoomBehavior,this.d3.select(this.canvasEl).call(zoomBehavior)}bindCanvasPointer(){const canvas=this.canvasEl;canvas.addEventListener("pointerdown",this.onCanvasPointerDown),canvas.addEventListener("pointermove",this.onCanvasPointerMove),canvas.addEventListener("pointerup",this.onCanvasPointerUp),canvas.addEventListener("pointercancel",this.onCanvasPointerCancel),canvas.addEventListener("lostpointercapture",this.onCanvasLostPointerCapture),canvas.addEventListener("pointerleave",this.onCanvasPointerLeave),canvas.addEventListener("dblclick",this.onCanvasDblClick)}simulationIsTicking(){return this.simulation!=null&&this.simulation.alpha()>this.simulation.alphaMin()}finishCanvasNodeDrag(pointerId,releaseCapture=!0,redraw=!0){const activePointerId=this.canvasPointerId;if(activePointerId==null||pointerId!=null&&pointerId!==activePointerId)return;const node=this.canvasDragNode&&this.simNodeById.get(this.canvasDragNode.id);if(this.canvasDragNode=void 0,this.canvasPointerId=void 0,this.simulation?.alphaTarget(0),node&&(node.fx=null,node.fy=null),releaseCapture&&this.canvasEl)try{this.canvasEl.releasePointerCapture(activePointerId)}catch{}redraw?this.markCanvasDirty():(this.canvasScene=void 0,this.pickDirty=!0)}takeCanvasPointerDown(pointerId){if(pointerId!=null&&this.canvasPointerDownId!==pointerId)return;const down=this.canvasPointerDownAt;return this.canvasPointerDownAt=void 0,this.canvasPointerDownId=void 0,down}canvasHoverSuppressed(){return!!this.canvasDragNode||this.isDragging||this.isPanning||this.isCameraTweening}updateCanvasHover(hit){const next=hit?.kind==="node"?{kind:"node",id:hit.node.id}:hit?.kind==="link"?{kind:"link",id:this.linkKey(hit.link),detail:this.linkHoverDetail(hit.link)}:void 0,previous=this.canvasHover;previous?.kind===next?.kind&&previous?.id===next?.id||(this.canvasHover=next,previous?.kind==="node"?this.emit("lr-node-leave",{nodeId:previous.id}):previous?.kind==="link"&&this.emitEdgeHover("leave",previous.detail),!(!this.isConnected||this.renderer!=="canvas"||this.canvasHover!==next)&&(next?.kind==="node"?this.emit("lr-node-enter",{nodeId:next.id}):next?.kind==="link"&&this.emitEdgeHover("enter",next.detail)))}nodeAtCanvasPoint(clientX,clientY){if(!this.canvasEl)return;const rect=this.canvasEl.getBoundingClientRect(),worldX=(clientX-rect.left-this.canvasCamera.x)/this.canvasCamera.k,worldY=(clientY-rect.top-this.canvasCamera.y)/this.canvasCamera.k;let closest,closestDistance=1/0;for(const node of this.simNodes){const distance=Math.hypot((node.x??0)-worldX,(node.y??0)-worldY);distance<=this.nodeRadius(node)+2/this.canvasCamera.k&&distance<closestDistance&&(closest=node,closestDistance=distance)}return closest}updateCanvasTooltip(hit,clientX,clientY){if(!this.canvasTooltipEl)return;if(!hit||hit.kind==="hull"){this.canvasTooltipEl.setAttribute("hidden","");return}const rect=this.canvasEl.getBoundingClientRect();this.canvasTooltipEl.textContent=hit.kind==="node"?this.nodeTooltipText(hit.node):this.linkTooltipText(hit.link);let left=clientX-rect.left,top=clientY-rect.top;this.canvasTooltipEl.style.left=`${left}px`,this.canvasTooltipEl.style.top=`${top}px`,this.canvasTooltipEl.removeAttribute("hidden");const tooltipRect=this.canvasTooltipEl.getBoundingClientRect(),view=this.ownerWindow;if(!view)return;const minLeft=Math.max(0,rect.left),maxRight=Math.min(view.innerWidth,rect.right),minTop=Math.max(0,rect.top),maxBottom=Math.min(view.innerHeight,rect.bottom);tooltipRect.right>maxRight&&(left-=tooltipRect.right-maxRight),tooltipRect.left<minLeft&&(left+=minLeft-tooltipRect.left),tooltipRect.bottom>maxBottom&&(top-=tooltipRect.bottom-maxBottom),tooltipRect.top<minTop&&(top+=minTop-tooltipRect.top),this.canvasTooltipEl.style.left=`${left}px`,this.canvasTooltipEl.style.top=`${top}px`}isSelected(kind,id){return identitySet(kind==="node"?this.selectedNodeIds:this.selectedEdgeIds).has(id)}paintedCurrent(kind,id){return this.selectionMode==="none"&&this.isSelected(kind,id)?"true":nothing}isDimmed(kind,id){return identitySet(kind==="node"?this.dimmedNodeIds:this.dimmedEdgeIds).has(id)}linkKey(link){return graphLinkIdentity(link)}emitSelectionIntent(kind,id,toggle){if(this.selectionMode==="none")return;const selected=this.isSelected(kind,id),time=this.ownerWindow?.performance.now()??0,repeat=this.lastActivation?.id===id&&time-this.lastActivation.time<=EXPAND_KEY_INTERVAL_MS;if(this.lastActivation={id,time},this.selectionMode==="single"||!toggle){if(this.selectionMode==="single"&&selected){repeat||this.emit("lr-selection-change",{selectedNodeIds:[],selectedEdgeIds:[]});return}this.emit("lr-selection-change",kind==="node"?{selectedNodeIds:[id],selectedEdgeIds:[]}:{selectedNodeIds:[],selectedEdgeIds:[id]});return}const selectedNodeIds=canonicalIdentityList(this.selectedNodeIds),selectedLinkIds=canonicalIdentityList(this.selectedEdgeIds),nodeIds=kind==="node"?selected?selectedNodeIds.filter(x=>x!==id):[...selectedNodeIds,id]:selectedNodeIds,linkIds=kind==="link"?selected?selectedLinkIds.filter(x=>x!==id):[...selectedLinkIds,id]:selectedLinkIds;this.emit("lr-selection-change",{selectedNodeIds:nodeIds,selectedEdgeIds:linkIds})}clearSelection(){this.selectionMode!=="none"&&(!canonicalIdentityList(this.selectedNodeIds).length&&!canonicalIdentityList(this.selectedEdgeIds).length||this.emit("lr-selection-change",{selectedNodeIds:[],selectedEdgeIds:[]}))}willUpdate(changed){super.willUpdate(changed),changed.has("height")&&this.syncRequestedHeightVar(),changed.has("fitTo")&&this.fitTo!=="container"&&(this.containerSize=null),this.fitTo==="container"&&!this.containerSize&&this.measureHostBox();const cursorOnly=changed.size>0&&[...changed.keys()].every(key=>key==="activeGraphItem"||key==="graphLiveText");cursorOnly||this.resolvedCssColorCache.clear(),cursorOnly||(this.navigableLinksCache=void 0),this.syncGraphHostRole();const wasMounting=this.isMounting;this.isMounting=!1;const hiddenTypesChanged=changed.has("hiddenTypes")&&!sameIds(canonicalIdentityList(changed.get("hiddenTypes")??[]),canonicalIdentityList(this.hiddenTypes)),structureChanged=this.d3&&(changed.has("nodes")||changed.has("edges")||hiddenTypesChanged||changed.has("layout")||this.layout==="layered"&&changed.has("edgeDistance")),graphItemsChanged=!!(structureChanged||changed.has("simNodes")||changed.has("communities")),activePart=shadowFocusTarget(this)?.getAttribute("part")??"",hadGraphItemFocus=graphItemsChanged&&["node","link","hull","cursor-item"].includes(activePart),previousIndex=this.normalizedGraphItem(),previousIdentity=graphItemsChanged?this.graphItemIdentity(previousIndex):void 0;if(structureChanged&&this.isConnected){this.rebuildSimulation(),this.renderer==="svg"&&this.simNodes.length+this.simLinks.length>1e3&&devWarnOnce("lr-graph-svg-scale",'<lr-graph>: renderer="svg" draws every node and link as DOM; use renderer="canvas" above about 1,000 of them.');const hovered=this.svgHoverNodeId;hovered!=null&&!this.simNodeById.has(hovered)&&(this.svgHoverNodeId=void 0,this.emit("lr-node-leave",{nodeId:hovered})),this.canvasHover?.kind==="node"&&!this.simNodeById.has(this.canvasHover.id)&&this.updateCanvasHover(void 0),this.navigableLinksCache=void 0}if(graphItemsChanged){this.visibleCommunitiesCache=void 0;const retainedIndex=previousIdentity?this.graphItemIndex(previousIdentity):-1,nextIndex=retainedIndex>=0?retainedIndex:this.normalizedGraphItem(previousIndex);this.activeGraphItem=nextIndex>=0?nextIndex:0,hadGraphItemFocus&&(this.pendingGraphItemFocus=nextIndex>=0?nextIndex:"base",nextIndex>=0&&(this.graphLiveText=this.graphItemAnnouncement(nextIndex)))}const selectedNodeIdsChanged=changed.has("selectedNodeIds")&&!sameIds(changed.get("selectedNodeIds"),this.selectedNodeIds),selectedLinkIdsChanged=changed.has("selectedEdgeIds")&&!sameIds(changed.get("selectedEdgeIds"),this.selectedEdgeIds);(selectedNodeIdsChanged||selectedLinkIdsChanged)&&!wasMounting&&(this.graphLiveText=this.localize("graphSelectionCount",void 0,{count:getNumberFormat(this.effectiveLocale).format(canonicalIdentityList(this.selectedNodeIds).length+canonicalIdentityList(this.selectedEdgeIds).length)}))}updated(changed){if(super.updated(changed),!this.isConnected){for(const[key,previous]of changed)this.detachedGraphChanges.has(key)||this.detachedGraphChanges.set(key,previous);return}this.setAttribute("aria-busy",String(this.loading));const announceGraphText=this.graphAnnouncementsReady&&changed.has("graphLiveText")&&this.graphLiveText!=="";if(!this.loading&&!this.loadFailed&&(this.graphAnnouncementsReady=!0),announceGraphText&&this.announcements.announcePolite(this.graphLiveText),changed.has("loadFailed")&&changed.get("loadFailed")!==void 0&&this.loadFailed&&this.announcements.announceAssertive(this.localize("graphMissingLibrary")),(changed.has("fitTo")||changed.has("renderer"))&&this.syncHostResizeObserver(),!this.d3)return;!changed.has("nodes")&&!changed.has("edges")&&!changed.has("hiddenTypes")&&((changed.has("width")||changed.has("height")||changed.has("containerSize")||changed.has("fitTo"))&&(this.simulation?.force("center",this.d3.forceCenter(this.safeWidth/2,this.safeHeight/2)),this.simulation?.alpha(.1).restart()),(changed.has("chargeStrength")||changed.has("edgeDistance"))&&(changed.has("chargeStrength")&&this.chargeForce?.strength(this.safeChargeStrength),changed.has("edgeDistance")&&this.linkForce?.distance(this.safeLinkDistance),this.simulation?.alpha(.3).restart())),this.applyInteractions(changed);const cursorOnly=changed.size>0&&[...changed.keys()].every(key=>key==="activeGraphItem"||key==="graphLiveText");this.renderer==="canvas"&&cursorOnly?this.scheduleCanvasDraw():this.applyCanvasInteractions(),this.focusNodeId==null?this.lastAppliedFocusNodeId=null:this.focusNodeId!==this.lastAppliedFocusNodeId&&this.simNodes.some(n=>n.id===this.focusNodeId)&&(this.lastAppliedFocusNodeId=this.focusNodeId,this.focusNode(this.focusNodeId)),this.updateFocusHalo();const pendingFocus=this.pendingGraphItemFocus;pendingFocus!==void 0&&(this.pendingGraphItemFocus=void 0,pendingFocus==="base"?this.renderRoot.querySelector('[part="canvas"], [part="svg"]')?.focus():this.focusGraphItemElement(pendingFocus))}applyInteractions(changed){if(!this.d3||this.renderer!=="svg")return;const svgEl=this.renderRoot.querySelector("svg"),reboundSurface=svgEl&&svgEl!==this.zoomedEl;if(svgEl&&reboundSurface){this.syncHostResizeObserver(),this.canvasHover=void 0,this.zoomedEl=svgEl,this.gEl=this.renderRoot.querySelector("g"),this.focusHaloEl=this.renderRoot.querySelector('[part="focus-halo"]');const bounds=this.effectiveZoomBounds,zoomBehavior=this.d3.zoom().scaleExtent([bounds.min,bounds.max]).on("start",()=>{this.isApplyingZoomTransform||(this.isPanning=!0,this.cancelCameraTween())}).on("zoom",event=>{this.gEl?.setAttribute("transform",event.transform.toString()),this.updateHitAreaZoomScale(event.transform.k),this.updateEdgeLabelZoomGate(event.transform.k),this.updateNodeLabelZoomGate(event.transform.k),this.scheduleViewportChange()}).on("end",()=>{this.isPanning=!1});this.zoomBehavior=zoomBehavior,this.d3.select(svgEl).call(zoomBehavior),this.updateHitAreaZoomScale(1),this.updateEdgeLabelZoomGate(1),this.updateNodeLabelZoomGate(1)}else if(this.zoomBehavior&&(changed.has("minZoom")||changed.has("maxZoom"))){const bounds=this.effectiveZoomBounds;this.zoomBehavior.scaleExtent([bounds.min,bounds.max])}if(changed.has("nodeLabels")&&this.zoomedEl&&this.updateNodeLabelZoomGate(this.d3.zoomTransform(this.zoomedEl).k),!(reboundSurface||changed.has("simNodes")||changed.has("simLinks")||changed.has("nodeTypes")||changed.has("withEdgeLabels")||changed.has("nodeLabels")||changed.has("communities")))return;const nodeEls=Array.from(this.renderRoot.querySelectorAll('[part="node"]'));this.nodeEls=nodeEls,this.nodeHitEls=Array.from(this.renderRoot.querySelectorAll('[data-hit-area="node"]')),this.nodeLabelEls=nodeEls.map(el=>el.parentElement?.querySelector('[part="label"]')??null),this.expandIndicatorEls=nodeEls.map(el=>el.parentElement?.querySelector('[part="expand-indicator"]')??null),this.linkEls=Array.from(this.renderRoot.querySelectorAll('[part="link"]:not([data-dangling])')),this.linkHitEls=Array.from(this.renderRoot.querySelectorAll('[data-hit-area="link"]')),this.linkLabelEls=this.linkEls.map(el=>el.parentElement?.querySelector('[part="link-label"]')??null),this.linkLabelHiddenByLength=[],this.danglingLinkEls=Array.from(this.renderRoot.querySelectorAll('[part="link"][data-dangling]')),this.communityHullEls=Array.from(this.renderRoot.querySelectorAll('[part="hull"]')),this.communityHullHitEls=Array.from(this.renderRoot.querySelectorAll('[data-hit-area="hull"]')),this.communityLabelEls=Array.from(this.renderRoot.querySelectorAll('[part="community-label"]')),this.layout!=="layered"&&nodeEls.forEach((el,i)=>{const id=this.simNodes[i]?.id;if(id!=null)for(const dragTarget of[el,this.nodeHitEls[i]])!dragTarget||this.boundNodeEls.has(dragTarget)||(this.boundNodeEls.add(dragTarget),this.d3.select(dragTarget).call(this.d3.drag().on("start",event=>{this.isDragging=!0,event.sourceEvent?.stopPropagation(),event.active||this.simulation?.alphaTarget(.3).restart();const n=this.simNodeById.get(id);n&&(n.fx=n.x,n.fy=n.y)}).on("drag",event=>{const n=this.simNodeById.get(id);n&&(n.fx=event.x,n.fy=event.y)}).on("end",event=>{this.isDragging=!1,event.active||this.simulation?.alphaTarget(0);const n=this.simNodeById.get(id);n&&(n.fx=null,n.fy=null)})))})}updateHitAreaZoomScale(zoom){const safeZoom=finiteRange(zoom,1,Number.EPSILON);this.gEl?.style.setProperty("--_lr-graph-hit-area-scale",String(1/safeZoom))}applyCanvasInteractions(){if(this.renderer!=="canvas"||!this.canvasEl)return;this.canvasEl!==this.zoomedEl&&(this.zoomedEl=this.canvasEl,this.setUpCanvasSurface());const bounds=this.effectiveZoomBounds;this.zoomBehavior?.scaleExtent([bounds.min,bounds.max]),this.markCanvasDirty()}onTick(){for(const l of this.danglingLinks){const source=l.source,target=l.target;target.x=(source.x??0)+STUB_OFFSET_PX,target.y=(source.y??0)+STUB_OFFSET_PX}for(const n of this.simNodes)n.x!=null&&n.y!=null&&this.lastPositionById.set(n.id,{x:n.x,y:n.y});this.simNodes.forEach((n,i)=>{const el=this.nodeEls[i];el&&(el.tagName==="circle"?(el.setAttribute("cx",String(n.x??0)),el.setAttribute("cy",String(n.y??0))):el.setAttribute("transform",`translate(${n.x??0},${n.y??0})`));const hit=this.nodeHitEls[i];hit&&(hit.setAttribute("x1",String((n.x??0)-NODE_HIT_SEGMENT_HALF)),hit.setAttribute("y1",String(n.y??0)),hit.setAttribute("x2",String((n.x??0)+NODE_HIT_SEGMENT_HALF)),hit.setAttribute("y2",String(n.y??0)));const label=this.nodeLabelEls[i];label&&(label.setAttribute("x",String((n.x??0)+this.nodeRadius(n)+2)),label.setAttribute("y",String(n.y??0)))}),this.simLinks.forEach((l,i)=>{const line=this.linkEls[i],coordinates=this.linkCoordinates(l);for(const target of[line,this.linkHitEls[i]])target&&(target.setAttribute("x1",String(coordinates.x1)),target.setAttribute("y1",String(coordinates.y1)),target.setAttribute("x2",String(coordinates.x2)),target.setAttribute("y2",String(coordinates.y2)))}),this.withEdgeLabels&&this.simLinks.forEach((l,i)=>{const labelEl=this.linkLabelEls[i];if(!labelEl)return;const label=ownGraphText(l,"label"),pos=this.edgeLabelPosition(l);labelEl.setAttribute("x",String(pos.x)),labelEl.setAttribute("y",String(pos.y));const{x1,y1,x2,y2}=this.linkCoordinates(l),edgeLength=Math.hypot(x2-x1,y2-y1),tooLong=this.edgeLabelWidth(label??"")>edgeLength*EDGE_LABEL_LENGTH_GATE_RATIO;this.linkLabelHiddenByLength[i]!==tooLong&&(this.linkLabelHiddenByLength[i]=tooLong,labelEl.setAttribute("visibility",tooLong?"hidden":"visible"))}),this.simNodes.forEach((n,i)=>{const indicator=this.expandIndicatorEls[i];indicator&&indicator.setAttribute("transform",`translate(${n.x??0},${n.y??0})`)}),this.danglingLinks.forEach((l,i)=>{const line=this.danglingLinkEls[i];if(!line)return;const coordinates=this.linkCoordinates(l);line.setAttribute("x1",String(coordinates.x1)),line.setAttribute("y1",String(coordinates.y1)),line.setAttribute("x2",String(coordinates.x2)),line.setAttribute("y2",String(coordinates.y2))}),this.updateFocusHalo(),this.visibleCommunities().forEach((entry,i)=>{const hullEl=this.communityHullEls[i],hullHitEl=this.communityHullHitEls[i],labelEl=this.communityLabelEls[i];if(!hullEl&&!hullHitEl&&!labelEl)return;const hull=this.communityHull(entry.members);hullEl&&hullEl.setAttribute("d",hullPathD(hull)),hullHitEl&&hullHitEl.setAttribute("d",hullPathD(hull)),labelEl&&(labelEl.setAttribute("x",String(hullCentroidX(hull))),labelEl.setAttribute("y",String(hullTopY(hull)-HULL_PADDING)))}),this.renderer==="canvas"&&this.markCanvasDirty(),this.scheduleViewportChange()}rebuildSimulation(){if(!this.d3)return;this.simulation?.stop(),this.boundNodeEls=new WeakSet;const liveIds=new Set(this.graphModel.nodes.map(n=>n.id));for(const id of this.lastPositionById.keys())liveIds.has(id)||this.lastPositionById.delete(id);const visible=this.visibleNodes();if(this.layout==="layered"){this.rebuildLayeredLayout(visible);return}const prevById=new Map(this.simNodes.map(n=>[n.id,n])),nodes=visible.map(n=>{const prev=prevById.get(n.id);if(prev)return{...prev,...n};const remembered=this.lastPositionById.get(n.id);return remembered?{...n,x:remembered.x,y:remembered.y}:{...n}}),byId=new Map(nodes.map(n=>[n.id,n])),{resolved:resolvedLinks,dangling:danglingLinks}=this.resolveLinksAgainst(byId),links=resolvedLinks;this.danglingLinks=danglingLinks;const seedForSpawn=this.safeSeed,incidentLinks=new Map;if(nodes.some(n=>n.x!=null))for(const l of resolvedLinks)for(const id of new Set([l.source.id,l.target.id])){const incident=incidentLinks.get(id);incident?incident.push(l):incidentLinks.set(id,[l])}for(const n of nodes){if(n.x!=null&&n.y!=null)continue;const neighborLink=incidentLinks.get(n.id)?.find(l=>{const source2=l.source,target2=l.target;return source2.id===n.id&&target2.x!=null||target2.id===n.id&&source2.x!=null});if(!neighborLink)continue;const source=neighborLink.source,target=neighborLink.target,neighbor=source.id===n.id?target:source,jitterRadius=this.safeLinkDistance/2,angle=seedForSpawn!=null?hashNodeSeed(seedForSpawn,n.id)/4294967296*Math.PI*2:Math.random()*Math.PI*2;n.x=(neighbor.x??0)+Math.cos(angle)*jitterRadius,n.y=(neighbor.y??0)+Math.sin(angle)*jitterRadius}if(seedForSpawn!=null)for(const n of nodes){if(n.x!=null&&n.y!=null)continue;const rng=mulberry32(hashNodeSeed(seedForSpawn,n.id));n.x=rng()*this.safeWidth,n.y=rng()*this.safeHeight}this.linkForce=this.d3.forceLink(links).distance(this.safeLinkDistance),this.chargeForce=this.d3.forceManyBody().strength(this.safeChargeStrength);const simulation=this.d3.forceSimulation(nodes).force("link",this.linkForce).force("charge",this.chargeForce).force("center",this.d3.forceCenter(this.safeWidth/2,this.safeHeight/2)).force("collide",this.d3.forceCollide().radius(n=>this.nodeRadius(n)+10)).on("tick",()=>this.onTick());if(this.simulation=simulation,prefersReducedMotion(this)||this.safeSeed!=null){const pinnedForSettle=new Set;for(const n of nodes)(prevById.has(n.id)||this.lastPositionById.has(n.id))&&n.x!=null&&n.y!=null&&n.fx==null&&n.fy==null&&(n.fx=n.x,n.fy=n.y,pinnedForSettle.add(n.id));for(simulation.stop();simulation.alpha()>simulation.alphaMin();)simulation.tick();for(const n of nodes)pinnedForSettle.has(n.id)&&(n.fx=null,n.fy=null)}this.simNodes=nodes,this.simNodeById=byId,this.simLinks=links;for(const n of nodes)n.x!=null&&n.y!=null&&this.lastPositionById.set(n.id,{x:n.x,y:n.y});this.announceHiddenNodeCount(nodes.length)}announceHiddenNodeCount(visibleNodeCount){const totalNodeCount=this.graphModel.nodes.length,hiddenNodeCount=totalNodeCount-visibleNodeCount;totalNodeCount>0&&(hiddenNodeCount>0||this.lastHiddenNodeCount>0)&&(this.graphLiveText=this.localize("graphNodesHidden",void 0,{hidden:getNumberFormat(this.effectiveLocale).format(hiddenNodeCount),total:getNumberFormat(this.effectiveLocale).format(totalNodeCount)})),this.lastHiddenNodeCount=hiddenNodeCount}rebuildLayeredLayout(visible){const boxes=visible.map(n=>{const r=this.nodeRadius(n);return{id:n.id,width:r*2,height:r*2}}),visibleIds=new Set(visible.map(n=>n.id)),edges=this.graphModel.links.filter(l=>visibleIds.has(l.source)&&visibleIds.has(l.target)).map(l=>({source:l.source,target:l.target})),{positions:raw}=layeredLayout({nodes:boxes,edges,options:{gapX:12,gapY:this.safeLinkDistance}}),bounds=extent(raw.values(),point=>point.x,point=>point.y),offsetX=raw.size?this.safeWidth/2-(bounds.minX+(bounds.maxX-bounds.minX)/2):this.safeWidth/2,offsetY=raw.size?this.safeHeight/2-(bounds.minY+(bounds.maxY-bounds.minY)/2):this.safeHeight/2,nodes=visible.map(n=>{const p=raw.get(n.id);return{...n,x:p.x+offsetX,y:p.y+offsetY}}),byId=new Map(nodes.map(n=>[n.id,n])),{resolved,dangling}=this.resolveLinksAgainst(byId);this.danglingLinks=dangling,this.simulation=void 0,this.simNodes=nodes,this.simNodeById=byId,this.simLinks=resolved;for(const n of nodes)n.x!=null&&n.y!=null&&this.lastPositionById.set(n.id,{x:n.x,y:n.y});this.announceHiddenNodeCount(nodes.length)}onNodeClick(node,e){const detail={nodeId:node.id,x:node.x??0,y:node.y??0};this.emit("lr-node-activate",{...detail}),this.emitSelectionIntent("node",node.id,!!(e?.ctrlKey||e?.metaKey))}getNodePosition(id){const node=this.simNodes.find(candidate=>candidate.id===id);if(!(!node||!Number.isFinite(node.x)||!Number.isFinite(node.y)))return{x:node.x,y:node.y}}onLinkClick(link,e){const source=typeof link.source=="object"?link.source.id:String(link.source),target=typeof link.target=="object"?link.target.id:String(link.target);this.emit("lr-edge-activate",{sourceNodeId:source,targetNodeId:target,...link.id?{edgeId:link.id}:{}}),this.emitSelectionIntent("link",this.linkKey(link),!!(e?.ctrlKey||e?.metaKey))}onNodeEnter(node,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.setAttribute("data-hovered",""),this.svgHoverNodeId=node.id,this.emit("lr-node-enter",{nodeId:node.id}))}onNodeLeave(node,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.removeAttribute("data-hovered"),this.svgHoverNodeId=void 0,this.emit("lr-node-leave",{nodeId:node.id}))}onNodeDblClick(node,e){e.stopPropagation(),this.emit("lr-node-expand",{nodeId:node.id})}onLinkEnter(link,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.setAttribute("data-hovered",""),this.emitEdgeHover("enter",this.linkHoverDetail(link)))}linkHoverDetail(link){const source=typeof link.source=="object"?link.source.id:String(link.source),target=typeof link.target=="object"?link.target.id:String(link.target);return{sourceNodeId:source,targetNodeId:target,...link.id?{edgeId:link.id}:{}}}onLinkLeave(link,e){this.isDragging||this.isPanning||this.isCameraTweening||(e.currentTarget.removeAttribute("data-hovered"),this.emitEdgeHover("leave",this.linkHoverDetail(link)))}emitEdgeHover(phase,detail){this.emit(phase==="enter"?"lr-edge-enter":"lr-edge-leave",{...detail})}nodeAccessibleText(node){let text=ownGraphText(node,"accessibleLabel")||ownGraphText(node,"label")||node.id;const type=this.resolveNodeType(node),typeLabel=type?ownGraphText(type,"label"):void 0;return typeLabel!==void 0&&(text=this.localize("graphTypedNode",void 0,{label:text,type:typeLabel})),node.expandable&&(text=this.localize("graphExpandableItem",void 0,{item:text})),text}boundedGraphText(value){if(typeof value!="string")return"";const normalized=value.replace(/\s+/g," ").trim();return normalized.length>512?`${normalized.slice(0,512)}…`:normalized}nodeTooltipText(node){return this.boundedGraphText(ownGraphText(node,"description")||ownGraphText(node,"label")||ownGraphText(node,"accessibleLabel")||node.id)}linkAccessibleText(link){const accessibleLabel=ownGraphText(link,"accessibleLabel");if(accessibleLabel)return accessibleLabel;const sourceValue=ownGraphValue(link,"source"),targetValue=ownGraphValue(link,"target"),source=sourceValue!==null&&typeof sourceValue=="object"?this.nodeAccessibleText(sourceValue):typeof sourceValue=="string"?sourceValue:"",target=targetValue!==null&&typeof targetValue=="object"?this.nodeAccessibleText(targetValue):typeof targetValue=="string"?targetValue:"";return ownGraphText(link,"label")||this.localize("graphLink",void 0,{source,target})}linkTooltipText(link){return this.boundedGraphText(ownGraphText(link,"description")||ownGraphText(link,"label")||ownGraphText(link,"accessibleLabel")||this.linkAccessibleText(link))}linkCoordinates(link){const source=link.source,target=link.target,x1=source.x??0,y1=source.y??0,targetX=target.x??0,targetY=target.y??0;if(!link.directed||link.dangling)return{x1,y1,x2:targetX,y2:targetY};const dx=targetX-x1,dy=targetY-y1,distance=Math.hypot(dx,dy);if(distance===0)return{x1,y1,x2:targetX,y2:targetY};const inset=Math.min(this.nodeRadius(target),distance);return{x1,y1,x2:targetX-dx/distance*inset,y2:targetY-dy/distance*inset}}edgeLabelPosition(link){const{x1,y1,x2,y2}=this.linkCoordinates(link),dx=x2-x1,dy=y2-y1,len=Math.hypot(dx,dy),mx=(x1+x2)/2,my=(y1+y2)/2;return len===0?{x:mx,y:my}:{x:mx+-dy/len*EDGE_LABEL_OFFSET_PX,y:my+dx/len*EDGE_LABEL_OFFSET_PX}}edgeLabelFontPx(){const raw=this.computedStyle().getPropertyValue("--lr-font-size-2xs").trim();return resolveCssTokenLength(raw,{host:this})??DEFAULT_EDGE_LABEL_FONT_PX}edgeLabelContext(){return this.edgeLabelMeasureCanvas?.ownerDocument!==this.ownerDocument&&(this.edgeLabelMeasureCanvas=this.ownerDocument.createElement("canvas"),this.edgeLabelMeasureCtx=this.edgeLabelMeasureCanvas.getContext("2d")),this.edgeLabelMeasureCtx??null}edgeLabelWidth(text){const cached=this.edgeLabelWidthCache.get(text);if(cached!=null)return cached;const ctx=this.edgeLabelContext();let width;if(ctx){const fontFamily=this.computedStyle().getPropertyValue("--lr-font").trim()||"sans-serif";ctx.font=`${this.edgeLabelFontPx()}px ${fontFamily}`,width=ctx.measureText(text).width}else width=text.length*this.edgeLabelFontPx()*.6;if(this.edgeLabelWidthCache.size>=EDGE_LABEL_WIDTH_CACHE_MAX){const oldest=this.edgeLabelWidthCache.keys().next().value;oldest!==void 0&&this.edgeLabelWidthCache.delete(oldest)}return this.edgeLabelWidthCache.set(text,width),width}updateEdgeLabelZoomGate(k){this.gEl&&(k<this.safeEdgeLabelMinZoom?this.gEl.setAttribute("data-edge-labels-hidden",""):this.gEl.removeAttribute("data-edge-labels-hidden"))}updateNodeLabelZoomGate(k){this.gEl&&(this.resolvedNodeLabelsMode==="zoom"&&k<NODE_LABEL_MIN_ZOOM?this.gEl.setAttribute("data-node-labels-hidden",""):this.gEl.removeAttribute("data-node-labels-hidden"))}linkIndexBase(){return this.simNodes.length}communityIndexBase(){return this.linkIndexBase()+this.navigableLinks().length}graphItemCount(){return this.communityIndexBase()+this.visibleCommunities().length}normalizedGraphItem(index=this.activeGraphItem){const count=this.graphItemCount();return count?Math.min(Math.max(index,0),count-1):-1}graphItemIdentity(index){if(index<0)return;if(index<this.linkIndexBase()){const node=this.simNodes[index];return node?{kind:"node",id:node.id}:void 0}if(index<this.communityIndexBase()){const link=this.navigableLinks()[index-this.linkIndexBase()];return link?{kind:"link",id:this.linkKey(link)}:void 0}const community=this.visibleCommunities()[index-this.communityIndexBase()]?.community;return community?{kind:"community",id:community.id}:void 0}graphItemIndex(identity){if(identity.kind==="node")return this.simNodes.findIndex(node=>node.id===identity.id);if(identity.kind==="link"){const index2=this.navigableLinks().findIndex(link=>this.linkKey(link)===identity.id);return index2<0?-1:this.linkIndexBase()+index2}const index=this.visibleCommunities().findIndex(entry=>entry.community.id===identity.id);return index<0?-1:this.communityIndexBase()+index}communityText(community){return ownGraphText(community,"label")??community.id}graphItemText(index){if(index<this.linkIndexBase()){const node=this.simNodes[index];return node?this.localize("graphNode",void 0,{label:this.nodeTooltipText(node)}):""}if(index<this.communityIndexBase()){const link=this.navigableLinks()[index-this.linkIndexBase()];return link?this.linkTooltipText(link):""}const entry=this.visibleCommunities()[index-this.communityIndexBase()];return entry?this.localize("graphCommunity",void 0,{label:this.communityText(entry.community),count:getNumberFormat(this.effectiveLocale).format(entry.members.length)}):""}graphItemAnnouncement(index){return this.localize("graphItemAnnouncement",void 0,{item:this.graphItemText(index),index:getNumberFormat(this.effectiveLocale).format(index+1),total:getNumberFormat(this.effectiveLocale).format(this.graphItemCount())})}onGraphItemFocus(index){this.normalizedGraphItem(index)<0||(this.activeGraphItem=index,this.graphLiveText=this.graphItemAnnouncement(index))}focusGraphItem(index){const normalized=this.normalizedGraphItem(index);normalized<0||(this.activeGraphItem=normalized,this.graphLiveText=this.graphItemAnnouncement(normalized),this.updateComplete.then(()=>this.focusGraphItemElement(normalized)))}focusGraphItemElement(index){if(this.renderer==="canvas"){this.renderRoot.querySelector('[part="cursor-item"]')?.focus(),this.scheduleCanvasDraw();return}[...this.renderRoot.querySelectorAll('[part="node"]'),...this.renderRoot.querySelectorAll('[part="link"][tabindex]'),...this.renderRoot.querySelectorAll('[part="hull"]')][index]?.focus()}onGraphKeyDown(e,index,activate){if(e.key==="Enter"||e.key===" "){if(e.preventDefault(),e.repeat)return;if(this.onGraphItemFocus(index),activate(e),index<this.simNodes.length){const now=this.ownerWindow?.performance.now()??0;if(this.lastKeyActivateIndex===index&&now-this.lastKeyActivateTime<=EXPAND_KEY_INTERVAL_MS){const node=this.simNodes[index];node&&this.emit("lr-node-expand",{nodeId:node.id}),this.lastKeyActivateIndex=null}else this.lastKeyActivateIndex=index,this.lastKeyActivateTime=now}return}const count=this.graphItemCount();if(!count)return;const rtl=isRtl(this),forwardKey=rtl?"ArrowLeft":"ArrowRight",backwardKey=rtl?"ArrowRight":"ArrowLeft";let next=index;if(e.key===forwardKey||e.key==="ArrowDown")next=Math.min(count-1,index+1);else if(e.key===backwardKey||e.key==="ArrowUp")next=Math.max(0,index-1);else if(e.key==="Home")next=0;else if(e.key==="End")next=count-1;else return;e.preventDefault(),this.focusGraphItem(next)}render(){const nodeLimit=publicCollectionTruncation(this,"nodes"),edgeLimit=publicCollectionTruncation(this,"edges"),limitNotices=html`${nodeLimit?html`<p part="limit" role="note">${this.localize("graphNodeLimit",void 0,{shown:getNumberFormat(this.effectiveLocale).format(nodeLimit.retained),total:getNumberFormat(this.effectiveLocale).format(nodeLimit.source)})}</p>`:nothing}${edgeLimit?html`<p part="limit" role="note">${this.localize("graphEdgeLimit",void 0,{shown:getNumberFormat(this.effectiveLocale).format(edgeLimit.retained),total:getNumberFormat(this.effectiveLocale).format(edgeLimit.source)})}</p>`:nothing}`;if(this.loading)return html`
2
2
  <div part="base">
3
3
  <lr-skeleton
4
4
  shape="rect"