@rsdoctor/components 1.5.17 → 1.5.18

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 (31) hide show
  1. package/dist/components/Alerts/bundle-alert.d.ts +1 -1
  2. package/dist/components/Alerts/bundle-alert.mjs +74 -67
  3. package/dist/components/Alerts/bundle-alert.mjs.map +1 -1
  4. package/dist/components/Alerts/list.d.ts +1 -0
  5. package/dist/components/Alerts/list.mjs +13 -5
  6. package/dist/components/Alerts/list.mjs.map +1 -1
  7. package/dist/components/Alerts/list.module.mjs +2 -1
  8. package/dist/components/Alerts/list.module.mjs.map +1 -1
  9. package/dist/components/Alerts/list_module.css +8 -0
  10. package/dist/components/Alerts/list_module.css.map +1 -1
  11. package/dist/components/Charts/TreeMap.mjs +36 -6
  12. package/dist/components/Charts/TreeMap.mjs.map +1 -1
  13. package/dist/components/Opener/ide.mjs +36 -2
  14. package/dist/components/Opener/ide.mjs.map +1 -1
  15. package/dist/pages/BundleSize/components/asset-path.d.ts +7 -0
  16. package/dist/pages/BundleSize/components/asset-path.mjs +9 -0
  17. package/dist/pages/BundleSize/components/asset-path.mjs.map +1 -0
  18. package/dist/pages/BundleSize/components/asset-path.test.d.ts +1 -0
  19. package/dist/pages/BundleSize/components/asset-path.test.mjs +27 -0
  20. package/dist/pages/BundleSize/components/asset-path.test.mjs.map +1 -0
  21. package/dist/pages/BundleSize/components/index.mjs +4 -3
  22. package/dist/pages/BundleSize/components/index.mjs.map +1 -1
  23. package/dist/pages/BundleSize/components/tree-graph.mjs +30 -13
  24. package/dist/pages/BundleSize/components/tree-graph.mjs.map +1 -1
  25. package/dist/utils/assets.d.ts +1 -0
  26. package/dist/utils/assets.mjs +17 -0
  27. package/dist/utils/assets.mjs.map +1 -0
  28. package/dist/utils/assets.test.d.ts +1 -0
  29. package/dist/utils/assets.test.mjs +22 -0
  30. package/dist/utils/assets.test.mjs.map +1 -0
  31. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"components/Charts/TreeMap.mjs","sources":["../../../src/components/Charts/TreeMap.tsx"],"sourcesContent":["import React, { useEffect, useState, memo, useMemo, useCallback } from 'react';\nimport EChartsReactCore from 'echarts-for-react/esm/core';\nimport * as echarts from 'echarts/core';\nimport { TreemapChart, type TreemapSeriesOption } from 'echarts/charts';\nimport {\n TooltipComponent,\n TitleComponent,\n type TooltipComponentOption,\n type TitleComponentOption,\n} from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\nimport { Alert, Checkbox, Radio, Input } from 'antd';\nimport {\n LeftOutlined,\n RightOutlined,\n SearchOutlined,\n FullscreenOutlined,\n FullscreenExitOutlined,\n} from '@ant-design/icons';\nimport type { ComposeOption, EChartsType } from 'echarts/core';\nimport { formatSize } from 'src/utils';\nimport { SDK } from '@rsdoctor/types';\nimport { ServerAPIProvider } from 'src/components/Manifest';\nimport { ModuleAnalyzeComponent } from '../../pages/ModuleAnalyze';\nimport Styles from './treemap.module.scss';\nimport { TREE_COLORS } from './constants';\nimport type {\n CallbackDataParams,\n ECElementEvent,\n} from 'echarts/types/dist/shared';\n\ntype TreeMapOption = ComposeOption<\n TreemapSeriesOption | TooltipComponentOption | TitleComponentOption\n>;\n\ntype TreemapDataNode = NonNullable<TreemapSeriesOption['data']>[number] & {\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n moduleId?: string | number;\n};\n\necharts.use([TreemapChart, TooltipComponent, TitleComponent, CanvasRenderer]);\n\nexport type TreeNode = {\n name: string;\n value?: number;\n children?: TreeNode[];\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n id?: string | number;\n};\n\nexport type SizeType = 'stat' | 'parsed' | 'gzip' | 'value';\n\ninterface TreeMapProps {\n treeData: TreeNode[];\n sizeType: SizeType;\n style?: React.CSSProperties;\n onChartClick?: (params: ECElementEvent) => void;\n highlightNodeId?: number;\n centerNodeId?: number;\n rootPath?: string;\n}\n\nfunction hashString(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n }\n return hash >>> 0;\n}\n\nfunction blendWithWhite(hex: string, ratio: number): string {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n\n const blendedR = Math.round(r * ratio + 255 * (1 - ratio));\n const blendedG = Math.round(g * ratio + 255 * (1 - ratio));\n const blendedB = Math.round(b * ratio + 255 * (1 - ratio));\n\n return `#${blendedR.toString(16).padStart(2, '0')}${blendedG.toString(16).padStart(2, '0')}${blendedB.toString(16).padStart(2, '0')}`;\n}\n\nfunction getLuminance(hex: string): number {\n const r = parseInt(hex.slice(1, 3), 16) / 255;\n const g = parseInt(hex.slice(3, 5), 16) / 255;\n const b = parseInt(hex.slice(5, 7), 16) / 255;\n\n const [rs, gs, bs] = [r, g, b].map((val) => {\n return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);\n });\n\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\nfunction isDarkColor(hex: string): boolean {\n return getLuminance(hex) < 0.4;\n}\n\nfunction getLevelOption() {\n return [\n {\n itemStyle: {\n borderWidth: 0,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n },\n {\n itemStyle: {\n borderColorAlpha: [1, 0.3],\n borderWidth: 5,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n upperLabel: {\n show: true,\n color: '#ffffff',\n fontSize: 12,\n height: 30,\n },\n },\n ];\n}\n\nexport const TreeMap: React.FC<TreeMapProps> = memo(\n ({\n treeData,\n sizeType,\n style,\n onChartClick,\n highlightNodeId,\n centerNodeId,\n rootPath,\n }) => {\n const [option, setOption] = useState<TreeMapOption | null>(null);\n const chartRef = React.useRef<EChartsReactCore | null>(null);\n const chartDataRef = React.useRef<TreemapDataNode[]>([]);\n const clickTimeoutRef = React.useRef<number | null>(null);\n\n useEffect(() => {\n if (!treeData) return;\n function convert(\n node: TreeNode,\n index = 0,\n level = 0,\n parentColor?: string,\n siblingIndex = 0,\n siblingCount = 1,\n chunkPath?: string,\n ): TreemapDataNode {\n const baseColor =\n parentColor || TREE_COLORS[index % TREE_COLORS.length];\n\n // For level 0 (chunk level), use the chunk's path/name as chunkPath\n const currentChunkPath =\n level === 0 ? node.path || node.name || '' : chunkPath || '';\n\n const children = node.children?.map((c, childIndex) =>\n convert(\n c,\n index,\n level + 1,\n baseColor,\n childIndex,\n node.children?.length || 0,\n currentChunkPath,\n ),\n );\n\n let val = 0;\n if (sizeType === 'stat') val = node.sourceSize || 0;\n else if (sizeType === 'parsed') val = node.bundledSize || 0;\n else if (sizeType === 'gzip') val = node.gzipSize || 0;\n else if (sizeType === 'value') val = node.value || 0;\n\n // Include chunk path in nodeId for non-root nodes to ensure uniqueness across chunks\n const nodeIdString =\n level === 0\n ? node.path || node.name || ''\n : `${currentChunkPath}::${node.path || node.name || ''}`;\n const nodeId = hashString(nodeIdString);\n const isHighlighted = highlightNodeId === nodeId;\n\n const baseColorRatio =\n level === 0 ? 1 : Math.max(0.35, 1 - level * 0.15);\n const baseBorderRatio =\n level === 0 ? 1 : Math.max(0.4, 1 - level * 0.15);\n\n const siblingGradientRange = 0.15;\n const siblingRatio =\n siblingCount > 1\n ? 1 - (siblingIndex / (siblingCount - 1)) * siblingGradientRange\n : 1;\n\n const colorRatio = baseColorRatio * siblingRatio;\n const borderRatio = baseBorderRatio * siblingRatio;\n\n const nodeColor = isHighlighted\n ? '#fff5f5'\n : level === 0\n ? blendWithWhite(baseColor, 0.8)\n : blendWithWhite(baseColor, colorRatio);\n\n const nodeBorderColor = isHighlighted\n ? '#ff4d4f'\n : level === 0\n ? baseColor\n : blendWithWhite(baseColor, borderRatio);\n\n const isDark = isDarkColor(nodeColor);\n const textColor = isDark ? '#ffffff' : '#000000';\n const textBorderColor = isDark\n ? 'rgba(255, 255, 255, 0.2)'\n : 'rgba(0, 0, 0, 0.1)';\n\n const result: TreemapDataNode = {\n id: nodeId,\n name: node.name,\n value: val,\n path: node.path || node.name,\n sourceSize:\n node.sourceSize ?? (sizeType === 'stat' ? val : undefined),\n bundledSize:\n node.bundledSize ?? (sizeType === 'parsed' ? val : undefined),\n gzipSize: node.gzipSize ?? (sizeType === 'gzip' ? val : undefined),\n moduleId: node.id,\n itemStyle: {\n borderWidth: isHighlighted ? 4 : 1,\n color: nodeColor,\n borderColor: nodeBorderColor,\n ...(level === 0 && { gapWidth: 2 }),\n },\n label: {\n show: true,\n color: textColor,\n textBorderColor: textBorderColor,\n textBorderWidth: 1,\n },\n upperLabel:\n level === 0\n ? undefined\n : {\n show: true,\n color: textColor,\n },\n };\n\n if (children && children.length > 0) {\n result.children = children;\n }\n\n if (isHighlighted) {\n result.emphasis = {\n itemStyle: {\n borderColor: '#ff4d4f',\n borderWidth: 4,\n color: '#fff5f5',\n },\n };\n } else {\n // Keep the same color on hover/click to prevent color change\n result.emphasis = {\n itemStyle: {\n color: nodeColor,\n borderColor: nodeBorderColor,\n borderWidth: isHighlighted ? 4 : 1,\n },\n };\n }\n\n return result;\n }\n\n const data = treeData\n .map((item, index) =>\n convert(item, index, 0, undefined, index, treeData.length, undefined),\n )\n .filter(\n (item) =>\n (typeof item.value === 'number' ? item.value > 0 : false) ||\n (item.children && item.children.length > 0),\n );\n\n chartDataRef.current = data;\n\n setOption({\n color: TREE_COLORS,\n tooltip: {\n padding: 10,\n backgroundColor: '#fff',\n borderColor: '#eee',\n borderWidth: 1,\n textStyle: {\n color: 'rgba(0, 0, 0, 0.8)',\n },\n confine: true,\n extraCssText: 'max-width: 450px; word-wrap: break-word;',\n position: function (pos, _params, _dom, _rect, size) {\n const obj: { top: number; left?: number; right?: number } = {\n top: pos[1] + 10,\n };\n if (pos[0] < size.viewSize[0] / 2) {\n obj.left = pos[0] + 10;\n } else {\n obj.right = size.viewSize[0] - pos[0] + 10;\n }\n return obj;\n } as TooltipComponentOption['position'],\n formatter: function (\n info: CallbackDataParams & { data?: TreemapDataNode },\n ) {\n const node = info.data || {};\n let path =\n typeof node.path === 'string'\n ? node.path\n : typeof node.name === 'string'\n ? node.name\n : String(node.name ?? '');\n\n if (rootPath && path) {\n const normalizedRoot = rootPath\n .replace(/\\\\/g, '/')\n .replace(/\\/$/, '');\n const normalizedPath = path.replace(/\\\\/g, '/');\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n path = normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n path = '';\n }\n }\n\n const sourceSize =\n typeof node.sourceSize === 'number' && node.sourceSize > 0\n ? node.sourceSize\n : typeof node.value === 'number' &&\n node.value > 0 &&\n sizeType === 'stat'\n ? node.value\n : undefined;\n const bundledSize =\n typeof node.bundledSize === 'number' && node.bundledSize > 0\n ? node.bundledSize\n : undefined;\n const gzipSize =\n typeof node.gzipSize === 'number' && node.gzipSize > 0\n ? node.gzipSize\n : undefined;\n\n function makeRow(label: string, value: string, color: string) {\n return `<div class=\"${Styles['tooltip-row']}\">\n <span class=\"${Styles['tooltip-label']}\" style=\"color: ${color};\">${label}</span>\n <span style=\"color: ${color};\">${value}</span>\n </div>`;\n }\n\n const rows = [];\n if (sourceSize !== undefined && sourceSize > 0) {\n rows.push(\n makeRow('Stat size', formatSize(sourceSize), '#52c41a'),\n );\n }\n if (bundledSize !== undefined && bundledSize > 0) {\n rows.push(\n makeRow('Parsed size', formatSize(bundledSize), '#d96420'),\n );\n }\n if (gzipSize !== undefined && gzipSize > 0) {\n rows.push(\n makeRow('Gzipped size', formatSize(gzipSize), '#1677ff'),\n );\n }\n\n return `\n <div style=\"font-family: sans-serif; font-size: 12px; line-height: 1.5;\">\n <div style=\"margin-bottom: 6px; max-width: 400px; word-wrap: break-word; overflow-wrap: break-word; word-break: break-all; white-space: normal; color: rgba(0, 0, 0, 0.8);\">${echarts.format.encodeHTML(path)}</div>\n ${rows.join('')}\n </div>\n `;\n },\n } as TooltipComponentOption,\n series: [\n {\n type: 'treemap',\n itemStyle: {\n gapColor: '#ffffff',\n },\n label: {\n show: true,\n formatter: '{b}',\n fontSize: 12,\n position: 'inside',\n fontWeight: 'normal',\n textBorderWidth: 1,\n padding: [4, 8, 4, 8],\n },\n upperLabel: {\n show: true,\n height: 30,\n fontSize: 12,\n fontWeight: 'normal',\n padding: [0, 0, 0, 4],\n },\n levels: getLevelOption(),\n data: data,\n breadcrumb: {\n show: true,\n left: 'center',\n top: 'bottom',\n height: 22,\n emptyItemWidth: 25,\n itemStyle: {\n color: '#999',\n borderColor: 'transparent',\n borderWidth: 0,\n borderRadius: 0,\n },\n emphasis: {\n itemStyle: {\n color: '#333',\n },\n },\n textStyle: {\n fontFamily: 'sans-serif',\n fontSize: 12,\n color: '#666',\n },\n },\n roam: true,\n nodeClick: false,\n zoomToNodeRatio: 0.7,\n animationDurationUpdate: 500,\n width: '100%',\n height: '100%',\n top: -10,\n bottom: 30,\n left: 0,\n right: 0,\n zoomLimit: {\n min: 0.5,\n max: 5,\n },\n } as TreemapSeriesOption,\n ],\n });\n }, [treeData, sizeType, highlightNodeId, rootPath]);\n\n useEffect(() => {\n if (centerNodeId && chartRef.current && option) {\n const chartInstance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n if (chartInstance) {\n const findNodeInfo = (\n data: TreemapDataNode[],\n targetId: number,\n path: string[] = [],\n ): { name: string; path: string[] } | null => {\n for (const item of data) {\n const itemName =\n typeof item.name === 'string'\n ? item.name\n : String(item.name ?? '');\n const currentPath = [...path, itemName];\n if (item.id === targetId) {\n return { name: itemName, path: currentPath };\n }\n if (item.children) {\n const found = findNodeInfo(\n item.children,\n targetId,\n currentPath,\n );\n if (found) return found;\n }\n }\n return null;\n };\n\n setTimeout(() => {\n const nodeInfo = findNodeInfo(chartDataRef.current, centerNodeId);\n if (!nodeInfo) return;\n const nodeName = nodeInfo.name;\n\n try {\n chartInstance.dispatchAction({\n type: 'highlight',\n seriesIndex: 0,\n name: nodeName,\n });\n } catch (e) {\n console.error('Failed to highlight node with name:', nodeName, e);\n }\n\n const zoomStrategies: Array<() => void> = [\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(centerNodeId),\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeName,\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path.join('/'),\n }),\n () =>\n nodeInfo.path.length > 0 &&\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path[nodeInfo.path.length - 1],\n }),\n ];\n\n for (const strategy of zoomStrategies) {\n try {\n strategy();\n return;\n } catch (e) {\n console.error(\n 'Failed to zoom to node with id:',\n centerNodeId,\n e,\n );\n }\n }\n\n console.warn('Failed to zoom to node with id:', centerNodeId);\n }, 200);\n }\n }\n }, [centerNodeId, option]);\n\n useEffect(() => {\n return () => {\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n };\n }, []);\n\n return option ? (\n <div className={Styles['chart-container']} style={style}>\n <Alert\n message=\"If parsed size lacks detailed module information, you can enable sourceMap when RSDOCTOR = true. This is because Rsdoctor relies on SourceMap to obtain Parsed Size. Rspack provides SourceMap information to Rsdoctor by default without affecting the build output.\"\n type=\"info\"\n showIcon\n style={{ marginBottom: 0 }}\n />\n <EChartsReactCore\n ref={chartRef}\n option={option}\n echarts={echarts}\n onEvents={{\n click: (params: ECElementEvent) => {\n // Delay to differentiate from double-click; only zoom on single click\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n clickTimeoutRef.current = window.setTimeout(() => {\n if (chartRef.current) {\n const instance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n const data = params?.data as TreemapDataNode | undefined;\n if (instance && data?.id !== undefined) {\n instance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(data.id),\n });\n }\n }\n }, 180);\n },\n dblclick: (params: ECElementEvent) => {\n // Double click: cancel pending single-click action and trigger analyze\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n clickTimeoutRef.current = null;\n }\n onChartClick?.(params);\n },\n }}\n style={{\n width: '100%',\n height: '100%',\n }}\n />\n </div>\n ) : null;\n },\n);\n\nexport const AssetTreemapWithFilter: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n}> = ({ treeData, onChartClick, bundledSize = true }) => {\n return (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetProjectInfo}>\n {(projectInfo) => {\n return (\n <AssetTreemapWithFilterInner\n treeData={treeData}\n onChartClick={onChartClick}\n bundledSize={bundledSize}\n rootPath={projectInfo.root}\n />\n );\n }}\n </ServerAPIProvider>\n );\n};\n\nconst AssetTreemapWithFilterInner: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n rootPath: string;\n}> = ({ treeData, onChartClick, bundledSize = true, rootPath }) => {\n const assetNames = useMemo(\n () => treeData.map((item) => item.name),\n [treeData],\n );\n\n const [checkedAssets, setCheckedAssets] = useState<string[]>(assetNames);\n const [collapsed, setCollapsed] = useState(false);\n const [sizeType, setSizeType] = useState<SizeType>(\n bundledSize ? 'parsed' : 'stat',\n );\n const [searchQuery, setSearchQuery] = useState('');\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [highlightNodeId, setHighlightNodeId] = useState<number | undefined>();\n const [centerNodeId, setCenterNodeId] = useState<number | undefined>();\n const [moduleId, setModuleId] = useState<string | number>('');\n const [showAnalyze, setShowAnalyze] = useState(false);\n const [chunkSearchQuery, setChunkSearchQuery] = useState('');\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const handleChartClick = useCallback(\n (params: ECElementEvent) => {\n onChartClick?.(params);\n const data = params.data as TreemapDataNode | undefined;\n const moduleId = data?.moduleId;\n if (moduleId !== undefined) {\n setModuleId(moduleId);\n setShowAnalyze(true);\n }\n },\n [onChartClick],\n );\n\n const enterFullscreen = useCallback(() => {\n if (containerRef.current) {\n const el = containerRef.current as HTMLElement & {\n webkitRequestFullscreen?: () => void;\n mozRequestFullScreen?: () => void;\n msRequestFullscreen?: () => void;\n };\n if (el.requestFullscreen) {\n el.requestFullscreen()\n .then(() => setIsFullscreen(true))\n .catch((err: unknown) =>\n console.error('Failed to enter fullscreen:', err),\n );\n } else if (el.webkitRequestFullscreen) {\n try {\n el.webkitRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (webkit):', err);\n }\n } else if (el.mozRequestFullScreen) {\n try {\n el.mozRequestFullScreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (moz):', err);\n }\n } else if (el.msRequestFullscreen) {\n try {\n el.msRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (ms):', err);\n }\n } else {\n console.error('Fullscreen API is not supported in this browser.');\n }\n }\n }, []);\n\n const exitFullscreen = useCallback(() => {\n document\n .exitFullscreen()\n .then(() => setIsFullscreen(false))\n .catch((err) => console.error('Failed to exit fullscreen:', err));\n }, []);\n\n const toggleFullscreen = useCallback(() => {\n if (isFullscreen) {\n exitFullscreen();\n } else {\n enterFullscreen();\n }\n }, [isFullscreen, enterFullscreen, exitFullscreen]);\n\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n const filteredTreeData = useMemo(() => {\n let filtered = treeData.filter((item) => checkedAssets.includes(item.name));\n\n if (chunkSearchQuery.trim()) {\n const searchLower = chunkSearchQuery.toLowerCase();\n filtered = filtered.filter((item) =>\n item.name.toLowerCase().includes(searchLower),\n );\n }\n\n return filtered;\n }, [treeData, checkedAssets, chunkSearchQuery]);\n\n const searchResults = useMemo(() => {\n if (!searchQuery.trim()) return [];\n\n const regex = new RegExp(searchQuery, 'i');\n const results: Array<{ path: string; nodeId: number }> = [];\n\n const collectMatchingPaths = (node: TreeNode, chunkPath?: string) => {\n // For chunk level (root of filteredTreeData), use its path/name as chunkPath\n const currentChunkPath = chunkPath || node.path || node.name || '';\n\n if (node.path && regex.test(node.path)) {\n // Use the same nodeId calculation as in convert function\n const nodeIdString = chunkPath\n ? `${chunkPath}::${node.path}`\n : node.path;\n const nodeId = hashString(nodeIdString);\n results.push({ path: node.path, nodeId });\n }\n if (node.children) {\n node.children.forEach((child) =>\n collectMatchingPaths(child, currentChunkPath),\n );\n }\n };\n\n filteredTreeData.forEach((chunk) => collectMatchingPaths(chunk));\n return results;\n }, [filteredTreeData, searchQuery]);\n\n const handleSearchResultClick = useCallback((nodeId: number) => {\n setHighlightNodeId(nodeId);\n setCenterNodeId(nodeId);\n }, []);\n\n const removeRootPath = useCallback(\n (filepath: string): string => {\n if (!rootPath || !filepath) return filepath;\n const normalizedRoot = rootPath.replace(/\\\\/g, '/').replace(/\\/$/, '');\n const normalizedPath = filepath.replace(/\\\\/g, '/');\n\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n return normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n return '';\n }\n return filepath;\n },\n [rootPath],\n );\n\n const getSize = useCallback((node: TreeNode, type?: SizeType) => {\n if (type === 'stat') return node.sourceSize || 0;\n if (type === 'parsed') return node.bundledSize || 0;\n if (type === 'gzip') return node.gzipSize || 0;\n if (type === 'value') return node.value || 0;\n if (node.value) return node.value;\n return 0;\n }, []);\n\n const calculateNodeTotalSize = useCallback(\n (node: TreeNode, type: SizeType): number => {\n let size = getSize(node, type);\n\n if (node.children && node.children.length > 0) {\n const childrenSize = node.children.reduce(\n (sum, child) => sum + calculateNodeTotalSize(child, type),\n 0,\n );\n if (size === 0 || (!node.path && childrenSize > 0)) {\n size = childrenSize;\n }\n }\n\n return size;\n },\n [getSize],\n );\n\n const getChunkSize = useCallback(\n (name: string, type?: SizeType) => {\n const node = treeData.find((n) => n.name === name);\n if (!node) return 0;\n const sizeTypeToUse = type || sizeType;\n return calculateNodeTotalSize(node, sizeTypeToUse);\n },\n [treeData, sizeType, calculateNodeTotalSize],\n );\n\n return (\n <div className={Styles.treemap} ref={containerRef}>\n <button\n className={Styles['fullscreen-button']}\n onClick={toggleFullscreen}\n title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {isFullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}\n </button>\n\n <div className={`${Styles.sidebar} ${collapsed ? Styles.collapsed : ''}`}>\n <div\n className={`${Styles['sidebar-toggle']} ${collapsed ? Styles.collapsed : ''}`}\n onClick={() => setCollapsed(!collapsed)}\n >\n {collapsed ? <RightOutlined /> : <LeftOutlined />}\n </div>\n <div className={Styles['sidebar-content']}>\n <div>\n <h4>Treemap sizes</h4>\n <Radio.Group\n value={sizeType}\n onChange={(e) => setSizeType(e.target.value)}\n size=\"small\"\n buttonStyle=\"solid\"\n >\n <Radio.Button value=\"stat\">Stat</Radio.Button>\n <Radio.Button value=\"parsed\">Parsed</Radio.Button>\n <Radio.Button value=\"gzip\">Gzipped</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <h4>Show chunks</h4>\n <Input\n placeholder=\"Search chunks\"\n value={chunkSearchQuery}\n onChange={(e) => setChunkSearchQuery(e.target.value)}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n style={{ marginBottom: 8 }}\n />\n <Checkbox\n indeterminate={\n checkedAssets.length > 0 &&\n checkedAssets.length < assetNames.length\n }\n checked={checkedAssets.length === assetNames.length}\n onChange={(e) =>\n setCheckedAssets(e.target.checked ? assetNames : [])\n }\n className={Styles['all-none-checkbox']}\n >\n All\n </Checkbox>\n <div\n className={Styles['chunk-list']}\n style={{ maxHeight: 180, overflowY: 'auto' }}\n >\n {assetNames\n .filter((name) =>\n name.toLowerCase().includes(chunkSearchQuery.toLowerCase()),\n )\n .map((name) => (\n <div\n key={name}\n className={Styles['chunk-item']}\n style={{ height: 15, lineHeight: '15px' }}\n >\n <Checkbox\n checked={checkedAssets.includes(name)}\n onChange={(e) => {\n if (e.target.checked) {\n setCheckedAssets([...checkedAssets, name]);\n } else {\n setCheckedAssets(\n checkedAssets.filter((a) => a !== name),\n );\n }\n }}\n >\n <span title={name}>{name}</span>\n </Checkbox>\n <span className={Styles['size-tag']}>\n {formatSize(getChunkSize(name, sizeType))}\n </span>\n </div>\n ))}\n </div>\n </div>\n\n <div>\n <h4>Search modules</h4>\n <Input\n placeholder=\"Enter regexp\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setHighlightNodeId(undefined);\n setCenterNodeId(undefined);\n }}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n />\n {searchQuery.trim() && searchResults.length > 0 && (\n <div className={Styles['search-results']}>\n <div className={Styles['search-results-header']}>\n Found {searchResults.length} file\n {searchResults.length > 1 ? 's' : ''}\n </div>\n <div className={Styles['search-results-list']}>\n {searchResults.map((result, index) => {\n const displayPath = removeRootPath(result.path);\n return (\n <div\n key={index}\n className={Styles['search-result-item']}\n onClick={() => handleSearchResultClick(result.nodeId)}\n title={result.path}\n >\n {displayPath || result.path}\n </div>\n );\n })}\n </div>\n </div>\n )}\n {searchQuery.trim() && searchResults.length === 0 && (\n <div className={Styles['search-results-empty']}>\n No files found matching \"{searchQuery}\"\n </div>\n )}\n </div>\n </div>\n </div>\n\n <div className={Styles['chart-wrapper']}>\n <TreeMap\n treeData={filteredTreeData}\n sizeType={sizeType}\n onChartClick={handleChartClick}\n highlightNodeId={highlightNodeId}\n centerNodeId={centerNodeId}\n rootPath={rootPath}\n style={{ width: '100%', height: '100%' }}\n />\n {moduleId ? (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetAllModuleGraph}\n body={{}}\n >\n {(modules) => (\n <ModuleAnalyzeComponent\n cwd={rootPath}\n moduleId={moduleId}\n modules={modules}\n show={showAnalyze}\n setShow={setShowAnalyze}\n />\n )}\n </ServerAPIProvider>\n ) : null}\n </div>\n </div>\n );\n};\n"],"names":["echarts","TreemapChart","TooltipComponent","TitleComponent","CanvasRenderer","hashString","str","hash","i","blendWithWhite","hex","ratio","r","parseInt","g","b","blendedR","Math","blendedG","blendedB","getLuminance","rs","gs","bs","val","isDarkColor","getLevelOption","TreeMap","memo","treeData","sizeType","style","onChartClick","highlightNodeId","centerNodeId","rootPath","option","setOption","useState","chartRef","React","chartDataRef","clickTimeoutRef","useEffect","convert","node","index","level","parentColor","siblingIndex","siblingCount","chunkPath","baseColor","TREE_COLORS","currentChunkPath","children","c","childIndex","nodeIdString","nodeId","isHighlighted","baseColorRatio","baseBorderRatio","siblingGradientRange","siblingRatio","colorRatio","borderRatio","nodeColor","nodeBorderColor","isDark","textColor","textBorderColor","result","undefined","data","item","pos","_params","_dom","_rect","size","obj","info","path","String","normalizedRoot","normalizedPath","sourceSize","bundledSize","gzipSize","makeRow","label","value","color","Styles","rows","formatSize","chartInstance","findNodeInfo","targetId","itemName","currentPath","found","setTimeout","nodeInfo","nodeName","e","console","zoomStrategies","strategy","window","Alert","EChartsReactCore","params","instance","AssetTreemapWithFilter","ServerAPIProvider","SDK","projectInfo","AssetTreemapWithFilterInner","assetNames","useMemo","checkedAssets","setCheckedAssets","collapsed","setCollapsed","setSizeType","searchQuery","setSearchQuery","isFullscreen","setIsFullscreen","setHighlightNodeId","setCenterNodeId","moduleId","setModuleId","showAnalyze","setShowAnalyze","chunkSearchQuery","setChunkSearchQuery","containerRef","handleChartClick","useCallback","enterFullscreen","el","err","exitFullscreen","document","toggleFullscreen","handleFullscreenChange","filteredTreeData","filtered","searchLower","searchResults","regex","RegExp","results","collectMatchingPaths","child","chunk","handleSearchResultClick","removeRootPath","filepath","getSize","type","calculateNodeTotalSize","childrenSize","sum","getChunkSize","name","n","sizeTypeToUse","FullscreenExitOutlined","FullscreenOutlined","RightOutlined","LeftOutlined","Radio","Input","SearchOutlined","Checkbox","a","displayPath","modules","ModuleAnalyzeComponent"],"mappings":"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"}
1
+ {"version":3,"file":"components/Charts/TreeMap.mjs","sources":["../../../src/components/Charts/TreeMap.tsx"],"sourcesContent":["import React, { useEffect, useState, memo, useMemo, useCallback } from 'react';\nimport EChartsReactCore from 'echarts-for-react/esm/core';\nimport * as echarts from 'echarts/core';\nimport { TreemapChart, type TreemapSeriesOption } from 'echarts/charts';\nimport {\n TooltipComponent,\n TitleComponent,\n type TooltipComponentOption,\n type TitleComponentOption,\n} from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\nimport { Alert, Checkbox, Radio, Input } from 'antd';\nimport {\n LeftOutlined,\n RightOutlined,\n SearchOutlined,\n FullscreenOutlined,\n FullscreenExitOutlined,\n} from '@ant-design/icons';\nimport type { ComposeOption, EChartsType } from 'echarts/core';\nimport { formatSize } from 'src/utils';\nimport { SDK } from '@rsdoctor/types';\nimport { ServerAPIProvider } from 'src/components/Manifest';\nimport { ModuleAnalyzeComponent } from '../../pages/ModuleAnalyze';\nimport Styles from './treemap.module.scss';\nimport { TREE_COLORS } from './constants';\nimport { isJavaScriptAsset } from '../../utils/assets';\nimport type {\n CallbackDataParams,\n ECElementEvent,\n} from 'echarts/types/dist/shared';\n\ntype TreeMapOption = ComposeOption<\n TreemapSeriesOption | TooltipComponentOption | TitleComponentOption\n>;\n\ntype TreemapDataNode = NonNullable<TreemapSeriesOption['data']>[number] & {\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n moduleId?: string | number;\n};\n\necharts.use([TreemapChart, TooltipComponent, TitleComponent, CanvasRenderer]);\n\nexport type TreeNode = {\n name: string;\n value?: number;\n children?: TreeNode[];\n path?: string;\n sourceSize?: number;\n bundledSize?: number;\n gzipSize?: number;\n id?: string | number;\n};\n\nexport type SizeType = 'stat' | 'parsed' | 'gzip' | 'value';\n\ninterface TreeMapProps {\n treeData: TreeNode[];\n sizeType: SizeType;\n style?: React.CSSProperties;\n onChartClick?: (params: ECElementEvent) => void;\n highlightNodeId?: number;\n centerNodeId?: number;\n rootPath?: string;\n}\n\nfunction hashString(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash << 5) + hash + str.charCodeAt(i);\n }\n return hash >>> 0;\n}\n\nfunction blendWithWhite(hex: string, ratio: number): string {\n const r = parseInt(hex.slice(1, 3), 16);\n const g = parseInt(hex.slice(3, 5), 16);\n const b = parseInt(hex.slice(5, 7), 16);\n\n const blendedR = Math.round(r * ratio + 255 * (1 - ratio));\n const blendedG = Math.round(g * ratio + 255 * (1 - ratio));\n const blendedB = Math.round(b * ratio + 255 * (1 - ratio));\n\n return `#${blendedR.toString(16).padStart(2, '0')}${blendedG.toString(16).padStart(2, '0')}${blendedB.toString(16).padStart(2, '0')}`;\n}\n\nfunction getLuminance(hex: string): number {\n const r = parseInt(hex.slice(1, 3), 16) / 255;\n const g = parseInt(hex.slice(3, 5), 16) / 255;\n const b = parseInt(hex.slice(5, 7), 16) / 255;\n\n const [rs, gs, bs] = [r, g, b].map((val) => {\n return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);\n });\n\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n}\n\nfunction isDarkColor(hex: string): boolean {\n return getLuminance(hex) < 0.4;\n}\n\nfunction getLevelOption() {\n return [\n {\n itemStyle: {\n borderWidth: 0,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n },\n {\n itemStyle: {\n borderColorAlpha: [1, 0.3],\n borderWidth: 5,\n gapWidth: 4,\n gapColor: '#ffffff',\n },\n upperLabel: {\n show: true,\n color: '#ffffff',\n fontSize: 12,\n height: 30,\n },\n },\n ];\n}\n\nexport const TreeMap: React.FC<TreeMapProps> = memo(\n ({\n treeData,\n sizeType,\n style,\n onChartClick,\n highlightNodeId,\n centerNodeId,\n rootPath,\n }) => {\n const [option, setOption] = useState<TreeMapOption | null>(null);\n const chartRef = React.useRef<EChartsReactCore | null>(null);\n const chartDataRef = React.useRef<TreemapDataNode[]>([]);\n const clickTimeoutRef = React.useRef<number | null>(null);\n\n useEffect(() => {\n if (!treeData) return;\n function convert(\n node: TreeNode,\n index = 0,\n level = 0,\n parentColor?: string,\n siblingIndex = 0,\n siblingCount = 1,\n chunkPath?: string,\n ): TreemapDataNode {\n const baseColor =\n parentColor || TREE_COLORS[index % TREE_COLORS.length];\n\n // For level 0 (chunk level), use the chunk's path/name as chunkPath\n const currentChunkPath =\n level === 0 ? node.path || node.name || '' : chunkPath || '';\n\n const children = node.children?.map((c, childIndex) =>\n convert(\n c,\n index,\n level + 1,\n baseColor,\n childIndex,\n node.children?.length || 0,\n currentChunkPath,\n ),\n );\n\n let val = 0;\n if (sizeType === 'stat') val = node.sourceSize || 0;\n else if (sizeType === 'parsed') val = node.bundledSize || 0;\n else if (sizeType === 'gzip') val = node.gzipSize || 0;\n else if (sizeType === 'value') val = node.value || 0;\n\n // Include chunk path in nodeId for non-root nodes to ensure uniqueness across chunks\n const nodeIdString =\n level === 0\n ? node.path || node.name || ''\n : `${currentChunkPath}::${node.path || node.name || ''}`;\n const nodeId = hashString(nodeIdString);\n const isHighlighted = highlightNodeId === nodeId;\n\n const baseColorRatio =\n level === 0 ? 1 : Math.max(0.35, 1 - level * 0.15);\n const baseBorderRatio =\n level === 0 ? 1 : Math.max(0.4, 1 - level * 0.15);\n\n const siblingGradientRange = 0.15;\n const siblingRatio =\n siblingCount > 1\n ? 1 - (siblingIndex / (siblingCount - 1)) * siblingGradientRange\n : 1;\n\n const colorRatio = baseColorRatio * siblingRatio;\n const borderRatio = baseBorderRatio * siblingRatio;\n\n const nodeColor = isHighlighted\n ? '#fff5f5'\n : level === 0\n ? blendWithWhite(baseColor, 0.8)\n : blendWithWhite(baseColor, colorRatio);\n\n const nodeBorderColor = isHighlighted\n ? '#ff4d4f'\n : level === 0\n ? baseColor\n : blendWithWhite(baseColor, borderRatio);\n\n const isDark = isDarkColor(nodeColor);\n const textColor = isDark ? '#ffffff' : '#000000';\n const textBorderColor = isDark\n ? 'rgba(255, 255, 255, 0.2)'\n : 'rgba(0, 0, 0, 0.1)';\n\n const result: TreemapDataNode = {\n id: nodeId,\n name: node.name,\n value: val,\n path: node.path || node.name,\n sourceSize:\n node.sourceSize ?? (sizeType === 'stat' ? val : undefined),\n bundledSize:\n node.bundledSize ?? (sizeType === 'parsed' ? val : undefined),\n gzipSize: node.gzipSize ?? (sizeType === 'gzip' ? val : undefined),\n moduleId: node.id,\n itemStyle: {\n borderWidth: isHighlighted ? 4 : 1,\n color: nodeColor,\n borderColor: nodeBorderColor,\n ...(level === 0 && { gapWidth: 2 }),\n },\n label: {\n show: true,\n color: textColor,\n textBorderColor: textBorderColor,\n textBorderWidth: 1,\n },\n upperLabel:\n level === 0\n ? undefined\n : {\n show: true,\n color: textColor,\n },\n };\n\n if (children && children.length > 0) {\n result.children = children;\n }\n\n if (isHighlighted) {\n result.emphasis = {\n itemStyle: {\n borderColor: '#ff4d4f',\n borderWidth: 4,\n color: '#fff5f5',\n },\n };\n } else {\n // Keep the same color on hover/click to prevent color change\n result.emphasis = {\n itemStyle: {\n color: nodeColor,\n borderColor: nodeBorderColor,\n borderWidth: isHighlighted ? 4 : 1,\n },\n };\n }\n\n return result;\n }\n\n const data = treeData\n .map((item, index) =>\n convert(item, index, 0, undefined, index, treeData.length, undefined),\n )\n .filter(\n (item) =>\n (typeof item.value === 'number' ? item.value > 0 : false) ||\n (item.children && item.children.length > 0),\n );\n\n chartDataRef.current = data;\n\n setOption({\n color: TREE_COLORS,\n tooltip: {\n padding: 10,\n backgroundColor: '#fff',\n borderColor: '#eee',\n borderWidth: 1,\n textStyle: {\n color: 'rgba(0, 0, 0, 0.8)',\n },\n confine: true,\n extraCssText: 'max-width: 450px; word-wrap: break-word;',\n position: function (pos, _params, _dom, _rect, size) {\n const obj: { top: number; left?: number; right?: number } = {\n top: pos[1] + 10,\n };\n if (pos[0] < size.viewSize[0] / 2) {\n obj.left = pos[0] + 10;\n } else {\n obj.right = size.viewSize[0] - pos[0] + 10;\n }\n return obj;\n } as TooltipComponentOption['position'],\n formatter: function (\n info: CallbackDataParams & { data?: TreemapDataNode },\n ) {\n const node = info.data || {};\n let path =\n typeof node.path === 'string'\n ? node.path\n : typeof node.name === 'string'\n ? node.name\n : String(node.name ?? '');\n\n if (rootPath && path) {\n const normalizedRoot = rootPath\n .replace(/\\\\/g, '/')\n .replace(/\\/$/, '');\n const normalizedPath = path.replace(/\\\\/g, '/');\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n path = normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n path = '';\n }\n }\n\n const sourceSize =\n typeof node.sourceSize === 'number' && node.sourceSize > 0\n ? node.sourceSize\n : typeof node.value === 'number' &&\n node.value > 0 &&\n sizeType === 'stat'\n ? node.value\n : undefined;\n const bundledSize =\n typeof node.bundledSize === 'number' && node.bundledSize > 0\n ? node.bundledSize\n : undefined;\n const gzipSize =\n typeof node.gzipSize === 'number' && node.gzipSize > 0\n ? node.gzipSize\n : undefined;\n\n function makeRow(label: string, value: string, color: string) {\n return `<div class=\"${Styles['tooltip-row']}\">\n <span class=\"${Styles['tooltip-label']}\" style=\"color: ${color};\">${label}</span>\n <span style=\"color: ${color};\">${value}</span>\n </div>`;\n }\n\n const rows = [];\n if (sourceSize !== undefined && sourceSize > 0) {\n rows.push(\n makeRow('Stat size', formatSize(sourceSize), '#52c41a'),\n );\n }\n if (bundledSize !== undefined && bundledSize > 0) {\n rows.push(\n makeRow('Parsed size', formatSize(bundledSize), '#d96420'),\n );\n }\n if (gzipSize !== undefined && gzipSize > 0) {\n rows.push(\n makeRow('Gzipped size', formatSize(gzipSize), '#1677ff'),\n );\n }\n\n return `\n <div style=\"font-family: sans-serif; font-size: 12px; line-height: 1.5;\">\n <div style=\"margin-bottom: 6px; max-width: 400px; word-wrap: break-word; overflow-wrap: break-word; word-break: break-all; white-space: normal; color: rgba(0, 0, 0, 0.8);\">${echarts.format.encodeHTML(path)}</div>\n ${rows.join('')}\n </div>\n `;\n },\n } as TooltipComponentOption,\n series: [\n {\n type: 'treemap',\n itemStyle: {\n gapColor: '#ffffff',\n },\n label: {\n show: true,\n formatter: '{b}',\n fontSize: 12,\n position: 'inside',\n fontWeight: 'normal',\n textBorderWidth: 1,\n padding: [4, 8, 4, 8],\n },\n upperLabel: {\n show: true,\n height: 30,\n fontSize: 12,\n fontWeight: 'normal',\n padding: [0, 0, 0, 4],\n },\n levels: getLevelOption(),\n data: data,\n breadcrumb: {\n show: true,\n left: 'center',\n top: 'bottom',\n height: 22,\n emptyItemWidth: 25,\n itemStyle: {\n color: '#999',\n borderColor: 'transparent',\n borderWidth: 0,\n borderRadius: 0,\n },\n emphasis: {\n itemStyle: {\n color: '#333',\n },\n },\n textStyle: {\n fontFamily: 'sans-serif',\n fontSize: 12,\n color: '#666',\n },\n },\n roam: true,\n nodeClick: false,\n zoomToNodeRatio: 0.7,\n animationDurationUpdate: 500,\n width: '100%',\n height: '100%',\n top: -10,\n bottom: 30,\n left: 0,\n right: 0,\n zoomLimit: {\n min: 0.5,\n max: 5,\n },\n } as TreemapSeriesOption,\n ],\n });\n }, [treeData, sizeType, highlightNodeId, rootPath]);\n\n useEffect(() => {\n if (centerNodeId && chartRef.current && option) {\n const chartInstance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n if (chartInstance) {\n const findNodeInfo = (\n data: TreemapDataNode[],\n targetId: number,\n path: string[] = [],\n ): { name: string; path: string[] } | null => {\n for (const item of data) {\n const itemName =\n typeof item.name === 'string'\n ? item.name\n : String(item.name ?? '');\n const currentPath = [...path, itemName];\n if (item.id === targetId) {\n return { name: itemName, path: currentPath };\n }\n if (item.children) {\n const found = findNodeInfo(\n item.children,\n targetId,\n currentPath,\n );\n if (found) return found;\n }\n }\n return null;\n };\n\n setTimeout(() => {\n const nodeInfo = findNodeInfo(chartDataRef.current, centerNodeId);\n if (!nodeInfo) return;\n const nodeName = nodeInfo.name;\n\n try {\n chartInstance.dispatchAction({\n type: 'highlight',\n seriesIndex: 0,\n name: nodeName,\n });\n } catch (e) {\n console.error('Failed to highlight node with name:', nodeName, e);\n }\n\n const zoomStrategies: Array<() => void> = [\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(centerNodeId),\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeName,\n }),\n () =>\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path.join('/'),\n }),\n () =>\n nodeInfo.path.length > 0 &&\n chartInstance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n name: nodeInfo.path[nodeInfo.path.length - 1],\n }),\n ];\n\n for (const strategy of zoomStrategies) {\n try {\n strategy();\n return;\n } catch (e) {\n console.error(\n 'Failed to zoom to node with id:',\n centerNodeId,\n e,\n );\n }\n }\n\n console.warn('Failed to zoom to node with id:', centerNodeId);\n }, 200);\n }\n }\n }, [centerNodeId, option]);\n\n useEffect(() => {\n return () => {\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n };\n }, []);\n\n return option ? (\n <div className={Styles['chart-container']} style={style}>\n <Alert\n message=\"If parsed size lacks detailed module information, you can enable sourceMap when RSDOCTOR = true. This is because Rsdoctor relies on SourceMap to obtain Parsed Size. Rspack provides SourceMap information to Rsdoctor by default without affecting the build output.\"\n type=\"info\"\n showIcon\n style={{ marginBottom: 0 }}\n />\n <EChartsReactCore\n ref={chartRef}\n option={option}\n echarts={echarts}\n onEvents={{\n click: (params: ECElementEvent) => {\n // Delay to differentiate from double-click; only zoom on single click\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n }\n clickTimeoutRef.current = window.setTimeout(() => {\n if (chartRef.current) {\n const instance =\n chartRef.current.getEchartsInstance() as unknown as EChartsType;\n const data = params?.data as TreemapDataNode | undefined;\n if (instance && data?.id !== undefined) {\n instance.dispatchAction({\n type: 'treemapZoomToNode',\n seriesIndex: 0,\n targetNodeId: String(data.id),\n });\n }\n }\n }, 180);\n },\n dblclick: (params: ECElementEvent) => {\n // Double click: cancel pending single-click action and trigger analyze\n if (clickTimeoutRef.current) {\n window.clearTimeout(clickTimeoutRef.current);\n clickTimeoutRef.current = null;\n }\n onChartClick?.(params);\n },\n }}\n style={{\n width: '100%',\n height: '100%',\n }}\n />\n </div>\n ) : null;\n },\n);\n\nexport const AssetTreemapWithFilter: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n}> = ({ treeData, onChartClick, bundledSize = true }) => {\n return (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetProjectInfo}>\n {(projectInfo) => {\n return (\n <AssetTreemapWithFilterInner\n treeData={treeData}\n onChartClick={onChartClick}\n bundledSize={bundledSize}\n rootPath={projectInfo.root}\n />\n );\n }}\n </ServerAPIProvider>\n );\n};\n\nconst AssetTreemapWithFilterInner: React.FC<{\n treeData: TreeNode[];\n onChartClick?: (params: ECElementEvent) => void;\n bundledSize?: boolean;\n rootPath: string;\n}> = ({ treeData, onChartClick, bundledSize = true, rootPath }) => {\n const assetNames = useMemo(\n () => treeData.map((item) => item.name),\n [treeData],\n );\n\n const [checkedAssets, setCheckedAssets] = useState<string[]>(assetNames);\n const [collapsed, setCollapsed] = useState(false);\n const [sizeType, setSizeType] = useState<SizeType>(\n bundledSize ? 'parsed' : 'stat',\n );\n const [searchQuery, setSearchQuery] = useState('');\n const [isFullscreen, setIsFullscreen] = useState(false);\n const [highlightNodeId, setHighlightNodeId] = useState<number | undefined>();\n const [centerNodeId, setCenterNodeId] = useState<number | undefined>();\n const [moduleId, setModuleId] = useState<string | number>('');\n const [showAnalyze, setShowAnalyze] = useState(false);\n const [chunkSearchQuery, setChunkSearchQuery] = useState('');\n const [showOnlyJavaScriptAssets, setShowOnlyJavaScriptAssets] =\n useState(false);\n\n const containerRef = React.useRef<HTMLDivElement>(null);\n\n const visibleAssetNames = useMemo(() => {\n if (!showOnlyJavaScriptAssets) {\n return assetNames;\n }\n\n return assetNames.filter(isJavaScriptAsset);\n }, [assetNames, showOnlyJavaScriptAssets]);\n\n const visibleAssetNamesKey = useMemo(\n () => visibleAssetNames.join('\\0'),\n [visibleAssetNames],\n );\n const previousVisibleAssetNamesKeyRef = React.useRef<string | undefined>(\n undefined,\n );\n\n useEffect(() => {\n if (previousVisibleAssetNamesKeyRef.current === visibleAssetNamesKey) {\n return;\n }\n\n previousVisibleAssetNamesKeyRef.current = visibleAssetNamesKey;\n setCheckedAssets(visibleAssetNames);\n }, [visibleAssetNames, visibleAssetNamesKey]);\n\n const handleChartClick = useCallback(\n (params: ECElementEvent) => {\n onChartClick?.(params);\n const data = params.data as TreemapDataNode | undefined;\n const moduleId = data?.moduleId;\n if (moduleId !== undefined) {\n setModuleId(moduleId);\n setShowAnalyze(true);\n }\n },\n [onChartClick],\n );\n\n const enterFullscreen = useCallback(() => {\n if (containerRef.current) {\n const el = containerRef.current as HTMLElement & {\n webkitRequestFullscreen?: () => void;\n mozRequestFullScreen?: () => void;\n msRequestFullscreen?: () => void;\n };\n if (el.requestFullscreen) {\n el.requestFullscreen()\n .then(() => setIsFullscreen(true))\n .catch((err: unknown) =>\n console.error('Failed to enter fullscreen:', err),\n );\n } else if (el.webkitRequestFullscreen) {\n try {\n el.webkitRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (webkit):', err);\n }\n } else if (el.mozRequestFullScreen) {\n try {\n el.mozRequestFullScreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (moz):', err);\n }\n } else if (el.msRequestFullscreen) {\n try {\n el.msRequestFullscreen();\n setIsFullscreen(true);\n } catch (err) {\n console.error('Failed to enter fullscreen (ms):', err);\n }\n } else {\n console.error('Fullscreen API is not supported in this browser.');\n }\n }\n }, []);\n\n const exitFullscreen = useCallback(() => {\n document\n .exitFullscreen()\n .then(() => setIsFullscreen(false))\n .catch((err) => console.error('Failed to exit fullscreen:', err));\n }, []);\n\n const toggleFullscreen = useCallback(() => {\n if (isFullscreen) {\n exitFullscreen();\n } else {\n enterFullscreen();\n }\n }, [isFullscreen, enterFullscreen, exitFullscreen]);\n\n useEffect(() => {\n const handleFullscreenChange = () => {\n setIsFullscreen(!!document.fullscreenElement);\n };\n document.addEventListener('fullscreenchange', handleFullscreenChange);\n return () => {\n document.removeEventListener('fullscreenchange', handleFullscreenChange);\n };\n }, []);\n\n const filteredTreeData = useMemo(() => {\n let filtered = treeData.filter(\n (item) =>\n visibleAssetNames.includes(item.name) &&\n checkedAssets.includes(item.name),\n );\n\n if (chunkSearchQuery.trim()) {\n const searchLower = chunkSearchQuery.toLowerCase();\n filtered = filtered.filter((item) =>\n item.name.toLowerCase().includes(searchLower),\n );\n }\n\n return filtered;\n }, [treeData, checkedAssets, chunkSearchQuery, visibleAssetNames]);\n\n const searchResults = useMemo(() => {\n if (!searchQuery.trim()) return [];\n\n const regex = new RegExp(searchQuery, 'i');\n const results: Array<{ path: string; nodeId: number }> = [];\n\n const collectMatchingPaths = (node: TreeNode, chunkPath?: string) => {\n // For chunk level (root of filteredTreeData), use its path/name as chunkPath\n const currentChunkPath = chunkPath || node.path || node.name || '';\n\n if (node.path && regex.test(node.path)) {\n // Use the same nodeId calculation as in convert function\n const nodeIdString = chunkPath\n ? `${chunkPath}::${node.path}`\n : node.path;\n const nodeId = hashString(nodeIdString);\n results.push({ path: node.path, nodeId });\n }\n if (node.children) {\n node.children.forEach((child) =>\n collectMatchingPaths(child, currentChunkPath),\n );\n }\n };\n\n filteredTreeData.forEach((chunk) => collectMatchingPaths(chunk));\n return results;\n }, [filteredTreeData, searchQuery]);\n\n const handleSearchResultClick = useCallback((nodeId: number) => {\n setHighlightNodeId(nodeId);\n setCenterNodeId(nodeId);\n }, []);\n\n const removeRootPath = useCallback(\n (filepath: string): string => {\n if (!rootPath || !filepath) return filepath;\n const normalizedRoot = rootPath.replace(/\\\\/g, '/').replace(/\\/$/, '');\n const normalizedPath = filepath.replace(/\\\\/g, '/');\n\n if (normalizedPath.startsWith(normalizedRoot + '/')) {\n return normalizedPath.slice(normalizedRoot.length + 1);\n } else if (normalizedPath === normalizedRoot) {\n return '';\n }\n return filepath;\n },\n [rootPath],\n );\n\n const getSize = useCallback((node: TreeNode, type?: SizeType) => {\n if (type === 'stat') return node.sourceSize || 0;\n if (type === 'parsed') return node.bundledSize || 0;\n if (type === 'gzip') return node.gzipSize || 0;\n if (type === 'value') return node.value || 0;\n if (node.value) return node.value;\n return 0;\n }, []);\n\n const calculateNodeTotalSize = useCallback(\n (node: TreeNode, type: SizeType): number => {\n let size = getSize(node, type);\n\n if (node.children && node.children.length > 0) {\n const childrenSize = node.children.reduce(\n (sum, child) => sum + calculateNodeTotalSize(child, type),\n 0,\n );\n if (size === 0 || (!node.path && childrenSize > 0)) {\n size = childrenSize;\n }\n }\n\n return size;\n },\n [getSize],\n );\n\n const getChunkSize = useCallback(\n (name: string, type?: SizeType) => {\n const node = treeData.find((n) => n.name === name);\n if (!node) return 0;\n const sizeTypeToUse = type || sizeType;\n return calculateNodeTotalSize(node, sizeTypeToUse);\n },\n [treeData, sizeType, calculateNodeTotalSize],\n );\n\n return (\n <div className={Styles.treemap} ref={containerRef}>\n <button\n className={Styles['fullscreen-button']}\n onClick={toggleFullscreen}\n title={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Enter fullscreen'}\n >\n {isFullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}\n </button>\n\n <div className={`${Styles.sidebar} ${collapsed ? Styles.collapsed : ''}`}>\n <div\n className={`${Styles['sidebar-toggle']} ${collapsed ? Styles.collapsed : ''}`}\n onClick={() => setCollapsed(!collapsed)}\n >\n {collapsed ? <RightOutlined /> : <LeftOutlined />}\n </div>\n <div className={Styles['sidebar-content']}>\n <div>\n <h4>Treemap sizes</h4>\n <Radio.Group\n value={sizeType}\n onChange={(e) => setSizeType(e.target.value)}\n size=\"small\"\n buttonStyle=\"solid\"\n >\n <Radio.Button value=\"stat\">Stat</Radio.Button>\n <Radio.Button value=\"parsed\">Parsed</Radio.Button>\n <Radio.Button value=\"gzip\">Gzipped</Radio.Button>\n </Radio.Group>\n </div>\n\n <div>\n <h4>Show chunks</h4>\n <Input\n placeholder=\"Search chunks\"\n value={chunkSearchQuery}\n onChange={(e) => setChunkSearchQuery(e.target.value)}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n style={{ marginBottom: 8 }}\n />\n <Checkbox\n indeterminate={\n checkedAssets.length > 0 &&\n checkedAssets.length < visibleAssetNames.length\n }\n checked={\n visibleAssetNames.length > 0 &&\n checkedAssets.length === visibleAssetNames.length\n }\n onChange={(e) =>\n setCheckedAssets(e.target.checked ? visibleAssetNames : [])\n }\n className={Styles['all-none-checkbox']}\n >\n All\n </Checkbox>\n <Checkbox\n checked={showOnlyJavaScriptAssets}\n onChange={(e) => {\n setShowOnlyJavaScriptAssets(e.target.checked);\n }}\n className={Styles['all-none-checkbox']}\n >\n JS only\n </Checkbox>\n <div\n className={Styles['chunk-list']}\n style={{ maxHeight: 180, overflowY: 'auto' }}\n >\n {visibleAssetNames\n .filter((name) =>\n name.toLowerCase().includes(chunkSearchQuery.toLowerCase()),\n )\n .map((name) => (\n <div\n key={name}\n className={Styles['chunk-item']}\n style={{ height: 15, lineHeight: '15px' }}\n >\n <Checkbox\n checked={checkedAssets.includes(name)}\n onChange={(e) => {\n if (e.target.checked) {\n setCheckedAssets([...checkedAssets, name]);\n } else {\n setCheckedAssets(\n checkedAssets.filter((a) => a !== name),\n );\n }\n }}\n >\n <span title={name}>{name}</span>\n </Checkbox>\n <span className={Styles['size-tag']}>\n {formatSize(getChunkSize(name, sizeType))}\n </span>\n </div>\n ))}\n </div>\n </div>\n\n <div>\n <h4>Search modules</h4>\n <Input\n placeholder=\"Enter regexp\"\n value={searchQuery}\n onChange={(e) => {\n setSearchQuery(e.target.value);\n setHighlightNodeId(undefined);\n setCenterNodeId(undefined);\n }}\n suffix={<SearchOutlined style={{ color: '#ccc' }} />}\n allowClear\n size=\"small\"\n />\n {searchQuery.trim() && searchResults.length > 0 && (\n <div className={Styles['search-results']}>\n <div className={Styles['search-results-header']}>\n Found {searchResults.length} file\n {searchResults.length > 1 ? 's' : ''}\n </div>\n <div className={Styles['search-results-list']}>\n {searchResults.map((result, index) => {\n const displayPath = removeRootPath(result.path);\n return (\n <div\n key={index}\n className={Styles['search-result-item']}\n onClick={() => handleSearchResultClick(result.nodeId)}\n title={result.path}\n >\n {displayPath || result.path}\n </div>\n );\n })}\n </div>\n </div>\n )}\n {searchQuery.trim() && searchResults.length === 0 && (\n <div className={Styles['search-results-empty']}>\n No files found matching \"{searchQuery}\"\n </div>\n )}\n </div>\n </div>\n </div>\n\n <div className={Styles['chart-wrapper']}>\n <TreeMap\n treeData={filteredTreeData}\n sizeType={sizeType}\n onChartClick={handleChartClick}\n highlightNodeId={highlightNodeId}\n centerNodeId={centerNodeId}\n rootPath={rootPath}\n style={{ width: '100%', height: '100%' }}\n />\n {moduleId ? (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetAllModuleGraph}\n body={{}}\n >\n {(modules) => (\n <ModuleAnalyzeComponent\n cwd={rootPath}\n moduleId={moduleId}\n modules={modules}\n show={showAnalyze}\n setShow={setShowAnalyze}\n />\n )}\n </ServerAPIProvider>\n ) : null}\n </div>\n </div>\n );\n};\n"],"names":["echarts","TreemapChart","TooltipComponent","TitleComponent","CanvasRenderer","hashString","str","hash","i","blendWithWhite","hex","ratio","r","parseInt","g","b","blendedR","Math","blendedG","blendedB","getLuminance","rs","gs","bs","val","isDarkColor","getLevelOption","TreeMap","memo","treeData","sizeType","style","onChartClick","highlightNodeId","centerNodeId","rootPath","option","setOption","useState","chartRef","React","chartDataRef","clickTimeoutRef","useEffect","convert","node","index","level","parentColor","siblingIndex","siblingCount","chunkPath","baseColor","TREE_COLORS","currentChunkPath","children","c","childIndex","nodeIdString","nodeId","isHighlighted","baseColorRatio","baseBorderRatio","siblingGradientRange","siblingRatio","colorRatio","borderRatio","nodeColor","nodeBorderColor","isDark","textColor","textBorderColor","result","undefined","data","item","pos","_params","_dom","_rect","size","obj","info","path","String","normalizedRoot","normalizedPath","sourceSize","bundledSize","gzipSize","makeRow","label","value","color","Styles","rows","formatSize","chartInstance","findNodeInfo","targetId","itemName","currentPath","found","setTimeout","nodeInfo","nodeName","e","console","zoomStrategies","strategy","window","Alert","EChartsReactCore","params","instance","AssetTreemapWithFilter","ServerAPIProvider","SDK","projectInfo","AssetTreemapWithFilterInner","assetNames","useMemo","checkedAssets","setCheckedAssets","collapsed","setCollapsed","setSizeType","searchQuery","setSearchQuery","isFullscreen","setIsFullscreen","setHighlightNodeId","setCenterNodeId","moduleId","setModuleId","showAnalyze","setShowAnalyze","chunkSearchQuery","setChunkSearchQuery","showOnlyJavaScriptAssets","setShowOnlyJavaScriptAssets","containerRef","visibleAssetNames","isJavaScriptAsset","visibleAssetNamesKey","previousVisibleAssetNamesKeyRef","handleChartClick","useCallback","enterFullscreen","el","err","exitFullscreen","document","toggleFullscreen","handleFullscreenChange","filteredTreeData","filtered","searchLower","searchResults","regex","RegExp","results","collectMatchingPaths","child","chunk","handleSearchResultClick","removeRootPath","filepath","getSize","type","calculateNodeTotalSize","childrenSize","sum","getChunkSize","name","n","sizeTypeToUse","FullscreenExitOutlined","FullscreenOutlined","RightOutlined","LeftOutlined","Radio","Input","SearchOutlined","Checkbox","a","displayPath","modules","ModuleAnalyzeComponent"],"mappings":";;;;;;;;;;;;;;;;AA4CAA,wCAAAA,GAAW,CAAC;IAACC;IAAcC;IAAkBC;IAAgBC;CAAe;AAyB5E,SAASC,WAAWC,GAAW;IAC7B,IAAIC,OAAO;IACX,IAAK,IAAIC,IAAI,GAAGA,IAAIF,IAAI,MAAM,EAAEE,IAC9BD,OAAQA,AAAAA,CAAAA,QAAQ,KAAKA,OAAOD,IAAI,UAAU,CAACE;IAE7C,OAAOD,SAAS;AAClB;AAEA,SAASE,eAAeC,GAAW,EAAEC,KAAa;IAChD,MAAMC,IAAIC,SAASH,IAAI,KAAK,CAAC,GAAG,IAAI;IACpC,MAAMI,IAAID,SAASH,IAAI,KAAK,CAAC,GAAG,IAAI;IACpC,MAAMK,IAAIF,SAASH,IAAI,KAAK,CAAC,GAAG,IAAI;IAEpC,MAAMM,WAAWC,KAAK,KAAK,CAACL,IAAID,QAAQ,MAAO,KAAIA,KAAI;IACvD,MAAMO,WAAWD,KAAK,KAAK,CAACH,IAAIH,QAAQ,MAAO,KAAIA,KAAI;IACvD,MAAMQ,WAAWF,KAAK,KAAK,CAACF,IAAIJ,QAAQ,MAAO,KAAIA,KAAI;IAEvD,OAAO,CAAC,CAAC,EAAEK,SAAS,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,OAAOE,SAAS,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,OAAOC,SAAS,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,MAAM;AACvI;AAEA,SAASC,aAAaV,GAAW;IAC/B,MAAME,IAAIC,SAASH,IAAI,KAAK,CAAC,GAAG,IAAI,MAAM;IAC1C,MAAMI,IAAID,SAASH,IAAI,KAAK,CAAC,GAAG,IAAI,MAAM;IAC1C,MAAMK,IAAIF,SAASH,IAAI,KAAK,CAAC,GAAG,IAAI,MAAM;IAE1C,MAAM,CAACW,IAAIC,IAAIC,GAAG,GAAG;QAACX;QAAGE;QAAGC;KAAE,CAAC,GAAG,CAAC,CAACS,MAC3BA,OAAO,UAAUA,MAAM,QAAQP,KAAK,GAAG,CAAEO,AAAAA,CAAAA,MAAM,KAAI,IAAK,OAAO;IAGxE,OAAO,SAASH,KAAK,SAASC,KAAK,SAASC;AAC9C;AAEA,SAASE,YAAYf,GAAW;IAC9B,OAAOU,aAAaV,OAAO;AAC7B;AAEA,SAASgB;IACP,OAAO;QACL;YACE,WAAW;gBACT,aAAa;gBACb,UAAU;gBACV,UAAU;YACZ;QACF;QACA;YACE,WAAW;gBACT,kBAAkB;oBAAC;oBAAG;iBAAI;gBAC1B,aAAa;gBACb,UAAU;gBACV,UAAU;YACZ;YACA,YAAY;gBACV,MAAM;gBACN,OAAO;gBACP,UAAU;gBACV,QAAQ;YACV;QACF;KACD;AACH;AAEO,MAAMC,UAAOA,WAAAA,GAA2BC,KAC7C,CAAC,EACCC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,YAAY,EACZC,eAAe,EACfC,YAAY,EACZC,QAAQ,EACT;IACC,MAAM,CAACC,QAAQC,UAAU,GAAGC,SAA+B;IAC3D,MAAMC,WAAWC,MAAAA,MAAY,CAA0B;IACvD,MAAMC,eAAeD,MAAAA,MAAY,CAAoB,EAAE;IACvD,MAAME,kBAAkBF,MAAAA,MAAY,CAAgB;IAEpDG,UAAU;QACR,IAAI,CAACd,UAAU;QACf,SAASe,QACPC,IAAc,EACdC,QAAQ,CAAC,EACTC,QAAQ,CAAC,EACTC,WAAoB,EACpBC,eAAe,CAAC,EAChBC,eAAe,CAAC,EAChBC,SAAkB;YAElB,MAAMC,YACJJ,eAAeK,WAAW,CAACP,QAAQO,YAAY,MAAM,CAAC;YAGxD,MAAMC,mBACJP,AAAU,MAAVA,QAAcF,KAAK,IAAI,IAAIA,KAAK,IAAI,IAAI,KAAKM,aAAa;YAE5D,MAAMI,WAAWV,KAAK,QAAQ,EAAE,IAAI,CAACW,GAAGC,aACtCb,QACEY,GACAV,OACAC,QAAQ,GACRK,WACAK,YACAZ,KAAK,QAAQ,EAAE,UAAU,GACzBS;YAIJ,IAAI9B,MAAM;YACV,IAAIM,AAAa,WAAbA,UAAqBN,MAAMqB,KAAK,UAAU,IAAI;iBAC7C,IAAIf,AAAa,aAAbA,UAAuBN,MAAMqB,KAAK,WAAW,IAAI;iBACrD,IAAIf,AAAa,WAAbA,UAAqBN,MAAMqB,KAAK,QAAQ,IAAI;iBAChD,IAAIf,AAAa,YAAbA,UAAsBN,MAAMqB,KAAK,KAAK,IAAI;YAGnD,MAAMa,eACJX,AAAU,MAAVA,QACIF,KAAK,IAAI,IAAIA,KAAK,IAAI,IAAI,KAC1B,GAAGS,iBAAiB,EAAE,EAAET,KAAK,IAAI,IAAIA,KAAK,IAAI,IAAI,IAAI;YAC5D,MAAMc,SAAStD,WAAWqD;YAC1B,MAAME,gBAAgB3B,oBAAoB0B;YAE1C,MAAME,iBACJd,AAAU,MAAVA,QAAc,IAAI9B,KAAK,GAAG,CAAC,MAAM,IAAI8B,AAAQ,OAARA;YACvC,MAAMe,kBACJf,AAAU,MAAVA,QAAc,IAAI9B,KAAK,GAAG,CAAC,KAAK,IAAI8B,AAAQ,OAARA;YAEtC,MAAMgB,uBAAuB;YAC7B,MAAMC,eACJd,eAAe,IACX,IAAKD,eAAgBC,CAAAA,eAAe,KAAMa,uBAC1C;YAEN,MAAME,aAAaJ,iBAAiBG;YACpC,MAAME,cAAcJ,kBAAkBE;YAEtC,MAAMG,YAAYP,gBACd,YACAb,AAAU,MAAVA,QACEtC,eAAe2C,WAAW,OAC1B3C,eAAe2C,WAAWa;YAEhC,MAAMG,kBAAkBR,gBACpB,YACAb,AAAU,MAAVA,QACEK,YACA3C,eAAe2C,WAAWc;YAEhC,MAAMG,SAAS5C,YAAY0C;YAC3B,MAAMG,YAAYD,SAAS,YAAY;YACvC,MAAME,kBAAkBF,SACpB,6BACA;YAEJ,MAAMG,SAA0B;gBAC9B,IAAIb;gBACJ,MAAMd,KAAK,IAAI;gBACf,OAAOrB;gBACP,MAAMqB,KAAK,IAAI,IAAIA,KAAK,IAAI;gBAC5B,YACEA,KAAK,UAAU,IAAKf,CAAAA,AAAa,WAAbA,WAAsBN,MAAMiD,MAAQ;gBAC1D,aACE5B,KAAK,WAAW,IAAKf,CAAAA,AAAa,aAAbA,WAAwBN,MAAMiD,MAAQ;gBAC7D,UAAU5B,KAAK,QAAQ,IAAKf,CAAAA,AAAa,WAAbA,WAAsBN,MAAMiD,MAAQ;gBAChE,UAAU5B,KAAK,EAAE;gBACjB,WAAW;oBACT,aAAae,gBAAgB,IAAI;oBACjC,OAAOO;oBACP,aAAaC;oBACb,GAAIrB,AAAU,MAAVA,SAAe;wBAAE,UAAU;oBAAE,CAAC;gBACpC;gBACA,OAAO;oBACL,MAAM;oBACN,OAAOuB;oBACP,iBAAiBC;oBACjB,iBAAiB;gBACnB;gBACA,YACExB,AAAU,MAAVA,QACI0B,SACA;oBACE,MAAM;oBACN,OAAOH;gBACT;YACR;YAEA,IAAIf,YAAYA,SAAS,MAAM,GAAG,GAChCiB,OAAO,QAAQ,GAAGjB;YAGpB,IAAIK,eACFY,OAAO,QAAQ,GAAG;gBAChB,WAAW;oBACT,aAAa;oBACb,aAAa;oBACb,OAAO;gBACT;YACF;iBAGAA,OAAO,QAAQ,GAAG;gBAChB,WAAW;oBACT,OAAOL;oBACP,aAAaC;oBACb,aAAaR,gBAAgB,IAAI;gBACnC;YACF;YAGF,OAAOY;QACT;QAEA,MAAME,OAAO7C,SACV,GAAG,CAAC,CAAC8C,MAAM7B,QACVF,QAAQ+B,MAAM7B,OAAO,GAAG2B,QAAW3B,OAAOjB,SAAS,MAAM,EAAE4C,SAE5D,MAAM,CACL,CAACE,OACE,CAAsB,YAAtB,OAAOA,KAAK,KAAK,GAAgBA,KAAK,KAAK,GAAG,IAAI,KAAI,KACtDA,KAAK,QAAQ,IAAIA,KAAK,QAAQ,CAAC,MAAM,GAAG;QAG/ClC,aAAa,OAAO,GAAGiC;QAEvBrC,UAAU;YACR,OAAOgB;YACP,SAAS;gBACP,SAAS;gBACT,iBAAiB;gBACjB,aAAa;gBACb,aAAa;gBACb,WAAW;oBACT,OAAO;gBACT;gBACA,SAAS;gBACT,cAAc;gBACd,UAAU,SAAUuB,GAAG,EAAEC,OAAO,EAAEC,IAAI,EAAEC,KAAK,EAAEC,IAAI;oBACjD,MAAMC,MAAsD;wBAC1D,KAAKL,GAAG,CAAC,EAAE,GAAG;oBAChB;oBACA,IAAIA,GAAG,CAAC,EAAE,GAAGI,KAAK,QAAQ,CAAC,EAAE,GAAG,GAC9BC,IAAI,IAAI,GAAGL,GAAG,CAAC,EAAE,GAAG;yBAEpBK,IAAI,KAAK,GAAGD,KAAK,QAAQ,CAAC,EAAE,GAAGJ,GAAG,CAAC,EAAE,GAAG;oBAE1C,OAAOK;gBACT;gBACA,WAAW,SACTC,IAAqD;oBAErD,MAAMrC,OAAOqC,KAAK,IAAI,IAAI,CAAC;oBAC3B,IAAIC,OACF,AAAqB,YAArB,OAAOtC,KAAK,IAAI,GACZA,KAAK,IAAI,GACT,AAAqB,YAArB,OAAOA,KAAK,IAAI,GACdA,KAAK,IAAI,GACTuC,OAAOvC,KAAK,IAAI,IAAI;oBAE5B,IAAIV,YAAYgD,MAAM;wBACpB,MAAME,iBAAiBlD,SACpB,OAAO,CAAC,OAAO,KACf,OAAO,CAAC,OAAO;wBAClB,MAAMmD,iBAAiBH,KAAK,OAAO,CAAC,OAAO;wBAC3C,IAAIG,eAAe,UAAU,CAACD,iBAAiB,MAC7CF,OAAOG,eAAe,KAAK,CAACD,eAAe,MAAM,GAAG;6BAC/C,IAAIC,mBAAmBD,gBAC5BF,OAAO;oBAEX;oBAEA,MAAMI,aACJ,AAA2B,YAA3B,OAAO1C,KAAK,UAAU,IAAiBA,KAAK,UAAU,GAAG,IACrDA,KAAK,UAAU,GACf,AAAsB,YAAtB,OAAOA,KAAK,KAAK,IACfA,KAAK,KAAK,GAAG,KACbf,AAAa,WAAbA,WACAe,KAAK,KAAK,GACV4B;oBACR,MAAMe,cACJ,AAA4B,YAA5B,OAAO3C,KAAK,WAAW,IAAiBA,KAAK,WAAW,GAAG,IACvDA,KAAK,WAAW,GAChB4B;oBACN,MAAMgB,WACJ,AAAyB,YAAzB,OAAO5C,KAAK,QAAQ,IAAiBA,KAAK,QAAQ,GAAG,IACjDA,KAAK,QAAQ,GACb4B;oBAEN,SAASiB,QAAQC,KAAa,EAAEC,KAAa,EAAEC,KAAa;wBAC1D,OAAO,CAAC,YAAY,EAAEC,cAAAA,CAAAA,cAAqB,CAAC;iCACzB,EAAEA,cAAAA,CAAAA,gBAAuB,CAAC,gBAAgB,EAAED,MAAM,GAAG,EAAEF,MAAM;wCACtD,EAAEE,MAAM,GAAG,EAAED,MAAM;sBACrC,CAAC;oBACX;oBAEA,MAAMG,OAAO,EAAE;oBACf,IAAIR,AAAed,WAAfc,cAA4BA,aAAa,GAC3CQ,KAAK,IAAI,CACPL,QAAQ,aAAaM,WAAWT,aAAa;oBAGjD,IAAIC,AAAgBf,WAAhBe,eAA6BA,cAAc,GAC7CO,KAAK,IAAI,CACPL,QAAQ,eAAeM,WAAWR,cAAc;oBAGpD,IAAIC,AAAahB,WAAbgB,YAA0BA,WAAW,GACvCM,KAAK,IAAI,CACPL,QAAQ,gBAAgBM,WAAWP,WAAW;oBAIlD,OAAO,CAAC;;8LAE0K,EAAEzF,wCAAAA,MAAAA,CAAAA,UAAyB,CAACmF,MAAM;kBAC9M,EAAEY,KAAK,IAAI,CAAC,IAAI;;cAEpB,CAAC;gBACL;YACF;YACA,QAAQ;gBACN;oBACE,MAAM;oBACN,WAAW;wBACT,UAAU;oBACZ;oBACA,OAAO;wBACL,MAAM;wBACN,WAAW;wBACX,UAAU;wBACV,UAAU;wBACV,YAAY;wBACZ,iBAAiB;wBACjB,SAAS;4BAAC;4BAAG;4BAAG;4BAAG;yBAAE;oBACvB;oBACA,YAAY;wBACV,MAAM;wBACN,QAAQ;wBACR,UAAU;wBACV,YAAY;wBACZ,SAAS;4BAAC;4BAAG;4BAAG;4BAAG;yBAAE;oBACvB;oBACA,QAAQrE;oBACR,MAAMgD;oBACN,YAAY;wBACV,MAAM;wBACN,MAAM;wBACN,KAAK;wBACL,QAAQ;wBACR,gBAAgB;wBAChB,WAAW;4BACT,OAAO;4BACP,aAAa;4BACb,aAAa;4BACb,cAAc;wBAChB;wBACA,UAAU;4BACR,WAAW;gCACT,OAAO;4BACT;wBACF;wBACA,WAAW;4BACT,YAAY;4BACZ,UAAU;4BACV,OAAO;wBACT;oBACF;oBACA,MAAM;oBACN,WAAW;oBACX,iBAAiB;oBACjB,yBAAyB;oBACzB,OAAO;oBACP,QAAQ;oBACR,KAAK;oBACL,QAAQ;oBACR,MAAM;oBACN,OAAO;oBACP,WAAW;wBACT,KAAK;wBACL,KAAK;oBACP;gBACF;aACD;QACH;IACF,GAAG;QAAC7C;QAAUC;QAAUG;QAAiBE;KAAS;IAElDQ,UAAU;QACR,IAAIT,gBAAgBK,SAAS,OAAO,IAAIH,QAAQ;YAC9C,MAAM6D,gBACJ1D,SAAS,OAAO,CAAC,kBAAkB;YACrC,IAAI0D,eAAe;gBACjB,MAAMC,eAAe,CACnBxB,MACAyB,UACAhB,OAAiB,EAAE;oBAEnB,KAAK,MAAMR,QAAQD,KAAM;wBACvB,MAAM0B,WACJ,AAAqB,YAArB,OAAOzB,KAAK,IAAI,GACZA,KAAK,IAAI,GACTS,OAAOT,KAAK,IAAI,IAAI;wBAC1B,MAAM0B,cAAc;+BAAIlB;4BAAMiB;yBAAS;wBACvC,IAAIzB,KAAK,EAAE,KAAKwB,UACd,OAAO;4BAAE,MAAMC;4BAAU,MAAMC;wBAAY;wBAE7C,IAAI1B,KAAK,QAAQ,EAAE;4BACjB,MAAM2B,QAAQJ,aACZvB,KAAK,QAAQ,EACbwB,UACAE;4BAEF,IAAIC,OAAO,OAAOA;wBACpB;oBACF;oBACA,OAAO;gBACT;gBAEAC,WAAW;oBACT,MAAMC,WAAWN,aAAazD,aAAa,OAAO,EAAEP;oBACpD,IAAI,CAACsE,UAAU;oBACf,MAAMC,WAAWD,SAAS,IAAI;oBAE9B,IAAI;wBACFP,cAAc,cAAc,CAAC;4BAC3B,MAAM;4BACN,aAAa;4BACb,MAAMQ;wBACR;oBACF,EAAE,OAAOC,GAAG;wBACVC,QAAQ,KAAK,CAAC,uCAAuCF,UAAUC;oBACjE;oBAEA,MAAME,iBAAoC;wBACxC,IACEX,cAAc,cAAc,CAAC;gCAC3B,MAAM;gCACN,aAAa;gCACb,cAAcb,OAAOlD;4BACvB;wBACF,IACE+D,cAAc,cAAc,CAAC;gCAC3B,MAAM;gCACN,aAAa;gCACb,MAAMQ;4BACR;wBACF,IACER,cAAc,cAAc,CAAC;gCAC3B,MAAM;gCACN,aAAa;gCACb,MAAMO,SAAS,IAAI,CAAC,IAAI,CAAC;4BAC3B;wBACF,IACEA,SAAS,IAAI,CAAC,MAAM,GAAG,KACvBP,cAAc,cAAc,CAAC;gCAC3B,MAAM;gCACN,aAAa;gCACb,MAAMO,SAAS,IAAI,CAACA,SAAS,IAAI,CAAC,MAAM,GAAG,EAAE;4BAC/C;qBACH;oBAED,KAAK,MAAMK,YAAYD,eACrB,IAAI;wBACFC;wBACA;oBACF,EAAE,OAAOH,GAAG;wBACVC,QAAQ,KAAK,CACX,mCACAzE,cACAwE;oBAEJ;oBAGFC,QAAQ,IAAI,CAAC,mCAAmCzE;gBAClD,GAAG;YACL;QACF;IACF,GAAG;QAACA;QAAcE;KAAO;IAEzBO,UAAU,IACD;YACL,IAAID,gBAAgB,OAAO,EACzBoE,OAAO,YAAY,CAACpE,gBAAgB,OAAO;QAE/C,GACC,EAAE;IAEL,OAAON,SAAS,WAATA,GACL,KAAC;QAAI,WAAW0D,cAAAA,CAAAA,kBAAyB;QAAE,OAAO/D;;0BAChD,IAACgF,OAAKA;gBACJ,SAAQ;gBACR,MAAK;gBACL,UAAQ;gBACR,OAAO;oBAAE,cAAc;gBAAE;;0BAE3B,IAACC,MAAgBA;gBACf,KAAKzE;gBACL,QAAQH;gBACR,SAASpC;gBACT,UAAU;oBACR,OAAO,CAACiH;wBAEN,IAAIvE,gBAAgB,OAAO,EACzBoE,OAAO,YAAY,CAACpE,gBAAgB,OAAO;wBAE7CA,gBAAgB,OAAO,GAAGoE,OAAO,UAAU,CAAC;4BAC1C,IAAIvE,SAAS,OAAO,EAAE;gCACpB,MAAM2E,WACJ3E,SAAS,OAAO,CAAC,kBAAkB;gCACrC,MAAMmC,OAAOuC,QAAQ;gCACrB,IAAIC,YAAYxC,MAAM,OAAOD,QAC3ByC,SAAS,cAAc,CAAC;oCACtB,MAAM;oCACN,aAAa;oCACb,cAAc9B,OAAOV,KAAK,EAAE;gCAC9B;4BAEJ;wBACF,GAAG;oBACL;oBACA,UAAU,CAACuC;wBAET,IAAIvE,gBAAgB,OAAO,EAAE;4BAC3BoE,OAAO,YAAY,CAACpE,gBAAgB,OAAO;4BAC3CA,gBAAgB,OAAO,GAAG;wBAC5B;wBACAV,eAAeiF;oBACjB;gBACF;gBACA,OAAO;oBACL,OAAO;oBACP,QAAQ;gBACV;;;SAGF;AACN;AAGK,MAAME,yBAIR,CAAC,EAAEtF,QAAQ,EAAEG,YAAY,EAAEwD,cAAc,IAAI,EAAE,GAC3C,WAAP,GACE,IAAC4B,mBAAiBA;QAAC,KAAKC,IAAI,SAAS,CAAC,GAAG,CAAC,cAAc;kBACrD,CAACC,cACO,WAAP,GACE,IAACC,6BAA2BA;gBAC1B,UAAU1F;gBACV,cAAcG;gBACd,aAAawD;gBACb,UAAU8B,YAAY,IAAI;;;AAQtC,MAAMC,8BAKD,CAAC,EAAE1F,QAAQ,EAAEG,YAAY,EAAEwD,cAAc,IAAI,EAAErD,QAAQ,EAAE;IAC5D,MAAMqF,aAAaC,QACjB,IAAM5F,SAAS,GAAG,CAAC,CAAC8C,OAASA,KAAK,IAAI,GACtC;QAAC9C;KAAS;IAGZ,MAAM,CAAC6F,eAAeC,iBAAiB,GAAGrF,SAAmBkF;IAC7D,MAAM,CAACI,WAAWC,aAAa,GAAGvF,SAAS;IAC3C,MAAM,CAACR,UAAUgG,YAAY,GAAGxF,SAC9BkD,cAAc,WAAW;IAE3B,MAAM,CAACuC,aAAaC,eAAe,GAAG1F,SAAS;IAC/C,MAAM,CAAC2F,cAAcC,gBAAgB,GAAG5F,SAAS;IACjD,MAAM,CAACL,iBAAiBkG,mBAAmB,GAAG7F;IAC9C,MAAM,CAACJ,cAAckG,gBAAgB,GAAG9F;IACxC,MAAM,CAAC+F,UAAUC,YAAY,GAAGhG,SAA0B;IAC1D,MAAM,CAACiG,aAAaC,eAAe,GAAGlG,SAAS;IAC/C,MAAM,CAACmG,kBAAkBC,oBAAoB,GAAGpG,SAAS;IACzD,MAAM,CAACqG,0BAA0BC,4BAA4B,GAC3DtG,SAAS;IAEX,MAAMuG,eAAerG,MAAAA,MAAY,CAAiB;IAElD,MAAMsG,oBAAoBrB,QAAQ;QAChC,IAAI,CAACkB,0BACH,OAAOnB;QAGT,OAAOA,WAAW,MAAM,CAACuB;IAC3B,GAAG;QAACvB;QAAYmB;KAAyB;IAEzC,MAAMK,uBAAuBvB,QAC3B,IAAMqB,kBAAkB,IAAI,CAAC,OAC7B;QAACA;KAAkB;IAErB,MAAMG,kCAAkCzG,MAAAA,MAAY,CAClDiC;IAGF9B,UAAU;QACR,IAAIsG,gCAAgC,OAAO,KAAKD,sBAC9C;QAGFC,gCAAgC,OAAO,GAAGD;QAC1CrB,iBAAiBmB;IACnB,GAAG;QAACA;QAAmBE;KAAqB;IAE5C,MAAME,mBAAmBC,YACvB,CAAClC;QACCjF,eAAeiF;QACf,MAAMvC,OAAOuC,OAAO,IAAI;QACxB,MAAMoB,WAAW3D,MAAM;QACvB,IAAI2D,AAAa5D,WAAb4D,UAAwB;YAC1BC,YAAYD;YACZG,eAAe;QACjB;IACF,GACA;QAACxG;KAAa;IAGhB,MAAMoH,kBAAkBD,YAAY;QAClC,IAAIN,aAAa,OAAO,EAAE;YACxB,MAAMQ,KAAKR,aAAa,OAAO;YAK/B,IAAIQ,GAAG,iBAAiB,EACtBA,GAAG,iBAAiB,GACjB,IAAI,CAAC,IAAMnB,gBAAgB,OAC3B,KAAK,CAAC,CAACoB,MACN3C,QAAQ,KAAK,CAAC,+BAA+B2C;iBAE5C,IAAID,GAAG,uBAAuB,EACnC,IAAI;gBACFA,GAAG,uBAAuB;gBAC1BnB,gBAAgB;YAClB,EAAE,OAAOoB,KAAK;gBACZ3C,QAAQ,KAAK,CAAC,wCAAwC2C;YACxD;iBACK,IAAID,GAAG,oBAAoB,EAChC,IAAI;gBACFA,GAAG,oBAAoB;gBACvBnB,gBAAgB;YAClB,EAAE,OAAOoB,KAAK;gBACZ3C,QAAQ,KAAK,CAAC,qCAAqC2C;YACrD;iBACK,IAAID,GAAG,mBAAmB,EAC/B,IAAI;gBACFA,GAAG,mBAAmB;gBACtBnB,gBAAgB;YAClB,EAAE,OAAOoB,KAAK;gBACZ3C,QAAQ,KAAK,CAAC,oCAAoC2C;YACpD;iBAEA3C,QAAQ,KAAK,CAAC;QAElB;IACF,GAAG,EAAE;IAEL,MAAM4C,iBAAiBJ,YAAY;QACjCK,SACG,cAAc,GACd,IAAI,CAAC,IAAMtB,gBAAgB,QAC3B,KAAK,CAAC,CAACoB,MAAQ3C,QAAQ,KAAK,CAAC,8BAA8B2C;IAChE,GAAG,EAAE;IAEL,MAAMG,mBAAmBN,YAAY;QACnC,IAAIlB,cACFsB;aAEAH;IAEJ,GAAG;QAACnB;QAAcmB;QAAiBG;KAAe;IAElD5G,UAAU;QACR,MAAM+G,yBAAyB;YAC7BxB,gBAAgB,CAAC,CAACsB,SAAS,iBAAiB;QAC9C;QACAA,SAAS,gBAAgB,CAAC,oBAAoBE;QAC9C,OAAO;YACLF,SAAS,mBAAmB,CAAC,oBAAoBE;QACnD;IACF,GAAG,EAAE;IAEL,MAAMC,mBAAmBlC,QAAQ;QAC/B,IAAImC,WAAW/H,SAAS,MAAM,CAC5B,CAAC8C,OACCmE,kBAAkB,QAAQ,CAACnE,KAAK,IAAI,KACpC+C,cAAc,QAAQ,CAAC/C,KAAK,IAAI;QAGpC,IAAI8D,iBAAiB,IAAI,IAAI;YAC3B,MAAMoB,cAAcpB,iBAAiB,WAAW;YAChDmB,WAAWA,SAAS,MAAM,CAAC,CAACjF,OAC1BA,KAAK,IAAI,CAAC,WAAW,GAAG,QAAQ,CAACkF;QAErC;QAEA,OAAOD;IACT,GAAG;QAAC/H;QAAU6F;QAAee;QAAkBK;KAAkB;IAEjE,MAAMgB,gBAAgBrC,QAAQ;QAC5B,IAAI,CAACM,YAAY,IAAI,IAAI,OAAO,EAAE;QAElC,MAAMgC,QAAQ,IAAIC,OAAOjC,aAAa;QACtC,MAAMkC,UAAmD,EAAE;QAE3D,MAAMC,uBAAuB,CAACrH,MAAgBM;YAE5C,MAAMG,mBAAmBH,aAAaN,KAAK,IAAI,IAAIA,KAAK,IAAI,IAAI;YAEhE,IAAIA,KAAK,IAAI,IAAIkH,MAAM,IAAI,CAAClH,KAAK,IAAI,GAAG;gBAEtC,MAAMa,eAAeP,YACjB,GAAGA,UAAU,EAAE,EAAEN,KAAK,IAAI,EAAE,GAC5BA,KAAK,IAAI;gBACb,MAAMc,SAAStD,WAAWqD;gBAC1BuG,QAAQ,IAAI,CAAC;oBAAE,MAAMpH,KAAK,IAAI;oBAAEc;gBAAO;YACzC;YACA,IAAId,KAAK,QAAQ,EACfA,KAAK,QAAQ,CAAC,OAAO,CAAC,CAACsH,QACrBD,qBAAqBC,OAAO7G;QAGlC;QAEAqG,iBAAiB,OAAO,CAAC,CAACS,QAAUF,qBAAqBE;QACzD,OAAOH;IACT,GAAG;QAACN;QAAkB5B;KAAY;IAElC,MAAMsC,0BAA0BlB,YAAY,CAACxF;QAC3CwE,mBAAmBxE;QACnByE,gBAAgBzE;IAClB,GAAG,EAAE;IAEL,MAAM2G,iBAAiBnB,YACrB,CAACoB;QACC,IAAI,CAACpI,YAAY,CAACoI,UAAU,OAAOA;QACnC,MAAMlF,iBAAiBlD,SAAS,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO;QACnE,MAAMmD,iBAAiBiF,SAAS,OAAO,CAAC,OAAO;QAE/C,IAAIjF,eAAe,UAAU,CAACD,iBAAiB,MAC7C,OAAOC,eAAe,KAAK,CAACD,eAAe,MAAM,GAAG;QAC/C,IAAIC,mBAAmBD,gBAC5B,OAAO;QAET,OAAOkF;IACT,GACA;QAACpI;KAAS;IAGZ,MAAMqI,UAAUrB,YAAY,CAACtG,MAAgB4H;QAC3C,IAAIA,AAAS,WAATA,MAAiB,OAAO5H,KAAK,UAAU,IAAI;QAC/C,IAAI4H,AAAS,aAATA,MAAmB,OAAO5H,KAAK,WAAW,IAAI;QAClD,IAAI4H,AAAS,WAATA,MAAiB,OAAO5H,KAAK,QAAQ,IAAI;QAC7C,IAAI4H,AAAS,YAATA,MAAkB,OAAO5H,KAAK,KAAK,IAAI;QAC3C,IAAIA,KAAK,KAAK,EAAE,OAAOA,KAAK,KAAK;QACjC,OAAO;IACT,GAAG,EAAE;IAEL,MAAM6H,yBAAyBvB,YAC7B,CAACtG,MAAgB4H;QACf,IAAIzF,OAAOwF,QAAQ3H,MAAM4H;QAEzB,IAAI5H,KAAK,QAAQ,IAAIA,KAAK,QAAQ,CAAC,MAAM,GAAG,GAAG;YAC7C,MAAM8H,eAAe9H,KAAK,QAAQ,CAAC,MAAM,CACvC,CAAC+H,KAAKT,QAAUS,MAAMF,uBAAuBP,OAAOM,OACpD;YAEF,IAAIzF,AAAS,MAATA,QAAe,CAACnC,KAAK,IAAI,IAAI8H,eAAe,GAC9C3F,OAAO2F;QAEX;QAEA,OAAO3F;IACT,GACA;QAACwF;KAAQ;IAGX,MAAMK,eAAe1B,YACnB,CAAC2B,MAAcL;QACb,MAAM5H,OAAOhB,SAAS,IAAI,CAAC,CAACkJ,IAAMA,EAAE,IAAI,KAAKD;QAC7C,IAAI,CAACjI,MAAM,OAAO;QAClB,MAAMmI,gBAAgBP,QAAQ3I;QAC9B,OAAO4I,uBAAuB7H,MAAMmI;IACtC,GACA;QAACnJ;QAAUC;QAAU4I;KAAuB;IAG9C,OAAO,WAAP,GACE,KAAC;QAAI,WAAW5E,eAAAA,OAAc;QAAE,KAAK+C;;0BACnC,IAAC;gBACC,WAAW/C,cAAAA,CAAAA,oBAA2B;gBACtC,SAAS2D;gBACT,OAAOxB,eAAe,oBAAoB;gBAC1C,cAAYA,eAAe,oBAAoB;0BAE9CA,eAAe,WAAfA,GAAe,IAACgD,wBAAsBA,CAAAA,KAAAA,WAAAA,GAAM,IAACC,oBAAkBA,CAAAA;;0BAGlE,KAAC;gBAAI,WAAW,GAAGpF,eAAAA,OAAc,CAAC,CAAC,EAAE8B,YAAY9B,eAAAA,SAAgB,GAAG,IAAI;;kCACtE,IAAC;wBACC,WAAW,GAAGA,cAAAA,CAAAA,iBAAwB,CAAC,CAAC,EAAE8B,YAAY9B,eAAAA,SAAgB,GAAG,IAAI;wBAC7E,SAAS,IAAM+B,aAAa,CAACD;kCAE5BA,YAAY,WAAZA,GAAY,IAACuD,eAAaA,CAAAA,KAAAA,WAAAA,GAAM,IAACC,cAAYA,CAAAA;;kCAEhD,KAAC;wBAAI,WAAWtF,cAAAA,CAAAA,kBAAyB;;0CACvC,KAAC;;kDACC,IAAC;kDAAG;;kDACJ,KAACuF,MAAM,KAAK;wCACV,OAAOvJ;wCACP,UAAU,CAAC4E,IAAMoB,YAAYpB,EAAE,MAAM,CAAC,KAAK;wCAC3C,MAAK;wCACL,aAAY;;0DAEZ,IAAC2E,MAAM,MAAM;gDAAC,OAAM;0DAAO;;0DAC3B,IAACA,MAAM,MAAM;gDAAC,OAAM;0DAAS;;0DAC7B,IAACA,MAAM,MAAM;gDAAC,OAAM;0DAAO;;;;;;0CAI/B,KAAC;;kDACC,IAAC;kDAAG;;kDACJ,IAACC,OAAKA;wCACJ,aAAY;wCACZ,OAAO7C;wCACP,UAAU,CAAC/B,IAAMgC,oBAAoBhC,EAAE,MAAM,CAAC,KAAK;wCACnD,sBAAQ,IAAC6E,gBAAcA;4CAAC,OAAO;gDAAE,OAAO;4CAAO;;wCAC/C,YAAU;wCACV,MAAK;wCACL,OAAO;4CAAE,cAAc;wCAAE;;kDAE3B,IAACC,UAAQA;wCACP,eACE9D,cAAc,MAAM,GAAG,KACvBA,cAAc,MAAM,GAAGoB,kBAAkB,MAAM;wCAEjD,SACEA,kBAAkB,MAAM,GAAG,KAC3BpB,cAAc,MAAM,KAAKoB,kBAAkB,MAAM;wCAEnD,UAAU,CAACpC,IACTiB,iBAAiBjB,EAAE,MAAM,CAAC,OAAO,GAAGoC,oBAAoB,EAAE;wCAE5D,WAAWhD,cAAAA,CAAAA,oBAA2B;kDACvC;;kDAGD,IAAC0F,UAAQA;wCACP,SAAS7C;wCACT,UAAU,CAACjC;4CACTkC,4BAA4BlC,EAAE,MAAM,CAAC,OAAO;wCAC9C;wCACA,WAAWZ,cAAAA,CAAAA,oBAA2B;kDACvC;;kDAGD,IAAC;wCACC,WAAWA,cAAAA,CAAAA,aAAoB;wCAC/B,OAAO;4CAAE,WAAW;4CAAK,WAAW;wCAAO;kDAE1CgD,kBACE,MAAM,CAAC,CAACgC,OACPA,KAAK,WAAW,GAAG,QAAQ,CAACrC,iBAAiB,WAAW,KAEzD,GAAG,CAAC,CAACqC,OAAAA,WAAAA,GACJ,KAAC;gDAEC,WAAWhF,cAAAA,CAAAA,aAAoB;gDAC/B,OAAO;oDAAE,QAAQ;oDAAI,YAAY;gDAAO;;kEAExC,IAAC0F,UAAQA;wDACP,SAAS9D,cAAc,QAAQ,CAACoD;wDAChC,UAAU,CAACpE;4DACLA,EAAE,MAAM,CAAC,OAAO,GAClBiB,iBAAiB;mEAAID;gEAAeoD;6DAAK,IAEzCnD,iBACED,cAAc,MAAM,CAAC,CAAC+D,IAAMA,MAAMX;wDAGxC;kEAEA,kBAAC;4DAAK,OAAOA;sEAAOA;;;kEAEtB,IAAC;wDAAK,WAAWhF,cAAAA,CAAAA,WAAkB;kEAChCE,WAAW6E,aAAaC,MAAMhJ;;;+CAnB5BgJ;;;;0CA0Bf,KAAC;;kDACC,IAAC;kDAAG;;kDACJ,IAACQ,OAAKA;wCACJ,aAAY;wCACZ,OAAOvD;wCACP,UAAU,CAACrB;4CACTsB,eAAetB,EAAE,MAAM,CAAC,KAAK;4CAC7ByB,mBAAmB1D;4CACnB2D,gBAAgB3D;wCAClB;wCACA,sBAAQ,IAAC8G,gBAAcA;4CAAC,OAAO;gDAAE,OAAO;4CAAO;;wCAC/C,YAAU;wCACV,MAAK;;oCAENxD,YAAY,IAAI,MAAM+B,cAAc,MAAM,GAAG,KAAK,WAAL,GAC5C,KAAC;wCAAI,WAAWhE,cAAAA,CAAAA,iBAAwB;;0DACtC,KAAC;gDAAI,WAAWA,cAAAA,CAAAA,wBAA+B;;oDAAE;oDACxCgE,cAAc,MAAM;oDAAC;oDAC3BA,cAAc,MAAM,GAAG,IAAI,MAAM;;;0DAEpC,IAAC;gDAAI,WAAWhE,cAAAA,CAAAA,sBAA6B;0DAC1CgE,cAAc,GAAG,CAAC,CAACtF,QAAQ1B;oDAC1B,MAAM4I,cAAcpB,eAAe9F,OAAO,IAAI;oDAC9C,OAAO,WAAP,GACE,IAAC;wDAEC,WAAWsB,cAAAA,CAAAA,qBAA4B;wDACvC,SAAS,IAAMuE,wBAAwB7F,OAAO,MAAM;wDACpD,OAAOA,OAAO,IAAI;kEAEjBkH,eAAelH,OAAO,IAAI;uDALtB1B;gDAQX;;;;oCAILiF,YAAY,IAAI,MAAM+B,AAAyB,MAAzBA,cAAc,MAAM,IAAU,WAAL,GAC9C,KAAC;wCAAI,WAAWhE,cAAAA,CAAAA,uBAA8B;;4CAAE;4CACpBiC;4CAAY;;;;;;;;;0BAOhD,KAAC;gBAAI,WAAWjC,cAAAA,CAAAA,gBAAuB;;kCACrC,IAACnE,SAAOA;wBACN,UAAUgI;wBACV,UAAU7H;wBACV,cAAcoH;wBACd,iBAAiBjH;wBACjB,cAAcC;wBACd,UAAUC;wBACV,OAAO;4BAAE,OAAO;4BAAQ,QAAQ;wBAAO;;oBAExCkG,WAAW,WAAXA,GACC,IAACjB,mBAAiBA;wBAChB,KAAKC,IAAI,SAAS,CAAC,GAAG,CAAC,iBAAiB;wBACxC,MAAM,CAAC;kCAEN,CAACsE,UAAAA,WAAAA,GACA,IAACC,wBAAsBA;gCACrB,KAAKzJ;gCACL,UAAUkG;gCACV,SAASsD;gCACT,MAAMpD;gCACN,SAASC;;yBAIb;;;;;AAIZ"}
@@ -1,16 +1,50 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { Lodash } from "@rsdoctor/utils/common";
3
+ import { SDK } from "@rsdoctor/types";
3
4
  import "react";
4
5
  import vscode from "../../common/svg/vscode.mjs";
5
6
  const OPEN_IN_EDITOR_PATH = '/__open-in-editor';
7
+ let openInEditorTokenTask;
8
+ function clearOpenInEditorTokenTask(task = openInEditorTokenTask) {
9
+ if (openInEditorTokenTask === task) openInEditorTokenTask = void 0;
10
+ }
11
+ function getOpenInEditorTokenFromSocketUrl(socketUrl) {
12
+ if (!socketUrl) return;
13
+ try {
14
+ return new URL(socketUrl, window.location.origin).searchParams.get('token') || void 0;
15
+ } catch {
16
+ return;
17
+ }
18
+ }
19
+ async function getOpenInEditorToken(base) {
20
+ if (!base) return;
21
+ if (!openInEditorTokenTask) {
22
+ const task = fetch(`${base}${SDK.ServerAPI.API.Manifest}`).then((res)=>res.ok ? res.json() : void 0).then((manifest)=>{
23
+ const token = getOpenInEditorTokenFromSocketUrl(manifest?.__SOCKET__URL__);
24
+ if (!token) clearOpenInEditorTokenTask(task);
25
+ return token;
26
+ }).catch(()=>{
27
+ clearOpenInEditorTokenTask(task);
28
+ });
29
+ openInEditorTokenTask = task;
30
+ }
31
+ return openInEditorTokenTask;
32
+ }
6
33
  async function openInEditor(file, line, column, editor, urlSchemeFallback) {
7
34
  const fileSpec = `${file}:${line}:${column}`;
8
35
  try {
9
36
  const base = "u" > typeof window && window.location?.origin ? window.location.origin : '';
10
- const url = `${base}${OPEN_IN_EDITOR_PATH}?file=${encodeURIComponent(fileSpec)}&editor=${editor}`;
11
- const res = await fetch(url, {
37
+ const token = await getOpenInEditorToken(base);
38
+ if (!token) return void urlSchemeFallback();
39
+ const params = new URLSearchParams({
40
+ file: fileSpec,
41
+ editor,
42
+ token
43
+ });
44
+ const res = await fetch(`${base}${OPEN_IN_EDITOR_PATH}?${params}`, {
12
45
  method: 'GET'
13
46
  });
47
+ if (403 === res.status) clearOpenInEditorTokenTask();
14
48
  if (!res.ok) urlSchemeFallback();
15
49
  } catch {
16
50
  urlSchemeFallback();
@@ -1 +1 @@
1
- {"version":3,"file":"components/Opener/ide.mjs","sources":["../../../src/components/Opener/ide.tsx"],"sourcesContent":["import { Lodash } from '@rsdoctor/utils/common';\nimport React from 'react';\nimport VSCodeIcon from '../../common/svg/vscode.svg';\n\ninterface VSCodeProps {\n file: string;\n line?: number | string;\n column?: number | string;\n windowId?: number;\n style?: React.CSSProperties;\n}\n\nconst OPEN_IN_EDITOR_PATH = '/__open-in-editor';\n\ntype EditorKind = 'code' | 'cursor' | 'trae';\n\nasync function openInEditor(\n file: string,\n line: number | string,\n column: number | string,\n editor: EditorKind,\n urlSchemeFallback: () => void,\n) {\n const fileSpec = `${file}:${line}:${column}`;\n try {\n const base =\n typeof window !== 'undefined' && window.location?.origin\n ? window.location.origin\n : '';\n const url = `${base}${OPEN_IN_EDITOR_PATH}?file=${encodeURIComponent(fileSpec)}&editor=${editor}`;\n const res = await fetch(url, { method: 'GET' });\n if (!res.ok) {\n urlSchemeFallback();\n }\n } catch {\n urlSchemeFallback();\n }\n}\n\nexport function openVSCode({\n file,\n line = 1,\n column = 1,\n windowId,\n}: VSCodeProps) {\n const query: Record<string, unknown> = { windowId };\n const queryString = Object.keys(query)\n .map((k) => {\n const v = query[k];\n if (Lodash.isNil(v) || v === '') return null;\n return `${k}=${v}`;\n })\n .filter(Boolean)\n .join('&');\n\n const fallback = () => {\n let url = `vscode://file/${file}:${line}:${column}`;\n if (queryString) url += `?${queryString}`;\n window.open(url);\n };\n\n openInEditor(file, line, column, 'code', fallback);\n}\n\nexport function openCursor({\n file,\n line = 1,\n column = 1,\n}: Pick<VSCodeProps, 'file' | 'line' | 'column'>) {\n const fallback = () => {\n window.open(`cursor://file/${file}:${line}:${column}`);\n };\n openInEditor(file, line, column, 'cursor', fallback);\n}\n\nexport function openTrae({\n file,\n line = 1,\n column = 1,\n}: Pick<VSCodeProps, 'file' | 'line' | 'column'>) {\n const fallback = () => {\n window.open(`trae://file/${file}:${line}:${column}`);\n };\n\n openInEditor(file, line, column, 'trae', fallback);\n}\n\nexport const VSCode = (props: VSCodeProps): React.JSX.Element => {\n return (\n <VSCodeIcon\n onClick={() => {\n openVSCode(props);\n }}\n style={{\n width: 14,\n cursor: 'pointer',\n verticalAlign: 'middle',\n display: 'inline',\n transform: 'translateY(-1.5px)',\n ...props.style,\n }}\n />\n );\n};\n"],"names":["OPEN_IN_EDITOR_PATH","openInEditor","file","line","column","editor","urlSchemeFallback","fileSpec","base","window","url","encodeURIComponent","res","fetch","openVSCode","windowId","query","queryString","Object","k","v","Lodash","Boolean","fallback","openCursor","openTrae","VSCode","props","VSCodeIcon"],"mappings":";;;;AAYA,MAAMA,sBAAsB;AAI5B,eAAeC,aACbC,IAAY,EACZC,IAAqB,EACrBC,MAAuB,EACvBC,MAAkB,EAClBC,iBAA6B;IAE7B,MAAMC,WAAW,GAAGL,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;IAC5C,IAAI;QACF,MAAMI,OACJ,AAAkB,MAAlB,OAAOC,UAA0BA,OAAO,QAAQ,EAAE,SAC9CA,OAAO,QAAQ,CAAC,MAAM,GACtB;QACN,MAAMC,MAAM,GAAGF,OAAOR,oBAAoB,MAAM,EAAEW,mBAAmBJ,UAAU,QAAQ,EAAEF,QAAQ;QACjG,MAAMO,MAAM,MAAMC,MAAMH,KAAK;YAAE,QAAQ;QAAM;QAC7C,IAAI,CAACE,IAAI,EAAE,EACTN;IAEJ,EAAE,OAAM;QACNA;IACF;AACF;AAEO,SAASQ,WAAW,EACzBZ,IAAI,EACJC,OAAO,CAAC,EACRC,SAAS,CAAC,EACVW,QAAQ,EACI;IACZ,MAAMC,QAAiC;QAAED;IAAS;IAClD,MAAME,cAAcC,OAAO,IAAI,CAACF,OAC7B,GAAG,CAAC,CAACG;QACJ,MAAMC,IAAIJ,KAAK,CAACG,EAAE;QAClB,IAAIE,OAAO,KAAK,CAACD,MAAMA,AAAM,OAANA,GAAU,OAAO;QACxC,OAAO,GAAGD,EAAE,CAAC,EAAEC,GAAG;IACpB,GACC,MAAM,CAACE,SACP,IAAI,CAAC;IAER,MAAMC,WAAW;QACf,IAAIb,MAAM,CAAC,cAAc,EAAER,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;QACnD,IAAIa,aAAaP,OAAO,CAAC,CAAC,EAAEO,aAAa;QACzCR,OAAO,IAAI,CAACC;IACd;IAEAT,aAAaC,MAAMC,MAAMC,QAAQ,QAAQmB;AAC3C;AAEO,SAASC,WAAW,EACzBtB,IAAI,EACJC,OAAO,CAAC,EACRC,SAAS,CAAC,EACoC;IAC9C,MAAMmB,WAAW;QACfd,OAAO,IAAI,CAAC,CAAC,cAAc,EAAEP,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;IACvD;IACAH,aAAaC,MAAMC,MAAMC,QAAQ,UAAUmB;AAC7C;AAEO,SAASE,SAAS,EACvBvB,IAAI,EACJC,OAAO,CAAC,EACRC,SAAS,CAAC,EACoC;IAC9C,MAAMmB,WAAW;QACfd,OAAO,IAAI,CAAC,CAAC,YAAY,EAAEP,KAAK,CAAC,EAAEC,KAAK,CAAC,EAAEC,QAAQ;IACrD;IAEAH,aAAaC,MAAMC,MAAMC,QAAQ,QAAQmB;AAC3C;AAEO,MAAMG,SAAS,CAACC,QACd,WAAP,GACE,IAACC,QAAUA;QACT,SAAS;YACPd,WAAWa;QACb;QACA,OAAO;YACL,OAAO;YACP,QAAQ;YACR,eAAe;YACf,SAAS;YACT,WAAW;YACX,GAAGA,MAAM,KAAK;QAChB"}
1
+ {"version":3,"file":"components/Opener/ide.mjs","sources":["../../../src/components/Opener/ide.tsx"],"sourcesContent":["import { Lodash } from '@rsdoctor/utils/common';\nimport { SDK } from '@rsdoctor/types';\nimport React from 'react';\nimport VSCodeIcon from '../../common/svg/vscode.svg';\n\ninterface VSCodeProps {\n file: string;\n line?: number | string;\n column?: number | string;\n windowId?: number;\n style?: React.CSSProperties;\n}\n\nconst OPEN_IN_EDITOR_PATH = '/__open-in-editor';\n\nlet openInEditorTokenTask: Promise<string | undefined> | undefined;\n\nfunction clearOpenInEditorTokenTask(task = openInEditorTokenTask) {\n if (openInEditorTokenTask === task) {\n openInEditorTokenTask = undefined;\n }\n}\n\nfunction getOpenInEditorTokenFromSocketUrl(socketUrl?: string) {\n if (!socketUrl) return undefined;\n try {\n return (\n new URL(socketUrl, window.location.origin).searchParams.get('token') ||\n undefined\n );\n } catch {\n return undefined;\n }\n}\n\nasync function getOpenInEditorToken(base: string) {\n if (!base) return undefined;\n if (!openInEditorTokenTask) {\n const task = fetch(`${base}${SDK.ServerAPI.API.Manifest}`)\n .then((res) => (res.ok ? res.json() : undefined))\n .then((manifest) => {\n const token = getOpenInEditorTokenFromSocketUrl(\n manifest?.__SOCKET__URL__,\n );\n if (!token) {\n clearOpenInEditorTokenTask(task);\n }\n return token;\n })\n .catch(() => {\n clearOpenInEditorTokenTask(task);\n return undefined;\n });\n openInEditorTokenTask = task;\n }\n\n return openInEditorTokenTask;\n}\n\nasync function openInEditor(\n file: string,\n line: number | string,\n column: number | string,\n editor: SDK.OpenInEditorKind,\n urlSchemeFallback: () => void,\n) {\n const fileSpec = `${file}:${line}:${column}`;\n try {\n const base =\n typeof window !== 'undefined' && window.location?.origin\n ? window.location.origin\n : '';\n const token = await getOpenInEditorToken(base);\n if (!token) {\n urlSchemeFallback();\n return;\n }\n const params = new URLSearchParams({\n file: fileSpec,\n editor,\n token,\n });\n const res = await fetch(`${base}${OPEN_IN_EDITOR_PATH}?${params}`, {\n method: 'GET',\n });\n if (res.status === 403) {\n clearOpenInEditorTokenTask();\n }\n if (!res.ok) {\n urlSchemeFallback();\n }\n } catch {\n urlSchemeFallback();\n }\n}\n\nexport function openVSCode({\n file,\n line = 1,\n column = 1,\n windowId,\n}: VSCodeProps) {\n const query: Record<string, unknown> = { windowId };\n const queryString = Object.keys(query)\n .map((k) => {\n const v = query[k];\n if (Lodash.isNil(v) || v === '') return null;\n return `${k}=${v}`;\n })\n .filter(Boolean)\n .join('&');\n\n const fallback = () => {\n let url = `vscode://file/${file}:${line}:${column}`;\n if (queryString) url += `?${queryString}`;\n window.open(url);\n };\n\n openInEditor(file, line, column, 'code', fallback);\n}\n\nexport function openCursor({\n file,\n line = 1,\n column = 1,\n}: Pick<VSCodeProps, 'file' | 'line' | 'column'>) {\n const fallback = () => {\n window.open(`cursor://file/${file}:${line}:${column}`);\n };\n openInEditor(file, line, column, 'cursor', fallback);\n}\n\nexport function openTrae({\n file,\n line = 1,\n column = 1,\n}: Pick<VSCodeProps, 'file' | 'line' | 'column'>) {\n const fallback = () => {\n window.open(`trae://file/${file}:${line}:${column}`);\n };\n\n openInEditor(file, line, column, 'trae', fallback);\n}\n\nexport const VSCode = (props: VSCodeProps): React.JSX.Element => {\n return (\n <VSCodeIcon\n onClick={() => {\n openVSCode(props);\n }}\n style={{\n width: 14,\n cursor: 'pointer',\n verticalAlign: 'middle',\n display: 'inline',\n transform: 'translateY(-1.5px)',\n ...props.style,\n }}\n />\n );\n};\n"],"names":["OPEN_IN_EDITOR_PATH","openInEditorTokenTask","clearOpenInEditorTokenTask","task","undefined","getOpenInEditorTokenFromSocketUrl","socketUrl","URL","window","getOpenInEditorToken","base","fetch","SDK","res","manifest","token","openInEditor","file","line","column","editor","urlSchemeFallback","fileSpec","params","URLSearchParams","openVSCode","windowId","query","queryString","Object","k","v","Lodash","Boolean","fallback","url","openCursor","openTrae","VSCode","props","VSCodeIcon"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const normalizeAssetPath: (assetPath: string) => string;
2
+ export declare const createAssetPathMap: <T extends {
3
+ path: string;
4
+ }>(assets: T[]) => Map<string, T>;
5
+ export declare const resolveAssetFileTitleTarget: <T extends {
6
+ path: string;
7
+ }>(assetsMap: Map<string, T>, file: string, basename: string) => string | T;
@@ -0,0 +1,9 @@
1
+ const normalizeAssetPath = (assetPath)=>assetPath.replace(/\\/g, '/');
2
+ const createAssetPathMap = (assets)=>new Map(assets.map((asset)=>[
3
+ normalizeAssetPath(asset.path),
4
+ asset
5
+ ]));
6
+ const resolveAssetFileTitleTarget = (assetsMap, file, basename)=>assetsMap.get(normalizeAssetPath(file)) ?? basename;
7
+ export { createAssetPathMap, normalizeAssetPath, resolveAssetFileTitleTarget };
8
+
9
+ //# sourceMappingURL=asset-path.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages/BundleSize/components/asset-path.mjs","sources":["../../../../src/pages/BundleSize/components/asset-path.ts"],"sourcesContent":["export const normalizeAssetPath = (assetPath: string) =>\n assetPath.replace(/\\\\/g, '/');\n\nexport const createAssetPathMap = <T extends { path: string }>(assets: T[]) =>\n new Map(assets.map((asset) => [normalizeAssetPath(asset.path), asset]));\n\nexport const resolveAssetFileTitleTarget = <T extends { path: string }>(\n assetsMap: Map<string, T>,\n file: string,\n basename: string,\n) => assetsMap.get(normalizeAssetPath(file)) ?? basename;\n"],"names":["normalizeAssetPath","assetPath","createAssetPathMap","assets","Map","asset","resolveAssetFileTitleTarget","assetsMap","file","basename"],"mappings":"AAAO,MAAMA,qBAAqB,CAACC,YACjCA,UAAU,OAAO,CAAC,OAAO;AAEpB,MAAMC,qBAAqB,CAA6BC,SAC7D,IAAIC,IAAID,OAAO,GAAG,CAAC,CAACE,QAAU;YAACL,mBAAmBK,MAAM,IAAI;YAAGA;SAAM;AAEhE,MAAMC,8BAA8B,CACzCC,WACAC,MACAC,WACGF,UAAU,GAAG,CAACP,mBAAmBQ,UAAUC"}
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it } from "@rstest/core";
2
+ import { createAssetPathMap, normalizeAssetPath, resolveAssetFileTitleTarget } from "./asset-path.mjs";
3
+ describe('BundleSize asset path helpers', ()=>{
4
+ it('normalizes Windows path separators', ()=>{
5
+ expect(normalizeAssetPath('static\\js\\main.js')).toBe('static/js/main.js');
6
+ });
7
+ it('resolves assets using normalized tree file paths', ()=>{
8
+ const asset = {
9
+ path: 'static\\js\\main.js',
10
+ size: 1024
11
+ };
12
+ const assetsMap = createAssetPathMap([
13
+ asset
14
+ ]);
15
+ expect(resolveAssetFileTitleTarget(assetsMap, 'static/js/main.js', 'main.js')).toBe(asset);
16
+ });
17
+ it('falls back to basename when the asset lookup misses', ()=>{
18
+ const assetsMap = createAssetPathMap([
19
+ {
20
+ path: 'static/js/main.js'
21
+ }
22
+ ]);
23
+ expect(resolveAssetFileTitleTarget(assetsMap, 'static/css/main.css', 'main.css')).toBe('main.css');
24
+ });
25
+ });
26
+
27
+ //# sourceMappingURL=asset-path.test.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages/BundleSize/components/asset-path.test.mjs","sources":["../../../../src/pages/BundleSize/components/asset-path.test.ts"],"sourcesContent":["import { describe, expect, it } from '@rstest/core';\nimport {\n createAssetPathMap,\n normalizeAssetPath,\n resolveAssetFileTitleTarget,\n} from './asset-path';\n\ndescribe('BundleSize asset path helpers', () => {\n it('normalizes Windows path separators', () => {\n expect(normalizeAssetPath('static\\\\js\\\\main.js')).toBe('static/js/main.js');\n });\n\n it('resolves assets using normalized tree file paths', () => {\n const asset = {\n path: 'static\\\\js\\\\main.js',\n size: 1024,\n };\n const assetsMap = createAssetPathMap([asset]);\n\n expect(\n resolveAssetFileTitleTarget(assetsMap, 'static/js/main.js', 'main.js'),\n ).toBe(asset);\n });\n\n it('falls back to basename when the asset lookup misses', () => {\n const assetsMap = createAssetPathMap([{ path: 'static/js/main.js' }]);\n\n expect(\n resolveAssetFileTitleTarget(assetsMap, 'static/css/main.css', 'main.css'),\n ).toBe('main.css');\n });\n});\n"],"names":["describe","it","expect","normalizeAssetPath","asset","assetsMap","createAssetPathMap","resolveAssetFileTitleTarget"],"mappings":";;AAOAA,SAAS,iCAAiC;IACxCC,GAAG,sCAAsC;QACvCC,OAAOC,mBAAmB,wBAAwB,IAAI,CAAC;IACzD;IAEAF,GAAG,oDAAoD;QACrD,MAAMG,QAAQ;YACZ,MAAM;YACN,MAAM;QACR;QACA,MAAMC,YAAYC,mBAAmB;YAACF;SAAM;QAE5CF,OACEK,4BAA4BF,WAAW,qBAAqB,YAC5D,IAAI,CAACD;IACT;IAEAH,GAAG,uDAAuD;QACxD,MAAMI,YAAYC,mBAAmB;YAAC;gBAAE,MAAM;YAAoB;SAAE;QAEpEJ,OACEK,4BAA4BF,WAAW,uBAAuB,aAC9D,IAAI,CAAC;IACT;AACF"}
@@ -12,6 +12,7 @@ import "./index.css";
12
12
  import { AssetTreemapWithFilter } from "../../../components/Charts/TreeMap.mjs";
13
13
  import { Rspack } from "@rsdoctor/utils/common";
14
14
  import { TreeGraph } from "./tree-graph.mjs";
15
+ import { isJavaScriptAsset } from "../../../utils/assets.mjs";
15
16
  const WebpackModulesOverallBase = ({ errors, cwd, summary, entryPoints })=>{
16
17
  const [expanded, setExpanded] = usePersistedState('bundle-size-tabs-card-expanded', false);
17
18
  const cardDomId = useId();
@@ -225,11 +226,11 @@ const WebpackModulesOverallBase = ({ errors, cwd, summary, entryPoints })=>{
225
226
  return /*#__PURE__*/ jsx(ServerAPIProvider, {
226
227
  api: SDK.ServerAPI.API.GetSummaryBundles,
227
228
  children: (data)=>{
228
- const isTargetFileType = (filePath)=>{
229
+ const isVisibleTreemapAsset = (filePath)=>{
229
230
  const ext = filePath.toLowerCase().split('.').pop() || '';
230
- return 'js' === ext || 'cjs' === ext || 'mjs' === ext || 'bundle' === ext || 'css' === ext || 'html' === ext;
231
+ return isJavaScriptAsset(filePath) || 'css' === ext || 'html' === ext;
231
232
  };
232
- const computedTreeData = data.filter((item)=>isTargetFileType(item.asset.path)).map((item)=>{
233
+ const computedTreeData = data.filter((item)=>isVisibleTreemapAsset(item.asset.path)).map((item)=>{
233
234
  const moduleTree = flattenTreemapData(item.modules);
234
235
  const hasModules = item.modules.length > 0;
235
236
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"pages/BundleSize/components/index.mjs","sources":["../../../../src/pages/BundleSize/components/index.tsx"],"sourcesContent":["import {\n CodepenCircleOutlined,\n DeploymentUnitOutlined,\n InfoCircleOutlined,\n ShrinkOutlined,\n ArrowsAltOutlined,\n} from '@ant-design/icons';\nimport { type Client, SDK } from '@rsdoctor/types';\nimport {\n Button,\n Card,\n Col,\n Row,\n Space,\n Tag,\n Tooltip,\n Typography,\n Tabs,\n} from 'antd';\nimport React, { useId } from 'react';\nimport { ServerAPIProvider } from '../../../components/Manifest';\nimport { useProjectInfo } from '../../../components/Layout/project-info-context';\nimport { flattenTreemapData, usePersistedState } from '../../../utils';\nimport { BundleCards } from './cards';\nimport styles from './index.module.scss';\nimport './index.sass';\nimport {\n AssetTreemapWithFilter,\n TreeNode,\n} from 'src/components/Charts/TreeMap';\nimport { Rspack } from '@rsdoctor/utils/common';\nimport { TreeGraph } from './tree-graph';\n\ninterface WebpackModulesOverallProps {\n cwd: string;\n errors: SDK.ErrorsData;\n summary: Client.RsdoctorClientAssetsSummary;\n entryPoints: SDK.ServerAPI.InferResponseType<SDK.ServerAPI.API.GetEntryPoints>;\n}\n\nexport const WebpackModulesOverallBase: React.FC<\n WebpackModulesOverallProps\n> = ({ errors, cwd, summary, entryPoints }) => {\n const [expanded, setExpanded] = usePersistedState(\n 'bundle-size-tabs-card-expanded',\n false,\n );\n const cardDomId = useId();\n const expandActionText = expanded ? 'Shrink card' : 'Expand card';\n return (\n <>\n <React.Activity mode={expanded ? 'hidden' : 'visible'}>\n <BundleCards cwd={cwd} errors={errors} summary={summary} />\n </React.Activity>\n <Card\n className={styles.root}\n classNames={{ body: styles.rootBody }}\n id={cardDomId}\n >\n <Tabs\n size=\"middle\"\n className={styles.tabsRoot}\n tabBarExtraContent={{\n right: (\n <Tooltip\n // the content collapses/expands, but the cursor stays at the same position (outside the button now, cause layout has shifted)\n // antd doesn't know that and keeps the tooltip open, so we need to force rerender it on every state change\n key={String(expanded)}\n title={expandActionText}\n >\n <Button\n // TODO:: does it make sense here? the content basically stays the same and we're actually controlling other elements\n aria-controls={cardDomId}\n aria-expanded={expanded}\n aria-label={expandActionText}\n onClick={() => setExpanded(!expanded)}\n icon={expanded ? <ShrinkOutlined /> : <ArrowsAltOutlined />}\n size=\"small\"\n ></Button>\n </Tooltip>\n ),\n }}\n items={[\n {\n key: 'tree',\n label: (\n <Space>\n <Typography.Text>Tree Graph</Typography.Text>\n <Tooltip\n overlayStyle={{ maxWidth: 380 }}\n overlayInnerStyle={{ marginLeft: 16, padding: 10 }}\n color=\"white\"\n title={\n <Space direction=\"vertical\" color=\"white\" size=\"middle\">\n <Row>\n <Col>\n <Tag color=\"cyan\" style={{ margin: 0 }}>\n initial\n </Tag>\n <Typography.Text style={{ marginLeft: 4 }}>\n Identify whether the chunk is an initial chunk.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Tag color=\"green\" style={{ margin: 0 }}>\n concatenated\n </Tag>\n <Typography.Text style={{ marginLeft: 4 }}>\n Identify whether the module is a concatenated\n module\n </Typography.Text>\n <Tooltip\n overlayStyle={{ maxWidth: 408 }}\n placement=\"bottom\"\n color=\"white\"\n title={\n <Space direction=\"vertical\" color=\"white\">\n <Row>\n <Col>\n <Typography.Text strong>\n Concatenated Module\n </Typography.Text>\n <Typography.Text>\n : A performance optimization where\n multiple modules are merged (or\n \"hoisted\") into a single scope instead\n of wrapping each module in separate\n function closures. This reduces the\n bundle size and improves runtime\n performance by minimizing function call\n overhead.\n </Typography.Text>\n </Col>\n </Row>\n </Space>\n }\n >\n <InfoCircleOutlined\n style={{\n color: 'rgba(0,0,0,.45)',\n marginLeft: 4,\n }}\n />\n </Tooltip>\n <Typography.Text>.</Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Button\n size=\"small\"\n icon={<CodepenCircleOutlined />}\n />\n <Typography.Text style={{ marginLeft: 4 }}>\n Open the code.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Button\n size=\"small\"\n icon={<DeploymentUnitOutlined />}\n />\n <Typography.Text style={{ marginLeft: 4 }}>\n View the module dependency, that is, module\n reasons in stats.json.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Tag color={'purple'}>{'Bundled: 15.77 KB'}</Tag>\n <Typography.Text>\n The final size of the output files after\n processing, bundling, and optimization. This is\n what is delivered to the browser.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Tag color={'orange'}>{'Source: 60.46 KB'}</Tag>\n <Typography.Text>\n The original size of your source code files before\n any processing or transformations. This is the raw\n size of your code as you wrote it.\n </Typography.Text>\n </Col>\n </Row>\n </Space>\n }\n >\n <InfoCircleOutlined style={{ color: 'rgba(0,0,0,.45)' }} />\n </Tooltip>\n </Space>\n ),\n children: (\n <TreeGraph\n entryPoints={entryPoints}\n cwd={cwd}\n summary={summary}\n />\n ),\n },\n {\n key: 'treemap',\n label: 'Treemap',\n children: (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetProjectInfo}>\n {(data) => {\n const { isRspack, hasSourceMap } =\n Rspack.checkSourceMapSupport(data.configs);\n return (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetSummaryBundles}\n >\n {(data) => {\n // Filter assets to only show JS (js, cjs, mjs), .bundle, CSS, and HTML files\n const isTargetFileType = (\n filePath: string,\n ): boolean => {\n const ext =\n filePath.toLowerCase().split('.').pop() || '';\n return (\n ext === 'js' ||\n ext === 'cjs' ||\n ext === 'mjs' ||\n ext === 'bundle' ||\n ext === 'css' ||\n ext === 'html'\n );\n };\n\n const computedTreeData: TreeNode[] = data\n .filter((item) => isTargetFileType(item.asset.path))\n .map((item) => {\n const moduleTree = flattenTreemapData(\n item.modules,\n );\n const hasModules = item.modules.length > 0;\n return {\n name: item.asset.path,\n sourceSize: hasModules\n ? (moduleTree.sourceSize ?? 0)\n : item.asset.size,\n bundledSize: item.asset.size,\n gzipSize: item.asset.gzipSize ?? 0,\n children: moduleTree.children,\n };\n });\n return (\n <AssetTreemapWithFilter\n treeData={computedTreeData}\n bundledSize={hasSourceMap || isRspack}\n />\n );\n }}\n </ServerAPIProvider>\n );\n }}\n </ServerAPIProvider>\n ),\n },\n ]}\n defaultActiveKey=\"tree\"\n />\n </Card>\n </>\n );\n};\n\nexport const WebpackModulesOverall: React.FC = () => {\n const { project } = useProjectInfo();\n\n if (!project) {\n return null;\n }\n\n const { root, errors } = project;\n return (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetAssetsSummary}\n body={{ withFileContent: true }}\n >\n {(summary) => {\n return (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetEntryPoints}>\n {(entryPoints) => (\n <WebpackModulesOverallBase\n cwd={root}\n errors={errors}\n summary={summary}\n entryPoints={entryPoints}\n />\n )}\n </ServerAPIProvider>\n );\n }}\n </ServerAPIProvider>\n );\n};\n"],"names":["WebpackModulesOverallBase","errors","cwd","summary","entryPoints","expanded","setExpanded","usePersistedState","cardDomId","useId","expandActionText","React","BundleCards","Card","styles","Tabs","Tooltip","Button","ShrinkOutlined","ArrowsAltOutlined","String","Space","Typography","Row","Col","Tag","InfoCircleOutlined","CodepenCircleOutlined","DeploymentUnitOutlined","TreeGraph","ServerAPIProvider","SDK","data","isRspack","hasSourceMap","Rspack","isTargetFileType","filePath","ext","computedTreeData","item","moduleTree","flattenTreemapData","hasModules","AssetTreemapWithFilter","WebpackModulesOverall","project","useProjectInfo","root"],"mappings":"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"}
1
+ {"version":3,"file":"pages/BundleSize/components/index.mjs","sources":["../../../../src/pages/BundleSize/components/index.tsx"],"sourcesContent":["import {\n CodepenCircleOutlined,\n DeploymentUnitOutlined,\n InfoCircleOutlined,\n ShrinkOutlined,\n ArrowsAltOutlined,\n} from '@ant-design/icons';\nimport { type Client, SDK } from '@rsdoctor/types';\nimport {\n Button,\n Card,\n Col,\n Row,\n Space,\n Tag,\n Tooltip,\n Typography,\n Tabs,\n} from 'antd';\nimport React, { useId } from 'react';\nimport { ServerAPIProvider } from '../../../components/Manifest';\nimport { useProjectInfo } from '../../../components/Layout/project-info-context';\nimport { flattenTreemapData, usePersistedState } from '../../../utils';\nimport { BundleCards } from './cards';\nimport styles from './index.module.scss';\nimport './index.sass';\nimport {\n AssetTreemapWithFilter,\n TreeNode,\n} from 'src/components/Charts/TreeMap';\nimport { Rspack } from '@rsdoctor/utils/common';\nimport { TreeGraph } from './tree-graph';\nimport { isJavaScriptAsset } from '../../../utils/assets';\n\ninterface WebpackModulesOverallProps {\n cwd: string;\n errors: SDK.ErrorsData;\n summary: Client.RsdoctorClientAssetsSummary;\n entryPoints: SDK.ServerAPI.InferResponseType<SDK.ServerAPI.API.GetEntryPoints>;\n}\n\nexport const WebpackModulesOverallBase: React.FC<\n WebpackModulesOverallProps\n> = ({ errors, cwd, summary, entryPoints }) => {\n const [expanded, setExpanded] = usePersistedState(\n 'bundle-size-tabs-card-expanded',\n false,\n );\n const cardDomId = useId();\n const expandActionText = expanded ? 'Shrink card' : 'Expand card';\n return (\n <>\n <React.Activity mode={expanded ? 'hidden' : 'visible'}>\n <BundleCards cwd={cwd} errors={errors} summary={summary} />\n </React.Activity>\n <Card\n className={styles.root}\n classNames={{ body: styles.rootBody }}\n id={cardDomId}\n >\n <Tabs\n size=\"middle\"\n className={styles.tabsRoot}\n tabBarExtraContent={{\n right: (\n <Tooltip\n // the content collapses/expands, but the cursor stays at the same position (outside the button now, cause layout has shifted)\n // antd doesn't know that and keeps the tooltip open, so we need to force rerender it on every state change\n key={String(expanded)}\n title={expandActionText}\n >\n <Button\n // TODO:: does it make sense here? the content basically stays the same and we're actually controlling other elements\n aria-controls={cardDomId}\n aria-expanded={expanded}\n aria-label={expandActionText}\n onClick={() => setExpanded(!expanded)}\n icon={expanded ? <ShrinkOutlined /> : <ArrowsAltOutlined />}\n size=\"small\"\n ></Button>\n </Tooltip>\n ),\n }}\n items={[\n {\n key: 'tree',\n label: (\n <Space>\n <Typography.Text>Tree Graph</Typography.Text>\n <Tooltip\n overlayStyle={{ maxWidth: 380 }}\n overlayInnerStyle={{ marginLeft: 16, padding: 10 }}\n color=\"white\"\n title={\n <Space direction=\"vertical\" color=\"white\" size=\"middle\">\n <Row>\n <Col>\n <Tag color=\"cyan\" style={{ margin: 0 }}>\n initial\n </Tag>\n <Typography.Text style={{ marginLeft: 4 }}>\n Identify whether the chunk is an initial chunk.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Tag color=\"green\" style={{ margin: 0 }}>\n concatenated\n </Tag>\n <Typography.Text style={{ marginLeft: 4 }}>\n Identify whether the module is a concatenated\n module\n </Typography.Text>\n <Tooltip\n overlayStyle={{ maxWidth: 408 }}\n placement=\"bottom\"\n color=\"white\"\n title={\n <Space direction=\"vertical\" color=\"white\">\n <Row>\n <Col>\n <Typography.Text strong>\n Concatenated Module\n </Typography.Text>\n <Typography.Text>\n : A performance optimization where\n multiple modules are merged (or\n \"hoisted\") into a single scope instead\n of wrapping each module in separate\n function closures. This reduces the\n bundle size and improves runtime\n performance by minimizing function call\n overhead.\n </Typography.Text>\n </Col>\n </Row>\n </Space>\n }\n >\n <InfoCircleOutlined\n style={{\n color: 'rgba(0,0,0,.45)',\n marginLeft: 4,\n }}\n />\n </Tooltip>\n <Typography.Text>.</Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Button\n size=\"small\"\n icon={<CodepenCircleOutlined />}\n />\n <Typography.Text style={{ marginLeft: 4 }}>\n Open the code.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Button\n size=\"small\"\n icon={<DeploymentUnitOutlined />}\n />\n <Typography.Text style={{ marginLeft: 4 }}>\n View the module dependency, that is, module\n reasons in stats.json.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Tag color={'purple'}>{'Bundled: 15.77 KB'}</Tag>\n <Typography.Text>\n The final size of the output files after\n processing, bundling, and optimization. This is\n what is delivered to the browser.\n </Typography.Text>\n </Col>\n </Row>\n <Row>\n <Col>\n <Tag color={'orange'}>{'Source: 60.46 KB'}</Tag>\n <Typography.Text>\n The original size of your source code files before\n any processing or transformations. This is the raw\n size of your code as you wrote it.\n </Typography.Text>\n </Col>\n </Row>\n </Space>\n }\n >\n <InfoCircleOutlined style={{ color: 'rgba(0,0,0,.45)' }} />\n </Tooltip>\n </Space>\n ),\n children: (\n <TreeGraph\n entryPoints={entryPoints}\n cwd={cwd}\n summary={summary}\n />\n ),\n },\n {\n key: 'treemap',\n label: 'Treemap',\n children: (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetProjectInfo}>\n {(data) => {\n const { isRspack, hasSourceMap } =\n Rspack.checkSourceMapSupport(data.configs);\n return (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetSummaryBundles}\n >\n {(data) => {\n // Filter assets to only show JS (js, cjs, mjs), .bundle, CSS, and HTML files\n const isVisibleTreemapAsset = (filePath: string) => {\n const ext =\n filePath.toLowerCase().split('.').pop() || '';\n return (\n isJavaScriptAsset(filePath) ||\n ext === 'css' ||\n ext === 'html'\n );\n };\n\n const computedTreeData: TreeNode[] = data\n .filter((item) =>\n isVisibleTreemapAsset(item.asset.path),\n )\n .map((item) => {\n const moduleTree = flattenTreemapData(\n item.modules,\n );\n const hasModules = item.modules.length > 0;\n return {\n name: item.asset.path,\n sourceSize: hasModules\n ? (moduleTree.sourceSize ?? 0)\n : item.asset.size,\n bundledSize: item.asset.size,\n gzipSize: item.asset.gzipSize ?? 0,\n children: moduleTree.children,\n };\n });\n return (\n <AssetTreemapWithFilter\n treeData={computedTreeData}\n bundledSize={hasSourceMap || isRspack}\n />\n );\n }}\n </ServerAPIProvider>\n );\n }}\n </ServerAPIProvider>\n ),\n },\n ]}\n defaultActiveKey=\"tree\"\n />\n </Card>\n </>\n );\n};\n\nexport const WebpackModulesOverall: React.FC = () => {\n const { project } = useProjectInfo();\n\n if (!project) {\n return null;\n }\n\n const { root, errors } = project;\n return (\n <ServerAPIProvider\n api={SDK.ServerAPI.API.GetAssetsSummary}\n body={{ withFileContent: true }}\n >\n {(summary) => {\n return (\n <ServerAPIProvider api={SDK.ServerAPI.API.GetEntryPoints}>\n {(entryPoints) => (\n <WebpackModulesOverallBase\n cwd={root}\n errors={errors}\n summary={summary}\n entryPoints={entryPoints}\n />\n )}\n </ServerAPIProvider>\n );\n }}\n </ServerAPIProvider>\n );\n};\n"],"names":["WebpackModulesOverallBase","errors","cwd","summary","entryPoints","expanded","setExpanded","usePersistedState","cardDomId","useId","expandActionText","React","BundleCards","Card","styles","Tabs","Tooltip","Button","ShrinkOutlined","ArrowsAltOutlined","String","Space","Typography","Row","Col","Tag","InfoCircleOutlined","CodepenCircleOutlined","DeploymentUnitOutlined","TreeGraph","ServerAPIProvider","SDK","data","isRspack","hasSourceMap","Rspack","isVisibleTreemapAsset","filePath","ext","isJavaScriptAsset","computedTreeData","item","moduleTree","flattenTreemapData","hasModules","AssetTreemapWithFilter","WebpackModulesOverall","project","useProjectInfo","root"],"mappings":"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"}