@gen-epix/ui-phylogenetic-tree 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/identity.js +69 -50
- package/dist/_chunks/identity.js.map +1 -1
- package/dist/components/PhylogeneticTree/index.js +4 -3
- package/dist/components/PhylogeneticTree/index.js.map +1 -1
- package/dist/utils/NewickUtil/index.js.map +1 -1
- package/dist/utils/TreeUtil/index.js +19 -18
- package/dist/utils/TreeUtil/index.js.map +1 -1
- package/package.json +28 -26
|
@@ -7,7 +7,7 @@ import { useScrollbarSize as u } from "@gen-epix/ui-core/hooks/useScrollbarSize"
|
|
|
7
7
|
import { useDimensions as d } from "@gen-epix/ui-core/hooks/useDimensions";
|
|
8
8
|
import { useSubscribable as f } from "@gen-epix/ui-core/hooks/useSubscribable";
|
|
9
9
|
import { jsx as p } from "react/jsx-runtime";
|
|
10
|
-
//#region ../../node_modules/.pnpm/use-debounce@10.1.1_react@19.2.
|
|
10
|
+
//#region ../../node_modules/.pnpm/use-debounce@10.1.1_react@19.2.8/node_modules/use-debounce/dist/index.module.js
|
|
11
11
|
function m(e, t, n, i) {
|
|
12
12
|
var s = this, c = o(null), l = o(0), u = o(0), d = o(null), f = o([]), p = o(), m = o(), h = o(e), g = o(!0), _ = o(), v = o();
|
|
13
13
|
h.current = e;
|
|
@@ -209,14 +209,15 @@ var h = ({ ancestorDotRadius: h, ariaLabel: g, backgroundColor: _, dimFn: v, fon
|
|
|
209
209
|
Z(0);
|
|
210
210
|
return;
|
|
211
211
|
}
|
|
212
|
-
|
|
212
|
+
let t = e.getScrollPositionFromTreeVisibility({
|
|
213
213
|
itemHeight: C,
|
|
214
214
|
treeCanvasHeight: K,
|
|
215
215
|
treeHeight: Y,
|
|
216
216
|
treeSize: M.size,
|
|
217
217
|
verticalScrollPosition: W.data.vertical,
|
|
218
218
|
zoomLevel: U.data
|
|
219
|
-
})
|
|
219
|
+
});
|
|
220
|
+
Z(t);
|
|
220
221
|
}, [
|
|
221
222
|
C,
|
|
222
223
|
Z,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["r","n","t"],"sources":["../../../../../node_modules/.pnpm/use-debounce@10.1.1_react@19.2.7/node_modules/use-debounce/dist/index.module.js","../../../src/components/PhylogeneticTree/PhylogeneticTree.tsx"],"sourcesContent":["import{useRef as r,useMemo as n,useEffect as t,useState as e,useCallback as u}from\"react\";function c(e,u,c,i){var l=this,a=r(null),o=r(0),f=r(0),v=r(null),d=r([]),s=r(),m=r(),h=r(e),g=r(!0),x=r(),E=r();h.current=e;var b=\"undefined\"!=typeof window,p=!u&&0!==u&&b;if(\"function\"!=typeof e)throw new TypeError(\"Expected a function\");u=+u||0;var y=!!(c=c||{}).leading,w=!(\"trailing\"in c)||!!c.trailing,T=!!c.flushOnExit&&w,O=\"maxWait\"in c,F=\"debounceOnServer\"in c&&!!c.debounceOnServer,L=O?Math.max(+c.maxWait||0,u):null,A=n(function(){var r=function(r){var n=d.current,t=s.current;return d.current=s.current=null,o.current=r,f.current=f.current||r,m.current=h.current.apply(t,n)},n=function(r,n){p&&cancelAnimationFrame(v.current),v.current=p?requestAnimationFrame(r):setTimeout(r,n)},t=function(r){if(!g.current)return!1;var n=r-a.current;return!a.current||n>=u||n<0||O&&r-o.current>=L},e=function(n){return v.current=null,w&&d.current?r(n):(d.current=s.current=null,m.current)},c=function r(){var c=Date.now();if(y&&f.current===o.current&&A(),t(c))return e(c);if(g.current){var i=u-(c-a.current),l=O?Math.min(i,L-(c-o.current)):i;n(r,l)}},A=function(){i&&i({})},D=function(){if(b||F){var e,i=Date.now(),f=t(i);if(d.current=[].slice.call(arguments),s.current=l,a.current=i,T&&!x.current&&(x.current=function(){var r;\"hidden\"===(null==(r=globalThis.document)?void 0:r.visibilityState)&&E.current.flush()},null==(e=globalThis.document)||null==e.addEventListener||e.addEventListener(\"visibilitychange\",x.current)),f){if(!v.current&&g.current)return o.current=a.current,n(c,u),y?r(a.current):m.current;if(O)return n(c,u),r(a.current)}return v.current||n(c,u),m.current}};return D.cancel=function(){var r=v.current;r&&(p?cancelAnimationFrame(v.current):clearTimeout(v.current)),o.current=0,d.current=a.current=s.current=v.current=null,r&&i&&i({})},D.isPending=function(){return!!v.current},D.flush=function(){return v.current?e(Date.now()):m.current},D},[y,O,u,L,w,T,p,b,F,i]);return E.current=A,t(function(){return g.current=!0,function(){var r;T&&E.current.flush(),x.current&&(null==(r=globalThis.document)||null==r.removeEventListener||r.removeEventListener(\"visibilitychange\",x.current),x.current=null),g.current=!1}},[T]),A}function i(r,n){return r===n}function l(n,t,l){var a=l&&l.equalityFn||i,o=r(n),f=e({})[1],v=c(u(function(r){o.current=r,f({})},[f]),t,l,f),d=r(n);return a(d.current,n)||(v(n),d.current=n),[o.current,v]}function a(r,n,t){var e=void 0===t?{}:t,u=e.leading,i=e.trailing,l=e.flushOnExit;return c(r,n,{maxWait:n,leading:void 0===u||u,trailing:void 0===i||i,flushOnExit:void 0!==l&&l})}export{l as useDebounce,c as useDebouncedCallback,a as useThrottledCallback};\n//# sourceMappingURL=index.module.js.map\n","import { Box } from '@mui/material';\nimport type { Ref } from 'react';\nimport {\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useDebouncedCallback } from 'use-debounce';\nimport { DevicePixelRatioService } from '@gen-epix/ui-core/classes/services/DevicePixelRatioService';\nimport { Subject } from '@gen-epix/ui-core/classes/Subject';\nimport { useScrollbarSize } from '@gen-epix/ui-core/hooks/useScrollbarSize';\nimport { useDimensions } from '@gen-epix/ui-core/hooks/useDimensions';\nimport { useSubscribable } from '@gen-epix/ui-core/hooks/useSubscribable';\n\nimport type {\n TreeAssembly,\n TreeNode,\n TreePathProperties,\n} from '../../models/tree';\nimport { TreeUtil } from '../../utils/TreeUtil';\n\nexport type PhylogeneticTreeHighlightedNodeNamesSubjectValue = {\n highlightedNodeNames: string[];\n};\n\nexport type PhylogeneticTreePathClickEvent = {\n mouseEvent: MouseEvent;\n pathProperties: TreePathProperties;\n};\n\nexport type PhylogeneticTreeProps = {\n readonly ancestorDotRadius: number;\n readonly ariaLabel: string;\n readonly backgroundColor: string;\n readonly dimFn: (color: string) => string;\n readonly fontFamily: string;\n readonly headerHeight: number;\n readonly highlightedNodeNamesSubject?: Subject<PhylogeneticTreeHighlightedNodeNamesSubjectValue>;\n readonly initialViewState?: Partial<PhylogeneticTreeViewState>;\n readonly itemHeight: number;\n readonly leafDotRadius: number;\n readonly linkedScrollDebounceDelayMs: number;\n readonly maxScaleWidthPx: number;\n readonly maxZoomLevel: number;\n readonly maxZoomSpeed: number;\n readonly minimumDistancePercentageToShowLabel: number;\n readonly minScaleWidthPx: number;\n readonly minZoomLevel: number;\n readonly minZoomSpeed: number;\n readonly nodeNameColors?: { [key: string]: string } | null;\n readonly onCanvasChange?: (canvas?: HTMLCanvasElement) => void;\n readonly onLinkStateChange?: (isLinked: boolean) => void;\n readonly onPathClick?: (event: PhylogeneticTreePathClickEvent) => void;\n readonly onViewStateChange?: (viewState: PhylogeneticTreeViewState) => void;\n readonly panningThreshold: number;\n readonly ref?: Ref<PhylogeneticTreeRef>;\n readonly regularFillColorSupportLine: string;\n readonly scaleColor: string;\n readonly scaleIncrements: number[];\n readonly scrollSubject?: Subject<PhylogeneticTreeScrollSubjectValue>;\n readonly shouldShowDistances: boolean;\n readonly shouldShowSupportLinesWhenUnlinked: boolean;\n readonly sortedLeafNames: string[];\n readonly supportLineColorLinked: string;\n readonly supportLineColorUnlinked: string;\n readonly tree?: TreeNode;\n readonly treeColor: string;\n readonly treeFont: string;\n readonly treePadding: number;\n readonly visibleRangeSubject?: Subject<PhylogeneticTreeVisibleRangeSubjectValue>;\n};\n\nexport interface PhylogeneticTreeRef {\n link: (verticalPosition?: number) => void;\n syncScrollToVisibleTree: () => void;\n unlink: (viewState: { positionX: number; positionY: number; zoomLevel: number }) => void;\n}\n\nexport type PhylogeneticTreeScrollSubjectValue = {\n origin: HTMLElement;\n position: number;\n};\n\nexport type PhylogeneticTreeViewState = {\n horizontalScrollPosition: number;\n verticalScrollPosition: number;\n zoomLevel: number;\n};\n\nexport type PhylogeneticTreeVisibleRangeSubjectValue = {\n endIndex: number;\n startIndex: number;\n};\n\nexport const PhylogeneticTree = ({\n ancestorDotRadius,\n ariaLabel,\n backgroundColor,\n dimFn,\n fontFamily,\n headerHeight,\n highlightedNodeNamesSubject,\n initialViewState,\n itemHeight,\n leafDotRadius,\n linkedScrollDebounceDelayMs,\n maxScaleWidthPx,\n maxZoomLevel,\n maxZoomSpeed,\n minimumDistancePercentageToShowLabel,\n minScaleWidthPx,\n minZoomLevel,\n minZoomSpeed,\n nodeNameColors,\n onCanvasChange,\n onLinkStateChange,\n onPathClick,\n onViewStateChange,\n panningThreshold,\n ref,\n regularFillColorSupportLine,\n scaleColor,\n scaleIncrements,\n scrollSubject,\n shouldShowDistances,\n shouldShowSupportLinesWhenUnlinked,\n sortedLeafNames,\n supportLineColorLinked,\n supportLineColorUnlinked,\n tree,\n treeColor,\n treeFont,\n treePadding,\n visibleRangeSubject,\n}: PhylogeneticTreeProps) => {\n const scrollbarSize = useScrollbarSize();\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const { dimensions: { height, width } } = useDimensions(containerRef);\n const [treeCanvas, setTreeCanvas] = useState<HTMLCanvasElement>();\n const [treeAssembly, setTreeAssembly] = useState<TreeAssembly>(null);\n const [devicePixelRatio, setDevicePixelRatio] = useState<number>(DevicePixelRatioService.getInstance().data);\n const [isLinked, setIsLinked] = useState(true);\n const canvasScrollSubject = useMemo(() => new Subject<{ x: number; y: number }>({ x: 0, y: 0 }), []);\n const zoomLevelSubject = useMemo(() => new Subject<number>(!isNaN(initialViewState?.zoomLevel) ? initialViewState.zoomLevel : 1), [initialViewState]);\n const scrollPositionSubject = useMemo(() => new Subject<{ horizontal: number; vertical: number }>({\n horizontal: !isNaN(initialViewState?.horizontalScrollPosition) ? initialViewState.horizontalScrollPosition : 0,\n vertical: !isNaN(initialViewState?.verticalScrollPosition) ? initialViewState.verticalScrollPosition : 0,\n }), [initialViewState]);\n\n const treeCanvasWidth = width;\n const treeCanvasHeight = Math.max(0, height - headerHeight);\n const combinedCanvasHeight = Math.max(0, height);\n const treeWidthMinusPadding = treeCanvasWidth - (2 * treePadding);\n const pixelToGeneticDistanceRatio = tree?.maxBranchLength ? treeWidthMinusPadding / tree.maxBranchLength.toNumber() : null;\n const treeHeight = tree?.size ? (tree.size * itemHeight) + scrollbarSize : itemHeight;\n\n const handleTreeCanvasRef = useCallback((canvas: HTMLCanvasElement | null) => {\n setTreeCanvas(canvas ?? undefined);\n }, []);\n\n useEffect(() => {\n onLinkStateChange?.(isLinked);\n }, [isLinked, onLinkStateChange]);\n\n useEffect(() => {\n if (!onCanvasChange) {\n return;\n }\n onCanvasChange(treeCanvas);\n\n return () => {\n if (treeCanvas) {\n onCanvasChange(undefined);\n }\n };\n }, [treeCanvas, onCanvasChange]);\n\n useEffect(() => {\n if (!onViewStateChange) {\n return;\n }\n\n const emitViewState = () => {\n onViewStateChange({\n horizontalScrollPosition: scrollPositionSubject.data.horizontal,\n verticalScrollPosition: scrollPositionSubject.data.vertical,\n zoomLevel: zoomLevelSubject.data,\n });\n };\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe(() => {\n emitViewState();\n });\n const unsubscribeFromScrollPositionSubject = scrollPositionSubject.subscribe(() => {\n emitViewState();\n });\n\n emitViewState();\n\n return () => {\n unsubscribeFromZoomLevelSubject();\n unsubscribeFromScrollPositionSubject();\n };\n }, [onViewStateChange, scrollPositionSubject, zoomLevelSubject]);\n\n useEffect(() => {\n let zoomLevel = zoomLevelSubject.data;\n\n const updateIsLinked = () => {\n if (isLinked && zoomLevel !== 1) {\n setIsLinked(false);\n }\n };\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n updateIsLinked();\n });\n updateIsLinked();\n\n return () => {\n unsubscribeFromZoomLevelSubject();\n };\n }, [isLinked, zoomLevelSubject]);\n\n useEffect(() => {\n const unsubscribe = canvasScrollSubject.subscribe((data) => {\n scrollPositionSubject.next({\n horizontal: !isNaN(data.x) ? data.x : scrollPositionSubject.data.horizontal,\n vertical: !isNaN(data.y) ? data.y : scrollPositionSubject.data.vertical,\n });\n });\n\n return () => {\n unsubscribe();\n };\n }, [canvasScrollSubject, scrollPositionSubject]);\n\n const emitScrollPosition = useCallback((position: number) => {\n if (!scrollSubject || !scrollContainerRef.current) {\n return;\n }\n\n scrollSubject.next({\n origin: scrollContainerRef.current,\n position,\n });\n }, [scrollSubject]);\n\n const updateScrollSubjectDebounced = useDebouncedCallback((position: number) => {\n if (!scrollSubject || !scrollContainerRef.current) {\n return;\n }\n\n scrollSubject.next({\n origin: scrollContainerRef.current,\n position: position / devicePixelRatio,\n });\n }, linkedScrollDebounceDelayMs, { leading: true, trailing: true });\n\n const updateScrollPosition = useCallback((params: { internalZoomLevel: number; positionX: number; positionY: number }) => {\n const { internalZoomLevel, positionX, positionY } = params;\n if (internalZoomLevel === 0) {\n throw new Error('internalZoomLevel cannot be 0');\n }\n\n const { newPositionX, newPositionY } = TreeUtil.getSanitizedScrollPosition({\n devicePixelRatio,\n headerHeight,\n internalZoomLevel,\n isLinked,\n positionX,\n positionY,\n treeCanvasHeight,\n treeCanvasWidth,\n treeHeight,\n treePadding,\n });\n\n const positionYChanged = newPositionY !== canvasScrollSubject.data.y;\n\n canvasScrollSubject.next({\n x: newPositionX,\n y: newPositionY,\n });\n\n if (isLinked && internalZoomLevel === 1 && positionYChanged) {\n updateScrollSubjectDebounced(newPositionY);\n }\n }, [canvasScrollSubject, devicePixelRatio, headerHeight, isLinked, treeCanvasHeight, treeCanvasWidth, treeHeight, treePadding, updateScrollSubjectDebounced]);\n\n useEffect(() => {\n updateScrollPosition({\n internalZoomLevel: zoomLevelSubject.data,\n positionX: canvasScrollSubject.data.x,\n positionY: canvasScrollSubject.data.y,\n });\n }, [canvasScrollSubject, updateScrollPosition, zoomLevelSubject]);\n\n const link = useCallback((verticalPosition?: number) => {\n const nextVerticalPosition = verticalPosition ?? scrollSubject?.data?.position ?? 0;\n\n zoomLevelSubject.next(1);\n setIsLinked(true);\n updateScrollPosition({\n internalZoomLevel: 1,\n positionX: 0,\n positionY: nextVerticalPosition,\n });\n\n if (verticalPosition !== undefined) {\n emitScrollPosition(nextVerticalPosition);\n }\n }, [emitScrollPosition, scrollSubject, updateScrollPosition, zoomLevelSubject]);\n\n const unlink = useCallback((viewState: { positionX: number; positionY: number; zoomLevel: number }) => {\n setIsLinked(false);\n zoomLevelSubject.next(viewState.zoomLevel);\n updateScrollPosition({\n internalZoomLevel: viewState.zoomLevel,\n positionX: viewState.positionX,\n positionY: viewState.positionY,\n });\n }, [updateScrollPosition, zoomLevelSubject]);\n\n const syncScrollToVisibleTree = useCallback(() => {\n if (!tree?.size) {\n link(0);\n return;\n }\n\n const newScrollPosition = TreeUtil.getScrollPositionFromTreeVisibility({\n itemHeight,\n treeCanvasHeight,\n treeHeight,\n treeSize: tree.size,\n verticalScrollPosition: scrollPositionSubject.data.vertical,\n zoomLevel: zoomLevelSubject.data,\n });\n\n link(newScrollPosition);\n }, [itemHeight, link, scrollPositionSubject, tree, treeCanvasHeight, treeHeight, zoomLevelSubject]);\n\n useImperativeHandle(ref, () => ({\n link,\n syncScrollToVisibleTree,\n unlink,\n }), [link, syncScrollToVisibleTree, unlink]);\n\n const devicePixelRatioServiceCallback = useCallback((newDevicePixelRatio: number, previousDevicePixelRatio: number) => {\n canvasScrollSubject.next({\n x: (canvasScrollSubject.data.x / previousDevicePixelRatio) * newDevicePixelRatio,\n y: (canvasScrollSubject.data.y / previousDevicePixelRatio) * newDevicePixelRatio,\n });\n setDevicePixelRatio(newDevicePixelRatio);\n }, [canvasScrollSubject]);\n\n useSubscribable(DevicePixelRatioService.getInstance(), {\n callback: devicePixelRatioServiceCallback,\n });\n\n const getTickerMarkScale = useCallback((zoomLevel: number) => {\n return TreeUtil.getTickMarkScale({\n geneticTreeWidth: tree?.maxBranchLength,\n maxScaleWidthPx,\n minGeneticScaleUnit: TreeUtil.getMinGeneticScaleUnit(tree),\n minScaleWidthPx,\n scaleIncrements,\n treeWidthMinusPadding,\n zoomLevel,\n });\n }, [maxScaleWidthPx, minScaleWidthPx, scaleIncrements, tree, treeWidthMinusPadding]);\n\n const getPathPropertiesFromCanvas = useCallback((canvas: HTMLCanvasElement, event: MouseEvent): TreePathProperties => {\n return TreeUtil.getPathPropertiesFromCanvas({\n canvas,\n devicePixelRatio,\n event,\n treeAssembly,\n });\n }, [devicePixelRatio, treeAssembly]);\n\n useEffect(() => {\n if (!scrollSubject) {\n return;\n }\n\n let scrollData = scrollSubject.data;\n let zoomLevel = zoomLevelSubject.data;\n\n const update = () => {\n if (!scrollData || scrollData.origin === scrollContainerRef.current) {\n return;\n }\n if (isLinked && zoomLevel === 1) {\n canvasScrollSubject.next({\n x: canvasScrollSubject.data.x * devicePixelRatio,\n y: scrollData.position * devicePixelRatio,\n });\n }\n };\n\n const unsubscribeFromScrollSubject = scrollSubject.subscribe((data) => {\n scrollData = data;\n update();\n });\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n update();\n });\n\n return () => {\n unsubscribeFromScrollSubject();\n unsubscribeFromZoomLevelSubject();\n };\n }, [canvasScrollSubject, devicePixelRatio, scrollSubject, isLinked, zoomLevelSubject]);\n\n useEffect(() => {\n if (!tree || !pixelToGeneticDistanceRatio) {\n setTreeAssembly(null);\n return;\n }\n\n setTreeAssembly(TreeUtil.assembleTree({\n ancestorDotRadius,\n itemHeight,\n leafDotRadius,\n minimumDistancePercentageToShowLabel,\n pixelToGeneticDistanceRatio,\n rootNode: tree,\n sortedLeafNames,\n treeCanvasWidth,\n treePadding,\n }));\n }, [ancestorDotRadius, itemHeight, leafDotRadius, sortedLeafNames, minimumDistancePercentageToShowLabel, pixelToGeneticDistanceRatio, tree, treeCanvasWidth, treePadding]);\n\n useEffect(() => {\n if (!treeCanvas || !treeAssembly || !tree) {\n return;\n }\n\n let animationFrameId: number;\n let zoomLevel: number = zoomLevelSubject.data;\n let tickerMarkScale = getTickerMarkScale(zoomLevel);\n let highlightedNodeNames: string[] = highlightedNodeNamesSubject?.data?.highlightedNodeNames ?? [];\n let scrollPosition = scrollSubject?.data?.position ?? 0;\n let horizontalScrollPosition = scrollPositionSubject.data.horizontal;\n let verticalScrollPosition = scrollPositionSubject.data.vertical;\n let range = visibleRangeSubject?.data;\n\n const render = () => {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = requestAnimationFrame(() => {\n TreeUtil.drawTreeCanvas({\n backgroundColor,\n canvas: treeCanvas,\n devicePixelRatio,\n dimFn,\n fontFamily,\n geneticTreeWidth: tree.maxBranchLength,\n headerHeight,\n highlightedNodeNames,\n horizontalScrollPosition,\n isLinked,\n itemHeight,\n nodeNameColors,\n pixelToGeneticDistanceRatio,\n range,\n regularFillColorSupportLine,\n scaleColor,\n scrollPosition,\n shouldShowDistances,\n shouldShowSupportLinesWhenUnlinked,\n supportLineColorLinked,\n supportLineColorUnlinked,\n tickerMarkScale,\n treeAssembly,\n treeCanvasHeight,\n treeCanvasWidth,\n treeColor,\n treeFont,\n treePadding,\n verticalScrollPosition,\n zoomLevel,\n });\n });\n };\n\n const unsubscribeFromHighlighting = highlightedNodeNamesSubject ? highlightedNodeNamesSubject.subscribe((data) => {\n highlightedNodeNames = data.highlightedNodeNames;\n render();\n }) : (): null => null;\n\n const unsubscribeFromScrollPositionSubject = scrollPositionSubject.subscribe((data) => {\n horizontalScrollPosition = data.horizontal;\n verticalScrollPosition = data.vertical;\n render();\n });\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n tickerMarkScale = getTickerMarkScale(data);\n render();\n });\n\n const unsubscribeFromScrollSubject = scrollSubject?.subscribe((data) => {\n if (data.origin === scrollContainerRef.current) {\n return;\n }\n scrollPosition = data.position;\n render();\n });\n\n const unsubscribeFromVisibleRangeSubject = visibleRangeSubject?.subscribe((data) => {\n range = data;\n render();\n });\n\n render();\n\n return () => {\n unsubscribeFromHighlighting();\n unsubscribeFromScrollSubject?.();\n unsubscribeFromScrollPositionSubject();\n unsubscribeFromZoomLevelSubject();\n unsubscribeFromVisibleRangeSubject?.();\n cancelAnimationFrame(animationFrameId);\n };\n }, [\n backgroundColor,\n devicePixelRatio,\n dimFn,\n highlightedNodeNamesSubject,\n scrollSubject,\n visibleRangeSubject,\n fontFamily,\n getTickerMarkScale,\n headerHeight,\n isLinked,\n itemHeight,\n pixelToGeneticDistanceRatio,\n regularFillColorSupportLine,\n scaleColor,\n scrollPositionSubject,\n shouldShowDistances,\n shouldShowSupportLinesWhenUnlinked,\n nodeNameColors,\n supportLineColorLinked,\n supportLineColorUnlinked,\n tree,\n treeAssembly,\n treeCanvas,\n treeCanvasHeight,\n treeCanvasWidth,\n treeColor,\n treeFont,\n treePadding,\n zoomLevelSubject,\n ]);\n\n useEffect(() => {\n if (!treeCanvas) {\n return;\n }\n\n let zoomLevel = zoomLevelSubject.data;\n\n let pos = {\n currentX: 0,\n currentY: 0,\n x: 0,\n y: 0,\n };\n let followMouse = false;\n\n const clearHighlighting = () => {\n if (highlightedNodeNamesSubject?.data?.highlightedNodeNames?.length) {\n highlightedNodeNamesSubject.next({\n highlightedNodeNames: [],\n });\n }\n };\n\n const isEventInHeader = (event: MouseEvent | WheelEvent) => event.offsetY < headerHeight;\n\n const onMouseDown = (event: MouseEvent) => {\n if (isEventInHeader(event)) {\n treeCanvas.style.cursor = 'default';\n return;\n }\n\n pos = {\n currentX: canvasScrollSubject.data.x,\n currentY: canvasScrollSubject.data.y,\n x: event.clientX,\n y: event.clientY,\n };\n followMouse = true;\n };\n\n const onMouseMove = (event: MouseEvent) => {\n if (isEventInHeader(event)) {\n followMouse = false;\n treeCanvas.style.cursor = 'default';\n clearHighlighting();\n return;\n }\n\n if (followMouse) {\n treeCanvas.style.cursor = 'move';\n\n const deltaX = event.clientX - pos.x;\n const deltaY = event.clientY - pos.y;\n const scrollPositionX = pos.currentX - deltaX;\n const scrollPositionY = pos.currentY - deltaY;\n\n let sanitizedScrollPositionX = scrollPositionX;\n if (zoomLevel === 1 && Math.abs(deltaX) < panningThreshold && pos.currentX === 0) {\n sanitizedScrollPositionX = 0;\n }\n updateScrollPosition({ internalZoomLevel: zoomLevel, positionX: sanitizedScrollPositionX, positionY: scrollPositionY });\n return;\n }\n\n const pathProperties = getPathPropertiesFromCanvas(treeCanvas, event);\n if (pathProperties) {\n treeCanvas.style.cursor = 'pointer';\n highlightedNodeNamesSubject?.next({\n highlightedNodeNames: pathProperties.subTreeLeaveNames,\n });\n } else {\n treeCanvas.style.cursor = 'default';\n clearHighlighting();\n }\n };\n\n const onMouseUp = (event: MouseEvent) => {\n followMouse = false;\n\n if (isEventInHeader(event)) {\n return;\n }\n\n const pathProperties = getPathPropertiesFromCanvas(treeCanvas, event);\n if (pathProperties) {\n onPathClick?.({\n mouseEvent: event,\n pathProperties,\n });\n }\n };\n\n const onMouseWheel = (event: WheelEvent) => {\n event.preventDefault();\n\n if (isEventInHeader(event)) {\n return;\n }\n\n if (event.shiftKey) {\n updateScrollPosition({ internalZoomLevel: zoomLevel, positionX: canvasScrollSubject.data.x + (event.deltaX || event.deltaY), positionY: canvasScrollSubject.data.y });\n return;\n }\n if (event.metaKey || event.ctrlKey) {\n updateScrollPosition({ internalZoomLevel: zoomLevel, positionX: canvasScrollSubject.data.x, positionY: canvasScrollSubject.data.y + (event.deltaX || event.deltaY) });\n return;\n }\n\n const zoomSpeed = Math.min(maxZoomSpeed, Math.max(minZoomSpeed, treeHeight / treeCanvasHeight * 0.2));\n const newZoomLevel = Math.min(maxZoomLevel, Math.max(minZoomLevel, zoomLevel + (event.deltaY > 0 ? zoomSpeed : -zoomSpeed)));\n const treeBodyOffsetY = event.offsetY - headerHeight;\n\n const newScrollPositionY = TreeUtil.getNewScrollPositionForZoomLevel({\n currentZoomLevel: zoomLevel,\n dimensionSize: treeHeight,\n eventOffset: treeBodyOffsetY,\n newZoomLevel,\n scrollPosition: canvasScrollSubject.data.y,\n });\n const newScrollPositionX = TreeUtil.getNewScrollPositionForZoomLevel({\n currentZoomLevel: zoomLevel,\n dimensionSize: treeCanvasWidth,\n eventOffset: event.offsetX,\n newZoomLevel,\n scrollPosition: canvasScrollSubject.data.x,\n });\n zoomLevelSubject.next(newZoomLevel);\n if (newZoomLevel !== 1) {\n updateScrollPosition({ internalZoomLevel: newZoomLevel, positionX: newScrollPositionX, positionY: newScrollPositionY });\n } else {\n updateScrollPosition({ internalZoomLevel: 1, positionX: newScrollPositionX, positionY: scrollSubject?.data?.position ?? 0 });\n }\n };\n\n const onMouseOut = () => {\n followMouse = false;\n clearHighlighting();\n };\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n });\n\n treeCanvas.addEventListener('mousemove', onMouseMove);\n treeCanvas.addEventListener('mousedown', onMouseDown);\n treeCanvas.addEventListener('mouseup', onMouseUp);\n treeCanvas.addEventListener('mouseout', onMouseOut);\n treeCanvas.addEventListener('wheel', onMouseWheel, { passive: false });\n\n return () => {\n treeCanvas.removeEventListener('mousemove', onMouseMove);\n treeCanvas.removeEventListener('mousedown', onMouseDown);\n treeCanvas.removeEventListener('mouseup', onMouseUp);\n treeCanvas.removeEventListener('mouseout', onMouseOut);\n treeCanvas.removeEventListener('wheel', onMouseWheel);\n unsubscribeFromZoomLevelSubject();\n };\n }, [\n canvasScrollSubject,\n highlightedNodeNamesSubject,\n scrollSubject,\n getPathPropertiesFromCanvas,\n headerHeight,\n maxZoomLevel,\n maxZoomSpeed,\n minZoomLevel,\n minZoomSpeed,\n onPathClick,\n panningThreshold,\n treeCanvas,\n treeCanvasHeight,\n treeCanvasWidth,\n treeHeight,\n updateScrollPosition,\n zoomLevelSubject,\n ]);\n\n const shouldRenderCanvas = !!tree && treeCanvasWidth > 0 && tree.size > 0;\n\n return (\n <Box\n ref={containerRef}\n sx={{\n height: '100%',\n overflow: 'clip',\n position: 'relative',\n width: '100%',\n }}\n >\n <Box\n ref={scrollContainerRef}\n sx={{\n height: combinedCanvasHeight,\n overflowY: 'hidden',\n position: 'absolute',\n width: treeCanvasWidth,\n }}\n >\n {shouldRenderCanvas && (\n <Box\n aria-label={ariaLabel}\n component={'canvas'}\n ref={handleTreeCanvasRef}\n role={'figure'}\n sx={{\n height: combinedCanvasHeight,\n width: treeCanvasWidth,\n }}\n />\n )}\n </Box>\n </Box>\n );\n};\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["r","n","t"],"sources":["../../../../../node_modules/.pnpm/use-debounce@10.1.1_react@19.2.8/node_modules/use-debounce/dist/index.module.js","../../../src/components/PhylogeneticTree/PhylogeneticTree.tsx"],"sourcesContent":["import{useRef as r,useMemo as n,useEffect as t,useState as e,useCallback as u}from\"react\";function c(e,u,c,i){var l=this,a=r(null),o=r(0),f=r(0),v=r(null),d=r([]),s=r(),m=r(),h=r(e),g=r(!0),x=r(),E=r();h.current=e;var b=\"undefined\"!=typeof window,p=!u&&0!==u&&b;if(\"function\"!=typeof e)throw new TypeError(\"Expected a function\");u=+u||0;var y=!!(c=c||{}).leading,w=!(\"trailing\"in c)||!!c.trailing,T=!!c.flushOnExit&&w,O=\"maxWait\"in c,F=\"debounceOnServer\"in c&&!!c.debounceOnServer,L=O?Math.max(+c.maxWait||0,u):null,A=n(function(){var r=function(r){var n=d.current,t=s.current;return d.current=s.current=null,o.current=r,f.current=f.current||r,m.current=h.current.apply(t,n)},n=function(r,n){p&&cancelAnimationFrame(v.current),v.current=p?requestAnimationFrame(r):setTimeout(r,n)},t=function(r){if(!g.current)return!1;var n=r-a.current;return!a.current||n>=u||n<0||O&&r-o.current>=L},e=function(n){return v.current=null,w&&d.current?r(n):(d.current=s.current=null,m.current)},c=function r(){var c=Date.now();if(y&&f.current===o.current&&A(),t(c))return e(c);if(g.current){var i=u-(c-a.current),l=O?Math.min(i,L-(c-o.current)):i;n(r,l)}},A=function(){i&&i({})},D=function(){if(b||F){var e,i=Date.now(),f=t(i);if(d.current=[].slice.call(arguments),s.current=l,a.current=i,T&&!x.current&&(x.current=function(){var r;\"hidden\"===(null==(r=globalThis.document)?void 0:r.visibilityState)&&E.current.flush()},null==(e=globalThis.document)||null==e.addEventListener||e.addEventListener(\"visibilitychange\",x.current)),f){if(!v.current&&g.current)return o.current=a.current,n(c,u),y?r(a.current):m.current;if(O)return n(c,u),r(a.current)}return v.current||n(c,u),m.current}};return D.cancel=function(){var r=v.current;r&&(p?cancelAnimationFrame(v.current):clearTimeout(v.current)),o.current=0,d.current=a.current=s.current=v.current=null,r&&i&&i({})},D.isPending=function(){return!!v.current},D.flush=function(){return v.current?e(Date.now()):m.current},D},[y,O,u,L,w,T,p,b,F,i]);return E.current=A,t(function(){return g.current=!0,function(){var r;T&&E.current.flush(),x.current&&(null==(r=globalThis.document)||null==r.removeEventListener||r.removeEventListener(\"visibilitychange\",x.current),x.current=null),g.current=!1}},[T]),A}function i(r,n){return r===n}function l(n,t,l){var a=l&&l.equalityFn||i,o=r(n),f=e({})[1],v=c(u(function(r){o.current=r,f({})},[f]),t,l,f),d=r(n);return a(d.current,n)||(v(n),d.current=n),[o.current,v]}function a(r,n,t){var e=void 0===t?{}:t,u=e.leading,i=e.trailing,l=e.flushOnExit;return c(r,n,{maxWait:n,leading:void 0===u||u,trailing:void 0===i||i,flushOnExit:void 0!==l&&l})}export{l as useDebounce,c as useDebouncedCallback,a as useThrottledCallback};\n//# sourceMappingURL=index.module.js.map\n","import { Box } from '@mui/material';\nimport type { Ref } from 'react';\nimport {\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { useDebouncedCallback } from 'use-debounce';\nimport { DevicePixelRatioService } from '@gen-epix/ui-core/classes/services/DevicePixelRatioService';\nimport { Subject } from '@gen-epix/ui-core/classes/Subject';\nimport { useScrollbarSize } from '@gen-epix/ui-core/hooks/useScrollbarSize';\nimport { useDimensions } from '@gen-epix/ui-core/hooks/useDimensions';\nimport { useSubscribable } from '@gen-epix/ui-core/hooks/useSubscribable';\n\nimport type {\n TreeAssembly,\n TreeNode,\n TreePathProperties,\n} from '../../models/tree';\nimport { TreeUtil } from '../../utils/TreeUtil';\n\nexport type PhylogeneticTreeHighlightedNodeNamesSubjectValue = {\n highlightedNodeNames: string[];\n};\n\nexport type PhylogeneticTreePathClickEvent = {\n mouseEvent: MouseEvent;\n pathProperties: TreePathProperties;\n};\n\nexport type PhylogeneticTreeProps = {\n readonly ancestorDotRadius: number;\n readonly ariaLabel: string;\n readonly backgroundColor: string;\n readonly dimFn: (color: string) => string;\n readonly fontFamily: string;\n readonly headerHeight: number;\n readonly highlightedNodeNamesSubject?: Subject<PhylogeneticTreeHighlightedNodeNamesSubjectValue>;\n readonly initialViewState?: Partial<PhylogeneticTreeViewState>;\n readonly itemHeight: number;\n readonly leafDotRadius: number;\n readonly linkedScrollDebounceDelayMs: number;\n readonly maxScaleWidthPx: number;\n readonly maxZoomLevel: number;\n readonly maxZoomSpeed: number;\n readonly minimumDistancePercentageToShowLabel: number;\n readonly minScaleWidthPx: number;\n readonly minZoomLevel: number;\n readonly minZoomSpeed: number;\n readonly nodeNameColors?: { [key: string]: string } | null;\n readonly onCanvasChange?: (canvas?: HTMLCanvasElement) => void;\n readonly onLinkStateChange?: (isLinked: boolean) => void;\n readonly onPathClick?: (event: PhylogeneticTreePathClickEvent) => void;\n readonly onViewStateChange?: (viewState: PhylogeneticTreeViewState) => void;\n readonly panningThreshold: number;\n readonly ref?: Ref<PhylogeneticTreeRef>;\n readonly regularFillColorSupportLine: string;\n readonly scaleColor: string;\n readonly scaleIncrements: number[];\n readonly scrollSubject?: Subject<PhylogeneticTreeScrollSubjectValue>;\n readonly shouldShowDistances: boolean;\n readonly shouldShowSupportLinesWhenUnlinked: boolean;\n readonly sortedLeafNames: string[];\n readonly supportLineColorLinked: string;\n readonly supportLineColorUnlinked: string;\n readonly tree?: TreeNode;\n readonly treeColor: string;\n readonly treeFont: string;\n readonly treePadding: number;\n readonly visibleRangeSubject?: Subject<PhylogeneticTreeVisibleRangeSubjectValue>;\n};\n\nexport interface PhylogeneticTreeRef {\n link: (verticalPosition?: number) => void;\n syncScrollToVisibleTree: () => void;\n unlink: (viewState: { positionX: number; positionY: number; zoomLevel: number }) => void;\n}\n\nexport type PhylogeneticTreeScrollSubjectValue = {\n origin: HTMLElement;\n position: number;\n};\n\nexport type PhylogeneticTreeViewState = {\n horizontalScrollPosition: number;\n verticalScrollPosition: number;\n zoomLevel: number;\n};\n\nexport type PhylogeneticTreeVisibleRangeSubjectValue = {\n endIndex: number;\n startIndex: number;\n};\n\nexport const PhylogeneticTree = ({\n ancestorDotRadius,\n ariaLabel,\n backgroundColor,\n dimFn,\n fontFamily,\n headerHeight,\n highlightedNodeNamesSubject,\n initialViewState,\n itemHeight,\n leafDotRadius,\n linkedScrollDebounceDelayMs,\n maxScaleWidthPx,\n maxZoomLevel,\n maxZoomSpeed,\n minimumDistancePercentageToShowLabel,\n minScaleWidthPx,\n minZoomLevel,\n minZoomSpeed,\n nodeNameColors,\n onCanvasChange,\n onLinkStateChange,\n onPathClick,\n onViewStateChange,\n panningThreshold,\n ref,\n regularFillColorSupportLine,\n scaleColor,\n scaleIncrements,\n scrollSubject,\n shouldShowDistances,\n shouldShowSupportLinesWhenUnlinked,\n sortedLeafNames,\n supportLineColorLinked,\n supportLineColorUnlinked,\n tree,\n treeColor,\n treeFont,\n treePadding,\n visibleRangeSubject,\n}: PhylogeneticTreeProps) => {\n const scrollbarSize = useScrollbarSize();\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const { dimensions: { height, width } } = useDimensions(containerRef);\n const [treeCanvas, setTreeCanvas] = useState<HTMLCanvasElement>();\n const [treeAssembly, setTreeAssembly] = useState<TreeAssembly>(null);\n const [devicePixelRatio, setDevicePixelRatio] = useState<number>(DevicePixelRatioService.getInstance().data);\n const [isLinked, setIsLinked] = useState(true);\n const canvasScrollSubject = useMemo(() => new Subject<{ x: number; y: number }>({ x: 0, y: 0 }), []);\n const zoomLevelSubject = useMemo(() => new Subject<number>(!isNaN(initialViewState?.zoomLevel) ? initialViewState.zoomLevel : 1), [initialViewState]);\n const scrollPositionSubject = useMemo(() => new Subject<{ horizontal: number; vertical: number }>({\n horizontal: !isNaN(initialViewState?.horizontalScrollPosition) ? initialViewState.horizontalScrollPosition : 0,\n vertical: !isNaN(initialViewState?.verticalScrollPosition) ? initialViewState.verticalScrollPosition : 0,\n }), [initialViewState]);\n\n const treeCanvasWidth = width;\n const treeCanvasHeight = Math.max(0, height - headerHeight);\n const combinedCanvasHeight = Math.max(0, height);\n const treeWidthMinusPadding = treeCanvasWidth - (2 * treePadding);\n const pixelToGeneticDistanceRatio = tree?.maxBranchLength ? treeWidthMinusPadding / tree.maxBranchLength.toNumber() : null;\n const treeHeight = tree?.size ? (tree.size * itemHeight) + scrollbarSize : itemHeight;\n\n const handleTreeCanvasRef = useCallback((canvas: HTMLCanvasElement | null) => {\n setTreeCanvas(canvas ?? undefined);\n }, []);\n\n useEffect(() => {\n onLinkStateChange?.(isLinked);\n }, [isLinked, onLinkStateChange]);\n\n useEffect(() => {\n if (!onCanvasChange) {\n return;\n }\n onCanvasChange(treeCanvas);\n\n return () => {\n if (treeCanvas) {\n onCanvasChange(undefined);\n }\n };\n }, [treeCanvas, onCanvasChange]);\n\n useEffect(() => {\n if (!onViewStateChange) {\n return;\n }\n\n const emitViewState = () => {\n onViewStateChange({\n horizontalScrollPosition: scrollPositionSubject.data.horizontal,\n verticalScrollPosition: scrollPositionSubject.data.vertical,\n zoomLevel: zoomLevelSubject.data,\n });\n };\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe(() => {\n emitViewState();\n });\n const unsubscribeFromScrollPositionSubject = scrollPositionSubject.subscribe(() => {\n emitViewState();\n });\n\n emitViewState();\n\n return () => {\n unsubscribeFromZoomLevelSubject();\n unsubscribeFromScrollPositionSubject();\n };\n }, [onViewStateChange, scrollPositionSubject, zoomLevelSubject]);\n\n useEffect(() => {\n let zoomLevel = zoomLevelSubject.data;\n\n const updateIsLinked = () => {\n if (isLinked && zoomLevel !== 1) {\n setIsLinked(false);\n }\n };\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n updateIsLinked();\n });\n updateIsLinked();\n\n return () => {\n unsubscribeFromZoomLevelSubject();\n };\n }, [isLinked, zoomLevelSubject]);\n\n useEffect(() => {\n const unsubscribe = canvasScrollSubject.subscribe((data) => {\n scrollPositionSubject.next({\n horizontal: !isNaN(data.x) ? data.x : scrollPositionSubject.data.horizontal,\n vertical: !isNaN(data.y) ? data.y : scrollPositionSubject.data.vertical,\n });\n });\n\n return () => {\n unsubscribe();\n };\n }, [canvasScrollSubject, scrollPositionSubject]);\n\n const emitScrollPosition = useCallback((position: number) => {\n if (!scrollSubject || !scrollContainerRef.current) {\n return;\n }\n\n scrollSubject.next({\n origin: scrollContainerRef.current,\n position,\n });\n }, [scrollSubject]);\n\n const updateScrollSubjectDebounced = useDebouncedCallback((position: number) => {\n if (!scrollSubject || !scrollContainerRef.current) {\n return;\n }\n\n scrollSubject.next({\n origin: scrollContainerRef.current,\n position: position / devicePixelRatio,\n });\n }, linkedScrollDebounceDelayMs, { leading: true, trailing: true });\n\n const updateScrollPosition = useCallback((params: { internalZoomLevel: number; positionX: number; positionY: number }) => {\n const { internalZoomLevel, positionX, positionY } = params;\n if (internalZoomLevel === 0) {\n throw new Error('internalZoomLevel cannot be 0');\n }\n\n const { newPositionX, newPositionY } = TreeUtil.getSanitizedScrollPosition({\n devicePixelRatio,\n headerHeight,\n internalZoomLevel,\n isLinked,\n positionX,\n positionY,\n treeCanvasHeight,\n treeCanvasWidth,\n treeHeight,\n treePadding,\n });\n\n const positionYChanged = newPositionY !== canvasScrollSubject.data.y;\n\n canvasScrollSubject.next({\n x: newPositionX,\n y: newPositionY,\n });\n\n if (isLinked && internalZoomLevel === 1 && positionYChanged) {\n updateScrollSubjectDebounced(newPositionY);\n }\n }, [canvasScrollSubject, devicePixelRatio, headerHeight, isLinked, treeCanvasHeight, treeCanvasWidth, treeHeight, treePadding, updateScrollSubjectDebounced]);\n\n useEffect(() => {\n updateScrollPosition({\n internalZoomLevel: zoomLevelSubject.data,\n positionX: canvasScrollSubject.data.x,\n positionY: canvasScrollSubject.data.y,\n });\n }, [canvasScrollSubject, updateScrollPosition, zoomLevelSubject]);\n\n const link = useCallback((verticalPosition?: number) => {\n const nextVerticalPosition = verticalPosition ?? scrollSubject?.data?.position ?? 0;\n\n zoomLevelSubject.next(1);\n setIsLinked(true);\n updateScrollPosition({\n internalZoomLevel: 1,\n positionX: 0,\n positionY: nextVerticalPosition,\n });\n\n if (verticalPosition !== undefined) {\n emitScrollPosition(nextVerticalPosition);\n }\n }, [emitScrollPosition, scrollSubject, updateScrollPosition, zoomLevelSubject]);\n\n const unlink = useCallback((viewState: { positionX: number; positionY: number; zoomLevel: number }) => {\n setIsLinked(false);\n zoomLevelSubject.next(viewState.zoomLevel);\n updateScrollPosition({\n internalZoomLevel: viewState.zoomLevel,\n positionX: viewState.positionX,\n positionY: viewState.positionY,\n });\n }, [updateScrollPosition, zoomLevelSubject]);\n\n const syncScrollToVisibleTree = useCallback(() => {\n if (!tree?.size) {\n link(0);\n return;\n }\n\n const newScrollPosition = TreeUtil.getScrollPositionFromTreeVisibility({\n itemHeight,\n treeCanvasHeight,\n treeHeight,\n treeSize: tree.size,\n verticalScrollPosition: scrollPositionSubject.data.vertical,\n zoomLevel: zoomLevelSubject.data,\n });\n\n link(newScrollPosition);\n }, [itemHeight, link, scrollPositionSubject, tree, treeCanvasHeight, treeHeight, zoomLevelSubject]);\n\n useImperativeHandle(ref, () => ({\n link,\n syncScrollToVisibleTree,\n unlink,\n }), [link, syncScrollToVisibleTree, unlink]);\n\n const devicePixelRatioServiceCallback = useCallback((newDevicePixelRatio: number, previousDevicePixelRatio: number) => {\n canvasScrollSubject.next({\n x: (canvasScrollSubject.data.x / previousDevicePixelRatio) * newDevicePixelRatio,\n y: (canvasScrollSubject.data.y / previousDevicePixelRatio) * newDevicePixelRatio,\n });\n setDevicePixelRatio(newDevicePixelRatio);\n }, [canvasScrollSubject]);\n\n useSubscribable(DevicePixelRatioService.getInstance(), {\n callback: devicePixelRatioServiceCallback,\n });\n\n const getTickerMarkScale = useCallback((zoomLevel: number) => {\n return TreeUtil.getTickMarkScale({\n geneticTreeWidth: tree?.maxBranchLength,\n maxScaleWidthPx,\n minGeneticScaleUnit: TreeUtil.getMinGeneticScaleUnit(tree),\n minScaleWidthPx,\n scaleIncrements,\n treeWidthMinusPadding,\n zoomLevel,\n });\n }, [maxScaleWidthPx, minScaleWidthPx, scaleIncrements, tree, treeWidthMinusPadding]);\n\n const getPathPropertiesFromCanvas = useCallback((canvas: HTMLCanvasElement, event: MouseEvent): TreePathProperties => {\n return TreeUtil.getPathPropertiesFromCanvas({\n canvas,\n devicePixelRatio,\n event,\n treeAssembly,\n });\n }, [devicePixelRatio, treeAssembly]);\n\n useEffect(() => {\n if (!scrollSubject) {\n return;\n }\n\n let scrollData = scrollSubject.data;\n let zoomLevel = zoomLevelSubject.data;\n\n const update = () => {\n if (!scrollData || scrollData.origin === scrollContainerRef.current) {\n return;\n }\n if (isLinked && zoomLevel === 1) {\n canvasScrollSubject.next({\n x: canvasScrollSubject.data.x * devicePixelRatio,\n y: scrollData.position * devicePixelRatio,\n });\n }\n };\n\n const unsubscribeFromScrollSubject = scrollSubject.subscribe((data) => {\n scrollData = data;\n update();\n });\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n update();\n });\n\n return () => {\n unsubscribeFromScrollSubject();\n unsubscribeFromZoomLevelSubject();\n };\n }, [canvasScrollSubject, devicePixelRatio, scrollSubject, isLinked, zoomLevelSubject]);\n\n useEffect(() => {\n if (!tree || !pixelToGeneticDistanceRatio) {\n setTreeAssembly(null);\n return;\n }\n\n setTreeAssembly(TreeUtil.assembleTree({\n ancestorDotRadius,\n itemHeight,\n leafDotRadius,\n minimumDistancePercentageToShowLabel,\n pixelToGeneticDistanceRatio,\n rootNode: tree,\n sortedLeafNames,\n treeCanvasWidth,\n treePadding,\n }));\n }, [ancestorDotRadius, itemHeight, leafDotRadius, sortedLeafNames, minimumDistancePercentageToShowLabel, pixelToGeneticDistanceRatio, tree, treeCanvasWidth, treePadding]);\n\n useEffect(() => {\n if (!treeCanvas || !treeAssembly || !tree) {\n return;\n }\n\n let animationFrameId: number;\n let zoomLevel: number = zoomLevelSubject.data;\n let tickerMarkScale = getTickerMarkScale(zoomLevel);\n let highlightedNodeNames: string[] = highlightedNodeNamesSubject?.data?.highlightedNodeNames ?? [];\n let scrollPosition = scrollSubject?.data?.position ?? 0;\n let horizontalScrollPosition = scrollPositionSubject.data.horizontal;\n let verticalScrollPosition = scrollPositionSubject.data.vertical;\n let range = visibleRangeSubject?.data;\n\n const render = () => {\n cancelAnimationFrame(animationFrameId);\n animationFrameId = requestAnimationFrame(() => {\n TreeUtil.drawTreeCanvas({\n backgroundColor,\n canvas: treeCanvas,\n devicePixelRatio,\n dimFn,\n fontFamily,\n geneticTreeWidth: tree.maxBranchLength,\n headerHeight,\n highlightedNodeNames,\n horizontalScrollPosition,\n isLinked,\n itemHeight,\n nodeNameColors,\n pixelToGeneticDistanceRatio,\n range,\n regularFillColorSupportLine,\n scaleColor,\n scrollPosition,\n shouldShowDistances,\n shouldShowSupportLinesWhenUnlinked,\n supportLineColorLinked,\n supportLineColorUnlinked,\n tickerMarkScale,\n treeAssembly,\n treeCanvasHeight,\n treeCanvasWidth,\n treeColor,\n treeFont,\n treePadding,\n verticalScrollPosition,\n zoomLevel,\n });\n });\n };\n\n const unsubscribeFromHighlighting = highlightedNodeNamesSubject ? highlightedNodeNamesSubject.subscribe((data) => {\n highlightedNodeNames = data.highlightedNodeNames;\n render();\n }) : (): null => null;\n\n const unsubscribeFromScrollPositionSubject = scrollPositionSubject.subscribe((data) => {\n horizontalScrollPosition = data.horizontal;\n verticalScrollPosition = data.vertical;\n render();\n });\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n tickerMarkScale = getTickerMarkScale(data);\n render();\n });\n\n const unsubscribeFromScrollSubject = scrollSubject?.subscribe((data) => {\n if (data.origin === scrollContainerRef.current) {\n return;\n }\n scrollPosition = data.position;\n render();\n });\n\n const unsubscribeFromVisibleRangeSubject = visibleRangeSubject?.subscribe((data) => {\n range = data;\n render();\n });\n\n render();\n\n return () => {\n unsubscribeFromHighlighting();\n unsubscribeFromScrollSubject?.();\n unsubscribeFromScrollPositionSubject();\n unsubscribeFromZoomLevelSubject();\n unsubscribeFromVisibleRangeSubject?.();\n cancelAnimationFrame(animationFrameId);\n };\n }, [\n backgroundColor,\n devicePixelRatio,\n dimFn,\n highlightedNodeNamesSubject,\n scrollSubject,\n visibleRangeSubject,\n fontFamily,\n getTickerMarkScale,\n headerHeight,\n isLinked,\n itemHeight,\n pixelToGeneticDistanceRatio,\n regularFillColorSupportLine,\n scaleColor,\n scrollPositionSubject,\n shouldShowDistances,\n shouldShowSupportLinesWhenUnlinked,\n nodeNameColors,\n supportLineColorLinked,\n supportLineColorUnlinked,\n tree,\n treeAssembly,\n treeCanvas,\n treeCanvasHeight,\n treeCanvasWidth,\n treeColor,\n treeFont,\n treePadding,\n zoomLevelSubject,\n ]);\n\n useEffect(() => {\n if (!treeCanvas) {\n return;\n }\n\n let zoomLevel = zoomLevelSubject.data;\n\n let pos = {\n currentX: 0,\n currentY: 0,\n x: 0,\n y: 0,\n };\n let followMouse = false;\n\n const clearHighlighting = () => {\n if (highlightedNodeNamesSubject?.data?.highlightedNodeNames?.length) {\n highlightedNodeNamesSubject.next({\n highlightedNodeNames: [],\n });\n }\n };\n\n const isEventInHeader = (event: MouseEvent | WheelEvent) => event.offsetY < headerHeight;\n\n const onMouseDown = (event: MouseEvent) => {\n if (isEventInHeader(event)) {\n treeCanvas.style.cursor = 'default';\n return;\n }\n\n pos = {\n currentX: canvasScrollSubject.data.x,\n currentY: canvasScrollSubject.data.y,\n x: event.clientX,\n y: event.clientY,\n };\n followMouse = true;\n };\n\n const onMouseMove = (event: MouseEvent) => {\n if (isEventInHeader(event)) {\n followMouse = false;\n treeCanvas.style.cursor = 'default';\n clearHighlighting();\n return;\n }\n\n if (followMouse) {\n treeCanvas.style.cursor = 'move';\n\n const deltaX = event.clientX - pos.x;\n const deltaY = event.clientY - pos.y;\n const scrollPositionX = pos.currentX - deltaX;\n const scrollPositionY = pos.currentY - deltaY;\n\n let sanitizedScrollPositionX = scrollPositionX;\n if (zoomLevel === 1 && Math.abs(deltaX) < panningThreshold && pos.currentX === 0) {\n sanitizedScrollPositionX = 0;\n }\n updateScrollPosition({ internalZoomLevel: zoomLevel, positionX: sanitizedScrollPositionX, positionY: scrollPositionY });\n return;\n }\n\n const pathProperties = getPathPropertiesFromCanvas(treeCanvas, event);\n if (pathProperties) {\n treeCanvas.style.cursor = 'pointer';\n highlightedNodeNamesSubject?.next({\n highlightedNodeNames: pathProperties.subTreeLeaveNames,\n });\n } else {\n treeCanvas.style.cursor = 'default';\n clearHighlighting();\n }\n };\n\n const onMouseUp = (event: MouseEvent) => {\n followMouse = false;\n\n if (isEventInHeader(event)) {\n return;\n }\n\n const pathProperties = getPathPropertiesFromCanvas(treeCanvas, event);\n if (pathProperties) {\n onPathClick?.({\n mouseEvent: event,\n pathProperties,\n });\n }\n };\n\n const onMouseWheel = (event: WheelEvent) => {\n event.preventDefault();\n\n if (isEventInHeader(event)) {\n return;\n }\n\n if (event.shiftKey) {\n updateScrollPosition({ internalZoomLevel: zoomLevel, positionX: canvasScrollSubject.data.x + (event.deltaX || event.deltaY), positionY: canvasScrollSubject.data.y });\n return;\n }\n if (event.metaKey || event.ctrlKey) {\n updateScrollPosition({ internalZoomLevel: zoomLevel, positionX: canvasScrollSubject.data.x, positionY: canvasScrollSubject.data.y + (event.deltaX || event.deltaY) });\n return;\n }\n\n const zoomSpeed = Math.min(maxZoomSpeed, Math.max(minZoomSpeed, treeHeight / treeCanvasHeight * 0.2));\n const newZoomLevel = Math.min(maxZoomLevel, Math.max(minZoomLevel, zoomLevel + (event.deltaY > 0 ? zoomSpeed : -zoomSpeed)));\n const treeBodyOffsetY = event.offsetY - headerHeight;\n\n const newScrollPositionY = TreeUtil.getNewScrollPositionForZoomLevel({\n currentZoomLevel: zoomLevel,\n dimensionSize: treeHeight,\n eventOffset: treeBodyOffsetY,\n newZoomLevel,\n scrollPosition: canvasScrollSubject.data.y,\n });\n const newScrollPositionX = TreeUtil.getNewScrollPositionForZoomLevel({\n currentZoomLevel: zoomLevel,\n dimensionSize: treeCanvasWidth,\n eventOffset: event.offsetX,\n newZoomLevel,\n scrollPosition: canvasScrollSubject.data.x,\n });\n zoomLevelSubject.next(newZoomLevel);\n if (newZoomLevel !== 1) {\n updateScrollPosition({ internalZoomLevel: newZoomLevel, positionX: newScrollPositionX, positionY: newScrollPositionY });\n } else {\n updateScrollPosition({ internalZoomLevel: 1, positionX: newScrollPositionX, positionY: scrollSubject?.data?.position ?? 0 });\n }\n };\n\n const onMouseOut = () => {\n followMouse = false;\n clearHighlighting();\n };\n\n const unsubscribeFromZoomLevelSubject = zoomLevelSubject.subscribe((data) => {\n zoomLevel = data;\n });\n\n treeCanvas.addEventListener('mousemove', onMouseMove);\n treeCanvas.addEventListener('mousedown', onMouseDown);\n treeCanvas.addEventListener('mouseup', onMouseUp);\n treeCanvas.addEventListener('mouseout', onMouseOut);\n treeCanvas.addEventListener('wheel', onMouseWheel, { passive: false });\n\n return () => {\n treeCanvas.removeEventListener('mousemove', onMouseMove);\n treeCanvas.removeEventListener('mousedown', onMouseDown);\n treeCanvas.removeEventListener('mouseup', onMouseUp);\n treeCanvas.removeEventListener('mouseout', onMouseOut);\n treeCanvas.removeEventListener('wheel', onMouseWheel);\n unsubscribeFromZoomLevelSubject();\n };\n }, [\n canvasScrollSubject,\n highlightedNodeNamesSubject,\n scrollSubject,\n getPathPropertiesFromCanvas,\n headerHeight,\n maxZoomLevel,\n maxZoomSpeed,\n minZoomLevel,\n minZoomSpeed,\n onPathClick,\n panningThreshold,\n treeCanvas,\n treeCanvasHeight,\n treeCanvasWidth,\n treeHeight,\n updateScrollPosition,\n zoomLevelSubject,\n ]);\n\n const shouldRenderCanvas = !!tree && treeCanvasWidth > 0 && tree.size > 0;\n\n return (\n <Box\n ref={containerRef}\n sx={{\n height: '100%',\n overflow: 'clip',\n position: 'relative',\n width: '100%',\n }}\n >\n <Box\n ref={scrollContainerRef}\n sx={{\n height: combinedCanvasHeight,\n overflowY: 'hidden',\n position: 'absolute',\n width: treeCanvasWidth,\n }}\n >\n {shouldRenderCanvas && (\n <Box\n aria-label={ariaLabel}\n component={'canvas'}\n ref={handleTreeCanvasRef}\n role={'figure'}\n sx={{\n height: combinedCanvasHeight,\n width: treeCanvasWidth,\n }}\n />\n )}\n </Box>\n </Box>\n );\n};\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/_baseSum.js","../../../../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/sum.js","../../../src/utils/NewickUtil/NewickUtil.ts"],"sourcesContent":["/**\n * The base implementation of `_.sum` and `_.sumBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the sum.\n */\nfunction baseSum(array, iteratee) {\n var result,\n index = -1,\n length = array.length;\n\n while (++index < length) {\n var current = iteratee(array[index]);\n if (current !== undefined) {\n result = result === undefined ? current : (result + current);\n }\n }\n return result;\n}\n\nmodule.exports = baseSum;\n","var baseSum = require('./_baseSum'),\n identity = require('./identity');\n\n/**\n * Computes the sum of the values in `array`.\n *\n * @static\n * @memberOf _\n * @since 3.4.0\n * @category Math\n * @param {Array} array The array to iterate over.\n * @returns {number} Returns the sum.\n * @example\n *\n * _.sum([4, 2, 8, 6]);\n * // => 20\n */\nfunction sum(array) {\n return (array && array.length)\n ? baseSum(array, identity)\n : 0;\n}\n\nmodule.exports = sum;\n","import { Decimal } from 'decimal.js';\nimport sum from 'lodash/sum';\nimport { StringUtil } from '@gen-epix/ui-core/utils/StringUtil';\n\nimport type { TreeNode } from '../../models/tree';\n\nexport class NewickUtil {\n public static getSortedNames(node: TreeNode): string[] {\n return [\n ...(node.children ?? []).map(child => NewickUtil.getSortedNames(child)).flat(),\n ...(!node.children ? [node.name] : []),\n ];\n }\n\n public static parse(newick: string): TreeNode {\n const ancestors: Array<Partial<TreeNode>> = [];\n let tree: Partial<TreeNode> = {};\n const tokens = newick.split(/(;|\\(|\\)|,|:)/).map(x => x.trim()).filter(x => x);\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n const subtree: Partial<TreeNode> = {};\n const x = tokens[i - 1];\n switch (token) {\n case ',': // another branch\n ancestors[ancestors.length - 1].children.push(subtree);\n tree = subtree;\n break;\n case ';': // end of tree, nothing to do\n break;\n case ':': // optional length next\n break;\n case '(': // new children\n tree.children = [subtree];\n ancestors.push(tree);\n tree = subtree;\n break;\n case ')': // optional name next\n tree = ancestors.pop();\n tree.children.forEach(child => {\n if (!child.children) {\n child.size = 1;\n child.maxBranchLength = new Decimal(child.branchLength ?? 0);\n child.subTreeLeaveNames = [child.name];\n child.subTreeNames = child.subTreeNames ?? [];\n }\n });\n tree.size = sum(tree.children.map(child => child.size));\n tree.subTreeNames = tree.children.map(child => child.subTreeNames).flat().filter(n => n);\n tree.subTreeLeaveNames = tree.children.map(child => child.subTreeLeaveNames).flat().filter(n => n);\n tree.maxBranchLength = Decimal.max(...tree.children.map(child => child.maxBranchLength));\n break;\n default:\n if (x === ')' || x === '(' || x === ',') {\n tree.name = token;\n } else if (x === ':') {\n tree.branchLength = new Decimal(token);\n tree.subTreeNames = (tree.children ?? []).map(child => [child.name, ...child.subTreeNames]).flat().filter(n => n);\n tree.subTreeLeaveNames = (tree.children ?? []).map(child => child.subTreeLeaveNames).flat().filter(n => n);\n tree.maxBranchLength = tree.branchLength.add(tree.children?.length ? Decimal.max(...tree.children.map(child => child.maxBranchLength)) : 0);\n tree.name = tree.name || `Generated-${StringUtil.createHash(tree.subTreeNames.join(','))}`;\n }\n }\n }\n tree.branchLength = tree.branchLength ?? new Decimal(0);\n tree.maxBranchLength = tree.children?.length ? Decimal.max(...tree.children.map(child => child.maxBranchLength)) : new Decimal(0);\n tree.name = 'Root';\n return tree;\n }\n}\n"],"x_google_ignoreList":[0,1],"mappings":";;;;CASA,SAAS,EAAQ,GAAO,GAAU;EAKhC,KAJA,IAAI,GACA,IAAQ,IACR,IAAS,EAAM,QAEZ,EAAE,IAAQ,IAAQ;GACvB,IAAI,IAAU,EAAS,EAAM,EAAM;GACnC,AAAI,MAAY,KAAA,MACd,IAAS,MAAW,KAAA,IAAY,IAAW,IAAS;EAExD;EACA,OAAO;CACT;CAEA,EAAO,UAAU;;CCvBjB,IAAI,IAAA,EAAA,GACA,IAAA,EAAA;CAgBJ,SAAS,EAAI,GAAO;EAClB,OAAQ,KAAS,EAAM,SACnB,EAAQ,GAAO,CAAQ,IACvB;CACN;CAEA,EAAO,UAAU;YCjBJ,IAAb,MAAa,EAAW;CACtB,OAAc,eAAe,GAA0B;EACrD,OAAO,CACL,IAAI,EAAK,YAAY,CAAC,EAAA,CAAG,KAAI,MAAS,EAAW,eAAe,CAAK,CAAC,CAAC,CAAC,KAAK,GAC7E,GAAK,EAAK,WAAyB,CAAC,IAAf,CAAC,EAAK,IAAI,CACjC;CACF;CAEA,OAAc,MAAM,GAA0B;EAC5C,IAAM,IAAsC,CAAC,GACzC,IAA0B,CAAC,GACzB,IAAS,EAAO,MAAM,eAAe,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,CAAC,QAAO,MAAK,CAAC;EAC7E,KAAK,IAAI,IAAI,GAAG,IAAI,EAAO,QAAQ,KAAK;GACtC,IAAM,IAAQ,EAAO,IACf,IAA6B,CAAC,GAC9B,IAAI,EAAO,IAAI;GACrB,QAAQ,GAAR;IACE,KAAK;KAEH,AADA,EAAU,EAAU,SAAS,EAAE,CAAC,SAAS,KAAK,CAAO,GACrD,IAAO;KACP;IACF,KAAK,KACH;IACF,KAAK,KACH;IACF,KAAK;KAGH,AAFA,EAAK,WAAW,CAAC,CAAO,GACxB,EAAU,KAAK,CAAI,GACnB,IAAO;KACP;IACF,KAAK;KAaH,AAZA,IAAO,EAAU,IAAI,GACrB,EAAK,SAAS,SAAQ,MAAS;MAC7B,AAAK,EAAM,aACT,EAAM,OAAO,GACb,EAAM,kBAAkB,IAAI,EAAQ,EAAM,gBAAgB,CAAC,GAC3D,EAAM,oBAAoB,CAAC,EAAM,IAAI,GACrC,EAAM,eAAe,EAAM,gBAAgB,CAAC;KAEhD,CAAC,GACD,EAAK,QAAA,
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/_baseSum.js","../../../../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/sum.js","../../../src/utils/NewickUtil/NewickUtil.ts"],"sourcesContent":["/**\n * The base implementation of `_.sum` and `_.sumBy` without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {number} Returns the sum.\n */\nfunction baseSum(array, iteratee) {\n var result,\n index = -1,\n length = array.length;\n\n while (++index < length) {\n var current = iteratee(array[index]);\n if (current !== undefined) {\n result = result === undefined ? current : (result + current);\n }\n }\n return result;\n}\n\nmodule.exports = baseSum;\n","var baseSum = require('./_baseSum'),\n identity = require('./identity');\n\n/**\n * Computes the sum of the values in `array`.\n *\n * @static\n * @memberOf _\n * @since 3.4.0\n * @category Math\n * @param {Array} array The array to iterate over.\n * @returns {number} Returns the sum.\n * @example\n *\n * _.sum([4, 2, 8, 6]);\n * // => 20\n */\nfunction sum(array) {\n return (array && array.length)\n ? baseSum(array, identity)\n : 0;\n}\n\nmodule.exports = sum;\n","import { Decimal } from 'decimal.js';\nimport sum from 'lodash/sum';\nimport { StringUtil } from '@gen-epix/ui-core/utils/StringUtil';\n\nimport type { TreeNode } from '../../models/tree';\n\nexport class NewickUtil {\n public static getSortedNames(node: TreeNode): string[] {\n return [\n ...(node.children ?? []).map(child => NewickUtil.getSortedNames(child)).flat(),\n ...(!node.children ? [node.name] : []),\n ];\n }\n\n public static parse(newick: string): TreeNode {\n const ancestors: Array<Partial<TreeNode>> = [];\n let tree: Partial<TreeNode> = {};\n const tokens = newick.split(/(;|\\(|\\)|,|:)/).map(x => x.trim()).filter(x => x);\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n const subtree: Partial<TreeNode> = {};\n const x = tokens[i - 1];\n switch (token) {\n case ',': // another branch\n ancestors[ancestors.length - 1].children.push(subtree);\n tree = subtree;\n break;\n case ';': // end of tree, nothing to do\n break;\n case ':': // optional length next\n break;\n case '(': // new children\n tree.children = [subtree];\n ancestors.push(tree);\n tree = subtree;\n break;\n case ')': // optional name next\n tree = ancestors.pop();\n tree.children.forEach(child => {\n if (!child.children) {\n child.size = 1;\n child.maxBranchLength = new Decimal(child.branchLength ?? 0);\n child.subTreeLeaveNames = [child.name];\n child.subTreeNames = child.subTreeNames ?? [];\n }\n });\n tree.size = sum(tree.children.map(child => child.size));\n tree.subTreeNames = tree.children.map(child => child.subTreeNames).flat().filter(n => n);\n tree.subTreeLeaveNames = tree.children.map(child => child.subTreeLeaveNames).flat().filter(n => n);\n tree.maxBranchLength = Decimal.max(...tree.children.map(child => child.maxBranchLength));\n break;\n default:\n if (x === ')' || x === '(' || x === ',') {\n tree.name = token;\n } else if (x === ':') {\n tree.branchLength = new Decimal(token);\n tree.subTreeNames = (tree.children ?? []).map(child => [child.name, ...child.subTreeNames]).flat().filter(n => n);\n tree.subTreeLeaveNames = (tree.children ?? []).map(child => child.subTreeLeaveNames).flat().filter(n => n);\n tree.maxBranchLength = tree.branchLength.add(tree.children?.length ? Decimal.max(...tree.children.map(child => child.maxBranchLength)) : 0);\n tree.name = tree.name || `Generated-${StringUtil.createHash(tree.subTreeNames.join(','))}`;\n }\n }\n }\n tree.branchLength = tree.branchLength ?? new Decimal(0);\n tree.maxBranchLength = tree.children?.length ? Decimal.max(...tree.children.map(child => child.maxBranchLength)) : new Decimal(0);\n tree.name = 'Root';\n return tree;\n }\n}\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|
|
@@ -497,7 +497,7 @@ var o = /* @__PURE__ */ n(((e, t) => {
|
|
|
497
497
|
}
|
|
498
498
|
t.exports = u;
|
|
499
499
|
})), Ee = /* @__PURE__ */ n(((e, t) => {
|
|
500
|
-
var n = Z(), r =
|
|
500
|
+
var n = Z(), r = 1 / 0, i = 17976931348623157e292;
|
|
501
501
|
function a(e) {
|
|
502
502
|
return e ? (e = n(e), e === r || e === -r ? (e < 0 ? -1 : 1) * i : e === e ? e : 0) : e === 0 ? e : 0;
|
|
503
503
|
}
|
|
@@ -512,7 +512,7 @@ var o = /* @__PURE__ */ n(((e, t) => {
|
|
|
512
512
|
})), Oe = /* @__PURE__ */ n(((e, t) => {
|
|
513
513
|
t.exports = Array.isArray;
|
|
514
514
|
})), ke = /* @__PURE__ */ n(((e, t) => {
|
|
515
|
-
var n = d(), r = c(), i = Oe(), a = X(), o =
|
|
515
|
+
var n = d(), r = c(), i = Oe(), a = X(), o = 1 / 0, s = n ? n.prototype : void 0, l = s ? s.toString : void 0;
|
|
516
516
|
function u(e) {
|
|
517
517
|
if (typeof e == "string") return e;
|
|
518
518
|
if (i(e)) return r(e, u) + "";
|
|
@@ -791,22 +791,23 @@ var o = /* @__PURE__ */ n(((e, t) => {
|
|
|
791
791
|
}
|
|
792
792
|
static getSanitizedScrollPosition(e) {
|
|
793
793
|
let { devicePixelRatio: t, headerHeight: n, internalZoomLevel: r, isLinked: i, positionX: a, positionY: o, treeCanvasHeight: s, treeCanvasWidth: c, treeHeight: l, treePadding: u } = e, d, f, p = u * t;
|
|
794
|
-
if (i && r === 1)
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
794
|
+
if (i && r === 1) {
|
|
795
|
+
if (l < s) f = 0, d = 0;
|
|
796
|
+
else {
|
|
797
|
+
let e = Math.round(t * 100) / 100, n = [
|
|
798
|
+
[1, 0],
|
|
799
|
+
[1.1, 1],
|
|
800
|
+
[1.25, 4],
|
|
801
|
+
[1.5, 7],
|
|
802
|
+
[1.75, 11],
|
|
803
|
+
[2, 0],
|
|
804
|
+
[2.2, 4],
|
|
805
|
+
[2.5, 7],
|
|
806
|
+
[3, 15]
|
|
807
|
+
].find(([t]) => e <= t)?.[1] ?? 0;
|
|
808
|
+
f = 0, d = l * t - s * t - n;
|
|
809
|
+
}
|
|
810
|
+
} else f = -s * t + p + n * t, d = l / r * t - p - n * t;
|
|
810
811
|
let m = Math.max(Math.min(d, o), f), h = Math.min(0, -c + 2 * p), g = Math.max(0, c / r * t - 2 * p);
|
|
811
812
|
return {
|
|
812
813
|
newPositionX: Math.max(Math.min(g, a), h),
|