From 899472c10f27badc1d25b49e25f77e1a2410e141 Mon Sep 17 00:00:00 2001 From: Denis Bardadym Date: Mon, 6 Jan 2025 14:40:24 +0100 Subject: [PATCH] Revert "Remove flamegraph, it does not bring any difference comparing to treemap or sunburst" This reverts commit 112ac3838d64b910fb78a04edcfa641ac21f60e8. --- CHANGELOG.md | 4 + plugin/render-template.ts | 1 + plugin/template-types.ts | 3 +- rollup.config-dev.js | 2 +- rollup.config.js | 2 +- src/flamegraph/chart.tsx | 56 + src/flamegraph/color.ts | 81 + src/flamegraph/const.ts | 2 + src/flamegraph/flamegraph.tsx | 39 + src/flamegraph/index.tsx | 124 + src/flamegraph/main.tsx | 99 + src/flamegraph/node.tsx | 103 + src/flamegraph/tooltip.tsx | 165 + test/__snapshots__/e2e-rolldown.test.ts.snap | 28202 ++++++++++------ test/__snapshots__/e2e.test.ts.snap | 28204 ++++++++++------ test/__snapshots__/gh59.test.ts.snap | 28234 +++++++++++------ test/__snapshots__/gh69.test.ts.snap | 28182 ++++++++++------ test/__snapshots__/gh93.test.ts.snap | 28084 ++++++++++------ test/util.ts | 2 +- 19 files changed, 94587 insertions(+), 47002 deletions(-) create mode 100644 src/flamegraph/chart.tsx create mode 100644 src/flamegraph/color.ts create mode 100644 src/flamegraph/const.ts create mode 100644 src/flamegraph/flamegraph.tsx create mode 100644 src/flamegraph/index.tsx create mode 100644 src/flamegraph/main.tsx create mode 100644 src/flamegraph/node.tsx create mode 100644 src/flamegraph/tooltip.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index ee18e16..56b7305 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.14.0 + +* Return `flamegraph` + ## 5.13.0 * Remove `flamegraph` template diff --git a/plugin/render-template.ts b/plugin/render-template.ts index 38833dc..ec00450 100644 --- a/plugin/render-template.ts +++ b/plugin/render-template.ts @@ -123,6 +123,7 @@ const TEMPLATE_TYPE_RENDERED: Record< treemap: buildHtml("treemap"), "raw-data": async ({ data }) => outputRawData(data), list: async ({ data }) => outputPlainTextList(data), + flamegraph: buildHtml("flamegraph"), }; export const renderTemplate = (templateType: TemplateType, options: RenderTemplateOptions) => { diff --git a/plugin/template-types.ts b/plugin/template-types.ts index fbc50bf..3a8fa5b 100644 --- a/plugin/template-types.ts +++ b/plugin/template-types.ts @@ -1,6 +1,6 @@ "use strict"; -export type TemplateType = "sunburst" | "treemap" | "network" | "raw-data" | "list"; +export type TemplateType = "sunburst" | "treemap" | "network" | "raw-data" | "list" | "flamegraph"; const templates: ReadonlyArray = [ "sunburst", @@ -8,6 +8,7 @@ const templates: ReadonlyArray = [ "network", "list", "raw-data", + "flamegraph", ]; export default templates; diff --git a/rollup.config-dev.js b/rollup.config-dev.js index 8abebb0..b9effad 100644 --- a/rollup.config-dev.js +++ b/rollup.config-dev.js @@ -6,7 +6,7 @@ const postcssUrl = require("postcss-url"); const { visualizer } = require("."); -const HTML_TEMPLATE = ["treemap", "sunburst", "network"]; +const HTML_TEMPLATE = ["treemap", "sunburst", "network", "flamegraph"]; const PLAIN_TEMPLATE = ["raw-data", "list"]; const ALL_TEMPLATE = [...HTML_TEMPLATE, ...PLAIN_TEMPLATE]; diff --git a/rollup.config.js b/rollup.config.js index 1deb19d..f37a15e 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,7 +4,7 @@ const typescript = require("@rollup/plugin-typescript"); const postcss = require("rollup-plugin-postcss"); const postcssUrl = require("postcss-url"); -const HTML_TEMPLATE = ["treemap", "sunburst", "network"]; +const HTML_TEMPLATE = ["treemap", "sunburst", "network", "flamegraph"]; /** @type {import('rollup').RollupOptions} */ module.exports = HTML_TEMPLATE.map((templateType) => ({ diff --git a/src/flamegraph/chart.tsx b/src/flamegraph/chart.tsx new file mode 100644 index 0000000..c2047d9 --- /dev/null +++ b/src/flamegraph/chart.tsx @@ -0,0 +1,56 @@ +import { FunctionalComponent } from "preact"; +import { useState, useEffect } from "preact/hooks"; +import { HierarchyRectangularNode } from "d3-hierarchy"; + +import { ModuleTree, ModuleTreeLeaf, SizeKey } from "../../shared/types"; +import { FlameGraph } from "./flamegraph"; +import { Tooltip } from "./tooltip"; + +export interface ChartProps { + root: HierarchyRectangularNode; + sizeProperty: SizeKey; + selectedNode: HierarchyRectangularNode | undefined; + setSelectedNode: ( + node: HierarchyRectangularNode | undefined, + ) => void; +} + +export const Chart: FunctionalComponent = ({ + root, + sizeProperty, + selectedNode, + setSelectedNode, +}) => { + const [showTooltip, setShowTooltip] = useState(false); + const [tooltipNode, setTooltipNode] = useState< + HierarchyRectangularNode | undefined + >(undefined); + + useEffect(() => { + const handleMouseOut = () => { + setShowTooltip(false); + }; + + document.addEventListener("mouseover", handleMouseOut); + return () => { + document.removeEventListener("mouseover", handleMouseOut); + }; + }, []); + + return ( + <> + { + setTooltipNode(node); + setShowTooltip(true); + }} + selectedNode={selectedNode} + onNodeClick={(node) => { + setSelectedNode(selectedNode === node ? undefined : node); + }} + /> + + + ); +}; diff --git a/src/flamegraph/color.ts b/src/flamegraph/color.ts new file mode 100644 index 0000000..0c621a0 --- /dev/null +++ b/src/flamegraph/color.ts @@ -0,0 +1,81 @@ +import { scaleSequential, scaleLinear } from "d3-scale"; +import { hsl, RGBColor } from "d3-color"; + +import { HierarchyNode } from "d3-hierarchy"; +import { COLOR_BASE, CssColor } from "../color"; +import { ModuleTree, ModuleTreeLeaf } from "../../shared/types"; + +// https://www.w3.org/TR/WCAG20/#relativeluminancedef +const rc = 0.2126; +const gc = 0.7152; +const bc = 0.0722; +// low-gamma adjust coefficient +const lowc = 1 / 12.92; + +function adjustGamma(p: number) { + return Math.pow((p + 0.055) / 1.055, 2.4); +} + +function relativeLuminance(o: RGBColor) { + const rsrgb = o.r / 255; + const gsrgb = o.g / 255; + const bsrgb = o.b / 255; + + const r = rsrgb <= 0.03928 ? rsrgb * lowc : adjustGamma(rsrgb); + const g = gsrgb <= 0.03928 ? gsrgb * lowc : adjustGamma(gsrgb); + const b = bsrgb <= 0.03928 ? bsrgb * lowc : adjustGamma(bsrgb); + + return r * rc + g * gc + b * bc; +} + +export interface NodeColor { + backgroundColor: CssColor; + fontColor: CssColor; +} + +export type NodeColorGetter = (node: HierarchyNode) => NodeColor; + +const createRainbowColor = (root: HierarchyNode): NodeColorGetter => { + const colorParentMap = new Map, CssColor>(); + colorParentMap.set(root, COLOR_BASE); + + if (root.children != null) { + const colorScale = scaleSequential([0, root.children.length], (n) => hsl(360 * n, 0.3, 0.85)); + root.children.forEach((c, id) => { + colorParentMap.set(c, colorScale(id).toString()); + }); + } + + const colorMap = new Map, NodeColor>(); + + const lightScale = scaleLinear().domain([0, root.height]).range([0.9, 0.3]); + + const getBackgroundColor = (node: HierarchyNode) => { + const parents = node.ancestors(); + const colorStr = + parents.length === 1 + ? colorParentMap.get(parents[0]) + : colorParentMap.get(parents[parents.length - 2]); + + const hslColor = hsl(colorStr as string); + hslColor.l = lightScale(node.depth); + + return hslColor; + }; + + return (node: HierarchyNode): NodeColor => { + if (!colorMap.has(node)) { + const backgroundColor = getBackgroundColor(node); + const l = relativeLuminance(backgroundColor.rgb()); + const fontColor = l > 0.19 ? "#000" : "#fff"; + colorMap.set(node, { + backgroundColor: backgroundColor.toString(), + fontColor, + }); + } + + return colorMap.get(node) as NodeColor; + }; +}; + +export default createRainbowColor; diff --git a/src/flamegraph/const.ts b/src/flamegraph/const.ts new file mode 100644 index 0000000..07a12fc --- /dev/null +++ b/src/flamegraph/const.ts @@ -0,0 +1,2 @@ +export const TOP_PADDING = 20; +export const PADDING = 2; diff --git a/src/flamegraph/flamegraph.tsx b/src/flamegraph/flamegraph.tsx new file mode 100644 index 0000000..494cc27 --- /dev/null +++ b/src/flamegraph/flamegraph.tsx @@ -0,0 +1,39 @@ +import { FunctionalComponent } from "preact"; +import { useContext } from "preact/hooks"; +import { HierarchyRectangularNode } from "d3-hierarchy"; + +import { ModuleTree, ModuleTreeLeaf } from "../../shared/types"; +import { Node } from "./node"; +import { StaticContext } from "./index"; + +export interface FlameGraphProps { + root: HierarchyRectangularNode; + onNodeHover: (event: HierarchyRectangularNode) => void; + selectedNode: HierarchyRectangularNode | undefined; + onNodeClick: (node: HierarchyRectangularNode) => void; +} + +export const FlameGraph: FunctionalComponent = ({ + root, + onNodeHover, + selectedNode, + onNodeClick, +}) => { + const { width, height, getModuleIds } = useContext(StaticContext); + + return ( + + {root.descendants().map((node) => { + return ( + + ); + })} + + ); +}; diff --git a/src/flamegraph/index.tsx b/src/flamegraph/index.tsx new file mode 100644 index 0000000..f5c28c4 --- /dev/null +++ b/src/flamegraph/index.tsx @@ -0,0 +1,124 @@ +import { createContext, render } from "preact"; +import { hierarchy, HierarchyNode, partition, PartitionLayout } from "d3-hierarchy"; +import { + isModuleTree, + ModuleLengths, + ModuleTree, + ModuleTreeLeaf, + SizeKey, + VisualizerData, +} from "../../shared/types"; + +import { generateUniqueId, Id } from "../uid"; +import { getAvailableSizeOptions } from "../sizes"; +import { Main } from "./main"; +import createRainbowColor, { NodeColorGetter } from "./color"; + +import "../style/style-flamegraph.scss"; +import { PADDING } from "./const"; + +export interface StaticData { + data: VisualizerData; + availableSizeProperties: SizeKey[]; + width: number; + height: number; +} + +export interface ModuleIds { + nodeUid: Id; + clipUid: Id; +} + +export interface ChartData { + layout: PartitionLayout; + rawHierarchy: HierarchyNode; + getModuleSize: (node: ModuleTree | ModuleTreeLeaf, sizeKey: SizeKey) => number; + getModuleIds: (node: ModuleTree | ModuleTreeLeaf) => ModuleIds; + getModuleColor: NodeColorGetter; +} + +export type Context = StaticData & ChartData; + +export const StaticContext = createContext({} as unknown as Context); + +const drawChart = ( + parentNode: Element, + data: VisualizerData, + width: number, + height: number, +): void => { + const availableSizeProperties = getAvailableSizeOptions(data.options); + + console.time("layout create"); + + const layout = partition() + .size([width, height]) + .padding(PADDING) + .round(true); + + console.timeEnd("layout create"); + + console.time("rawHierarchy create"); + const rawHierarchy = hierarchy(data.tree); + console.timeEnd("rawHierarchy create"); + + const nodeSizesCache = new Map(); + + const nodeIdsCache = new Map(); + + const getModuleSize = (node: ModuleTree | ModuleTreeLeaf, sizeKey: SizeKey) => + nodeSizesCache.get(node)?.[sizeKey] ?? 0; + + console.time("rawHierarchy eachAfter cache"); + rawHierarchy.eachAfter((node) => { + const nodeData = node.data; + + nodeIdsCache.set(nodeData, { + nodeUid: generateUniqueId("node"), + clipUid: generateUniqueId("clip"), + }); + + const sizes: ModuleLengths = { renderedLength: 0, gzipLength: 0, brotliLength: 0 }; + if (isModuleTree(nodeData)) { + for (const sizeKey of availableSizeProperties) { + sizes[sizeKey] = nodeData.children.reduce( + (acc, child) => getModuleSize(child, sizeKey) + acc, + 0, + ); + } + } else { + for (const sizeKey of availableSizeProperties) { + sizes[sizeKey] = data.nodeParts[nodeData.uid][sizeKey] ?? 0; + } + } + nodeSizesCache.set(nodeData, sizes); + }); + console.timeEnd("rawHierarchy eachAfter cache"); + + const getModuleIds = (node: ModuleTree | ModuleTreeLeaf) => nodeIdsCache.get(node) as ModuleIds; + + console.time("color"); + const getModuleColor = createRainbowColor(rawHierarchy); + console.timeEnd("color"); + + render( + +
+ , + parentNode, + ); +}; + +export default drawChart; diff --git a/src/flamegraph/main.tsx b/src/flamegraph/main.tsx new file mode 100644 index 0000000..fc4e7ad --- /dev/null +++ b/src/flamegraph/main.tsx @@ -0,0 +1,99 @@ +import { useContext, useMemo, useState } from "preact/hooks"; +import { HierarchyRectangularNode } from "d3-hierarchy"; + +import { FunctionalComponent } from "preact"; +import { SideBar } from "../sidebar"; +import { isModuleTree, ModuleTree, ModuleTreeLeaf, SizeKey } from "../../shared/types"; +import { useFilter } from "../use-filter"; +import { Chart } from "./chart"; + +import { StaticContext } from "./index"; + +export const Main: FunctionalComponent = () => { + const { availableSizeProperties, rawHierarchy, getModuleSize, layout, data } = + useContext(StaticContext); + + const [sizeProperty, setSizeProperty] = useState(availableSizeProperties[0]); + + const [selectedNode, setSelectedNode] = useState< + HierarchyRectangularNode | undefined + >(undefined); + + const { getModuleFilterMultiplier, setExcludeFilter, setIncludeFilter } = useFilter(); + + console.time("getNodeSizeMultiplier"); + const getNodeSizeMultiplier = useMemo(() => { + const selectedMultiplier = 1; // selectedSize < rootSize * increaseFactor ? (rootSize * increaseFactor) / selectedSize : rootSize / selectedSize; + const nonSelectedMultiplier = 0; // 1 / selectedMultiplier + + if (selectedNode === undefined) { + return (): number => 1; + } else if (isModuleTree(selectedNode.data)) { + const leaves = new Set(selectedNode.leaves().map((d) => d.data)); + return (node: ModuleTree | ModuleTreeLeaf): number => { + if (leaves.has(node)) { + return selectedMultiplier; + } + return nonSelectedMultiplier; + }; + } else { + return (node: ModuleTree | ModuleTreeLeaf): number => { + if (node === selectedNode.data) { + return selectedMultiplier; + } + return nonSelectedMultiplier; + }; + } + }, [getModuleSize, rawHierarchy.data, selectedNode, sizeProperty]); + console.timeEnd("getNodeSizeMultiplier"); + + console.time("root hierarchy compute"); + // root here always be the same as rawHierarchy even after layouting + const root = useMemo(() => { + const rootWithSizesAndSorted = rawHierarchy + .sum((node) => { + if (isModuleTree(node)) return 0; + + const meta = data.nodeMetas[data.nodeParts[node.uid].metaUid]; + /* eslint-disable typescript/no-non-null-asserted-optional-chain typescript/no-extra-non-null-assertion */ + const bundleId = Object.entries(meta.moduleParts).find(([, uid]) => uid == node.uid)?.[0]!!; + + const ownSize = getModuleSize(node, sizeProperty); + const zoomMultiplier = getNodeSizeMultiplier(node); + const filterMultiplier = getModuleFilterMultiplier(bundleId, meta); + + return ownSize * zoomMultiplier * filterMultiplier; + }) + .sort((a, b) => getModuleSize(a.data, sizeProperty) - getModuleSize(b.data, sizeProperty)); + + return layout(rootWithSizesAndSorted); + }, [ + data, + getModuleFilterMultiplier, + getModuleSize, + getNodeSizeMultiplier, + layout, + rawHierarchy, + sizeProperty, + ]); + + console.timeEnd("root hierarchy compute"); + + return ( + <> + + + + ); +}; diff --git a/src/flamegraph/node.tsx b/src/flamegraph/node.tsx new file mode 100644 index 0000000..ca817a5 --- /dev/null +++ b/src/flamegraph/node.tsx @@ -0,0 +1,103 @@ +/* eslint-disable react/no-unknown-property */ +import { FunctionalComponent } from "preact"; +import { useContext, useLayoutEffect, useRef } from "preact/hooks"; +import { HierarchyRectangularNode } from "d3-hierarchy"; +import { ModuleTree, ModuleTreeLeaf } from "../../shared/types"; +import { PADDING, TOP_PADDING } from "./const"; +import { StaticContext } from "."; + +type NodeEventHandler = (event: HierarchyRectangularNode) => void; + +export interface NodeProps { + node: HierarchyRectangularNode; + onMouseOver: NodeEventHandler; + selected: boolean; + onClick: NodeEventHandler; +} + +export const Node: FunctionalComponent = ({ node, onMouseOver, onClick, selected }) => { + const { getModuleColor } = useContext(StaticContext); + const { backgroundColor, fontColor } = getModuleColor(node); + const { x0, x1, y1, y0, data, children = null } = node; + + const textRef = useRef(null); + const textRectRef = useRef(); + + const width = x1 - x0; + const height = y1 - y0; + + const textProps: Record = { + "font-size": "0.7em", + "dominant-baseline": "middle", + "text-anchor": "middle", + x: width / 2, + }; + if (children != null) { + textProps.y = (TOP_PADDING + PADDING) / 2; + } else { + textProps.y = height / 2; + } + + useLayoutEffect(() => { + if (width == 0 || height == 0 || !textRef.current) { + return; + } + + if (textRectRef.current == null) { + textRectRef.current = textRef.current.getBoundingClientRect(); + } + + let scale = 1; + + scale = Math.min( + (width * 0.9) / textRectRef.current.width, + (height * 0.9) / textRectRef.current.height, + ); + scale = Math.min(1, scale); + textRef.current.setAttribute("y", String(height / 2 / scale)); + textRef.current.setAttribute("x", String(width / 2 / scale)); + + textRef.current.setAttribute("transform", `scale(${scale.toFixed(2)})`); + }, [children, height, width]); + + if (width == 0 || height == 0) { + return null; + } + + return ( + { + event.stopPropagation(); + onClick(node); + }} + onMouseOver={(event: MouseEvent) => { + event.stopPropagation(); + onMouseOver(node); + }} + > + + { + if (window.getSelection()?.toString() !== "") { + event.stopPropagation(); + } + }} + {...textProps} + > + {data.name} + + + ); +}; diff --git a/src/flamegraph/tooltip.tsx b/src/flamegraph/tooltip.tsx new file mode 100644 index 0000000..953e62c --- /dev/null +++ b/src/flamegraph/tooltip.tsx @@ -0,0 +1,165 @@ +import { useState, useRef, useEffect, useMemo, useContext } from "preact/hooks"; + +import { format as formatBytes } from "bytes"; + +import { FunctionalComponent } from "preact"; +import { HierarchyRectangularNode } from "d3-hierarchy"; +import { LABELS } from "../sizes"; +import { isModuleTree, ModuleTree, ModuleTreeLeaf, SizeKey } from "../../shared/types"; +import { StaticContext } from "."; + +export interface TooltipProps { + node?: HierarchyRectangularNode; + root: HierarchyRectangularNode; + sizeProperty: SizeKey; + visible: boolean; +} + +const Tooltip_marginX = 10; +const Tooltip_marginY = 30; + +const SOURCEMAP_RENDERED = ( + + {" "} + {LABELS.renderedLength} is a number of characters in the file after individual and
{" "} + whole bundle transformations according to sourcemap. +
+); + +const RENDRED = ( + + {LABELS.renderedLength} is a byte size of individual file after transformations and + treeshake. + +); + +const COMPRESSED = ( + + {LABELS.gzipLength} and {LABELS.brotliLength} is a byte size of individual file + after individual transformations, +
treeshake and compression. +
+); + +export const Tooltip: FunctionalComponent = ({ + node, + visible, + root, + sizeProperty, +}) => { + const { availableSizeProperties, getModuleSize, data } = useContext(StaticContext); + + const ref = useRef(null); + const [style, setStyle] = useState({}); + + const content = useMemo(() => { + if (!node) return null; + + const mainSize = getModuleSize(node.data, sizeProperty); + + const percentageNum = (100 * mainSize) / getModuleSize(root.data, sizeProperty); + const percentage = percentageNum.toFixed(2); + const percentageString = percentage + "%"; + + const path = node + .ancestors() + .reverse() + .map((d) => d.data.name) + .join("/"); + + let dataNode = null; + if (!isModuleTree(node.data)) { + const mainUid = data.nodeParts[node.data.uid].metaUid; + dataNode = data.nodeMetas[mainUid]; + } + + return ( + <> +
{path}
+ {availableSizeProperties.map((sizeProp) => { + if (sizeProp === sizeProperty) { + return ( +
+ + {LABELS[sizeProp]}: {formatBytes(mainSize)} + {" "} + ({percentageString}) +
+ ); + } else { + return ( +
+ {LABELS[sizeProp]}: {formatBytes(getModuleSize(node.data, sizeProp))} +
+ ); + } + })} +
+ {dataNode && dataNode.importedBy.length > 0 && ( +
+
+ Imported By: +
+ {dataNode.importedBy.map(({ uid }) => { + const id = data.nodeMetas[uid].id; + return
{id}
; + })} +
+ )} +
+ {data.options.sourcemap ? SOURCEMAP_RENDERED : RENDRED} + {(data.options.gzip || data.options.brotli) && ( + <> +
+ {COMPRESSED} + + )} + + ); + }, [availableSizeProperties, data, getModuleSize, node, root.data, sizeProperty]); + + const updatePosition = (mouseCoords: { x: number; y: number }) => { + if (!ref.current) return; + + const pos = { + left: mouseCoords.x + Tooltip_marginX, + top: mouseCoords.y + Tooltip_marginY, + }; + + const boundingRect = ref.current.getBoundingClientRect(); + + if (pos.left + boundingRect.width > window.innerWidth) { + // Shifting horizontally + pos.left = window.innerWidth - boundingRect.width; + } + + if (pos.top + boundingRect.height > window.innerHeight) { + // Flipping vertically + pos.top = mouseCoords.y - Tooltip_marginY - boundingRect.height; + } + + setStyle(pos); + }; + + useEffect(() => { + const handleMouseMove = (event: MouseEvent) => { + updatePosition({ + x: event.pageX, + y: event.pageY, + }); + }; + + document.addEventListener("mousemove", handleMouseMove, true); + return () => { + document.removeEventListener("mousemove", handleMouseMove, true); + }; + }, []); + + return ( +
+ {content} +
+ ); +}; + +export default Tooltip; diff --git a/test/__snapshots__/e2e-rolldown.test.ts.snap b/test/__snapshots__/e2e-rolldown.test.ts.snap index da6c84e..7f7c868 100644 --- a/test/__snapshots__/e2e-rolldown.test.ts.snap +++ b/test/__snapshots__/e2e-rolldown.test.ts.snap @@ -1,25 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`E2E > test - "list" 1`] = ` -"file3-XCd8Ebz0.js: - /test/e2e/file3.js: - rendered: 60 - gzip: 76 - brotli: 52 -input.js: - /test/e2e/input.js: - rendered: 78 - gzip: 91 - brotli: 69 -input2.js: - /test/e2e/input2.js: - rendered: 124 - gzip: 126 - brotli: 105 -" -`; - -exports[`E2E > test - "network" 1`] = ` +exports[`E2E > test - "flamegraph" 1`] = ` " @@ -169,10328 +150,19998 @@ main { + + + - case '**/.*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${DOT_LITERAL}\${ONE_CHAR}\${star}\`; +" +`; - default: { - const match = /^(.*?)\\.(\\w+)$/.exec(str); - if (!match) return; +exports[`E2E > test - "list" 1`] = ` +"file3-XCd8Ebz0.js: + /test/e2e/file3.js: + rendered: 60 + gzip: 76 + brotli: 52 +input.js: + /test/e2e/input.js: + rendered: 78 + gzip: 91 + brotli: 69 +input2.js: + /test/e2e/input2.js: + rendered: 124 + gzip: 126 + brotli: 105 +" +`; - const source = create(match[1]); - if (!source) return; +exports[`E2E > test - "network" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + + +" +`; + +exports[`E2E > test - "raw-data" 1`] = ` +"{ + "version": 2, + "tree": { + "name": "root", + "children": [ + { + "name": "input.js", + "children": [ + { + "name": "test/e2e/input.js", + "uid": "7665939b-1" + } + ] + }, + { + "name": "input2.js", + "children": [ + { + "name": "test/e2e/input2.js", + "uid": "7665939b-3" + } + ] + }, + { + "name": "file3-XCd8Ebz0.js", + "children": [ + { + "name": "test/e2e/file3.js", + "uid": "7665939b-5" + } + ] + } + ], + "isRoot": true + }, + "nodeParts": { + "7665939b-1": { + "renderedLength": 78, + "gzipLength": 91, + "brotliLength": 69, + "metaUid": "7665939b-0" + }, + "7665939b-3": { + "renderedLength": 124, + "gzipLength": 126, + "brotliLength": 105, + "metaUid": "7665939b-2" + }, + "7665939b-5": { + "renderedLength": 60, + "gzipLength": 76, + "brotliLength": 52, + "metaUid": "7665939b-4" + } + }, + "nodeMetas": { + "7665939b-0": { + "id": "/test/e2e/input.js", + "moduleParts": { + "input.js": "7665939b-1" + }, + "imported": [ + { + "uid": "7665939b-6" + }, + { + "uid": "7665939b-7" + } + ], + "importedBy": [], + "isEntry": true + }, + "7665939b-2": { + "id": "/test/e2e/input2.js", + "moduleParts": { + "input2.js": "7665939b-3" + }, + "imported": [ + { + "uid": "7665939b-4", + "dynamic": true + } + ], + "importedBy": [], + "isEntry": true + }, + "7665939b-4": { + "id": "/test/e2e/file3.js", + "moduleParts": { + "file3-XCd8Ebz0.js": "7665939b-5" + }, + "imported": [], + "importedBy": [ + { + "uid": "7665939b-2" + } + ] + }, + "7665939b-6": { + "id": "/test/e2e/node_modules/module/test.js", + "moduleParts": {}, + "imported": [], + "importedBy": [ + { + "uid": "7665939b-0" + } + ] + }, + "7665939b-7": { + "id": "jquery", + "moduleParts": {}, + "imported": [], + "importedBy": [ + { + "uid": "7665939b-0" + } + ] + } + }, + "env": { + "rollup": "4.23.0" + }, + "options": { + "gzip": true, + "brotli": true, + "sourcemap": false + } +}" +`; + +exports[`E2E > test - "sunburst" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ - - - + const output = utils.removePrefix(input, state); + let source = create(output); -" -`; + if (source && opts.strictSlashes !== true) { + source += \`\${SLASH_LITERAL}?\`; + } -exports[`E2E > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "input.js", - "children": [ - { - "name": "test/e2e/input.js", - "uid": "7665939b-1" - } - ] - }, - { - "name": "input2.js", - "children": [ - { - "name": "test/e2e/input2.js", - "uid": "7665939b-3" - } - ] - }, - { - "name": "file3-XCd8Ebz0.js", - "children": [ - { - "name": "test/e2e/file3.js", - "uid": "7665939b-5" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "7665939b-1": { - "renderedLength": 78, - "gzipLength": 91, - "brotliLength": 69, - "metaUid": "7665939b-0" - }, - "7665939b-3": { - "renderedLength": 124, - "gzipLength": 126, - "brotliLength": 105, - "metaUid": "7665939b-2" - }, - "7665939b-5": { - "renderedLength": 60, - "gzipLength": 76, - "brotliLength": 52, - "metaUid": "7665939b-4" - } - }, - "nodeMetas": { - "7665939b-0": { - "id": "/test/e2e/input.js", - "moduleParts": { - "input.js": "7665939b-1" - }, - "imported": [ - { - "uid": "7665939b-6" - }, - { - "uid": "7665939b-7" - } - ], - "importedBy": [], - "isEntry": true - }, - "7665939b-2": { - "id": "/test/e2e/input2.js", - "moduleParts": { - "input2.js": "7665939b-3" - }, - "imported": [ - { - "uid": "7665939b-4", - "dynamic": true - } - ], - "importedBy": [], - "isEntry": true - }, - "7665939b-4": { - "id": "/test/e2e/file3.js", - "moduleParts": { - "file3-XCd8Ebz0.js": "7665939b-5" - }, - "imported": [], - "importedBy": [ - { - "uid": "7665939b-2" - } - ] - }, - "7665939b-6": { - "id": "/test/e2e/node_modules/module/test.js", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "7665939b-0" - } - ] - }, - "7665939b-7": { - "id": "jquery", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "7665939b-0" - } - ] - } - }, - "env": { - "rollup": "4.23.0" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false + return source; + }; + + parse_1 = parse; + return parse_1; } -}" -`; -exports[`E2E > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- + + + - let dx = r * Math.cos(a0), - dy = r * Math.sin(a0), - x0 = x + dx, - y0 = y + dy, - cw = 1 ^ ccw, - da = ccw ? a0 - a1 : a1 - a0; +" +`; - // Is this path empty? Move to (x0,y0). - if (this._x1 === null) { - this._append\`M\${x0},\${y0}\`; - } +exports[`E2E > test - "treemap" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + - case '**/.*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${DOT_LITERAL}\${ONE_CHAR}\${star}\`; +" +`; - default: { - const match = /^(.*?)\\.(\\w+)$/.exec(str); - if (!match) return; +exports[`E2E > test - "list" 1`] = ` +"file3-Bi_Qu0hn.js: + /test/e2e/file3.js: + rendered: 18 + gzip: 38 + brotli: 22 +input.js: + /test/e2e/input.js: + rendered: 66 + gzip: 80 + brotli: 67 +input2.js: + /test/e2e/input2.js: + rendered: 80 + gzip: 96 + brotli: 84 +" +`; - const source = create(match[1]); - if (!source) return; +exports[`E2E > test - "network" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + + +" +`; + +exports[`E2E > test - "raw-data" 1`] = ` +"{ + "version": 2, + "tree": { + "name": "root", + "children": [ + { + "name": "input.js", + "children": [ + { + "name": "test/e2e/input.js", + "uid": "04193cf6-1" + } + ] + }, + { + "name": "input2.js", + "children": [ + { + "name": "test/e2e/input2.js", + "uid": "04193cf6-3" + } + ] + }, + { + "name": "file3-Bi_Qu0hn.js", + "children": [ + { + "name": "test/e2e/file3.js", + "uid": "04193cf6-5" + } + ] + } + ], + "isRoot": true + }, + "nodeParts": { + "04193cf6-1": { + "renderedLength": 66, + "gzipLength": 80, + "brotliLength": 67, + "metaUid": "04193cf6-0" + }, + "04193cf6-3": { + "renderedLength": 80, + "gzipLength": 96, + "brotliLength": 84, + "metaUid": "04193cf6-2" + }, + "04193cf6-5": { + "renderedLength": 18, + "gzipLength": 38, + "brotliLength": 22, + "metaUid": "04193cf6-4" + } + }, + "nodeMetas": { + "04193cf6-0": { + "id": "/test/e2e/input.js", + "moduleParts": { + "input.js": "04193cf6-1" + }, + "imported": [ + { + "uid": "04193cf6-6" + }, + { + "uid": "04193cf6-7" + } + ], + "importedBy": [], + "isEntry": true + }, + "04193cf6-2": { + "id": "/test/e2e/input2.js", + "moduleParts": { + "input2.js": "04193cf6-3" + }, + "imported": [ + { + "uid": "04193cf6-4", + "dynamic": true + } + ], + "importedBy": [], + "isEntry": true + }, + "04193cf6-4": { + "id": "/test/e2e/file3.js", + "moduleParts": { + "file3-Bi_Qu0hn.js": "04193cf6-5" + }, + "imported": [], + "importedBy": [ + { + "uid": "04193cf6-2" + } + ] + }, + "04193cf6-6": { + "id": "/test/e2e/node_modules/module/test.js", + "moduleParts": {}, + "imported": [], + "importedBy": [ + { + "uid": "04193cf6-0" + } + ] + }, + "04193cf6-7": { + "id": "jquery", + "moduleParts": {}, + "imported": [], + "importedBy": [ + { + "uid": "04193cf6-0" + } + ], + "isExternal": true + } + }, + "env": { + "rollup": "4.29.1" + }, + "options": { + "gzip": true, + "brotli": true, + "sourcemap": false + } +}" +`; + +exports[`E2E > test - "sunburst" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ - - - + const output = utils.removePrefix(input, state); + let source = create(output); -" -`; + if (source && opts.strictSlashes !== true) { + source += \`\${SLASH_LITERAL}?\`; + } -exports[`E2E > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "input.js", - "children": [ - { - "name": "test/e2e/input.js", - "uid": "04193cf6-1" - } - ] - }, - { - "name": "input2.js", - "children": [ - { - "name": "test/e2e/input2.js", - "uid": "04193cf6-3" - } - ] - }, - { - "name": "file3-Bi_Qu0hn.js", - "children": [ - { - "name": "test/e2e/file3.js", - "uid": "04193cf6-5" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "04193cf6-1": { - "renderedLength": 66, - "gzipLength": 80, - "brotliLength": 67, - "metaUid": "04193cf6-0" - }, - "04193cf6-3": { - "renderedLength": 80, - "gzipLength": 96, - "brotliLength": 84, - "metaUid": "04193cf6-2" - }, - "04193cf6-5": { - "renderedLength": 18, - "gzipLength": 38, - "brotliLength": 22, - "metaUid": "04193cf6-4" - } - }, - "nodeMetas": { - "04193cf6-0": { - "id": "/test/e2e/input.js", - "moduleParts": { - "input.js": "04193cf6-1" - }, - "imported": [ - { - "uid": "04193cf6-6" - }, - { - "uid": "04193cf6-7" - } - ], - "importedBy": [], - "isEntry": true - }, - "04193cf6-2": { - "id": "/test/e2e/input2.js", - "moduleParts": { - "input2.js": "04193cf6-3" - }, - "imported": [ - { - "uid": "04193cf6-4", - "dynamic": true - } - ], - "importedBy": [], - "isEntry": true - }, - "04193cf6-4": { - "id": "/test/e2e/file3.js", - "moduleParts": { - "file3-Bi_Qu0hn.js": "04193cf6-5" - }, - "imported": [], - "importedBy": [ - { - "uid": "04193cf6-2" - } - ] - }, - "04193cf6-6": { - "id": "/test/e2e/node_modules/module/test.js", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "04193cf6-0" - } - ] - }, - "04193cf6-7": { - "id": "jquery", - "moduleParts": {}, - "imported": [], - "importedBy": [ - { - "uid": "04193cf6-0" - } - ], - "isExternal": true - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false + return source; + }; + + parse_1 = parse; + return parse_1; } -}" -`; -exports[`E2E > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- + + + - let dx = r * Math.cos(a0), - dy = r * Math.sin(a0), - x0 = x + dx, - y0 = y + dy, - cw = 1 ^ ccw, - da = ccw ? a0 - a1 : a1 - a0; +" +`; - // Is this path empty? Move to (x0,y0). - if (this._x1 === null) { - this._append\`M\${x0},\${y0}\`; - } +exports[`E2E > test - "treemap" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + - case '**/*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${slashDot}\${ONE_CHAR}\${star}\`; +" +`; - case '**/*.*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${slashDot}\${star}\${DOT_LITERAL}\${ONE_CHAR}\${star}\`; +exports[`GH-59 > test - "list" 1`] = ` +"components/A.js: + /test/gh59/src/components/A.js: + rendered: 12 + gzip: 32 + brotli: 16 +components/B.js: + /test/gh59/src/components/B.js: + rendered: 12 + gzip: 32 + brotli: 16 +components/index.js: + /test/gh59/src/components/index.js: + rendered: 0 + gzip: 0 + brotli: 0 +index.js: + /test/gh59/src/index.js: + rendered: 18 + gzip: 38 + brotli: 22 +" +`; - case '**/.*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${DOT_LITERAL}\${ONE_CHAR}\${star}\`; +exports[`GH-59 > test - "network" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + + +" +`; + +exports[`GH-59 > test - "raw-data" 1`] = ` +"{ + "version": 2, + "tree": { + "name": "root", + "children": [ + { + "name": "components/index.js", + "children": [ + { + "name": "test/gh59/src/components/index.js", + "uid": "dea430a7-1" + } + ] + }, + { + "name": "index.js", + "children": [ + { + "name": "test/gh59/src/index.js", + "uid": "dea430a7-3" + } + ] + }, + { + "name": "components/A.js", + "children": [ + { + "name": "test/gh59/src/components/A.js", + "uid": "dea430a7-5" + } + ] + }, + { + "name": "components/B.js", + "children": [ + { + "name": "test/gh59/src/components/B.js", + "uid": "dea430a7-7" + } + ] + } + ], + "isRoot": true + }, + "nodeParts": { + "dea430a7-1": { + "renderedLength": 0, + "gzipLength": 0, + "brotliLength": 0, + "metaUid": "dea430a7-0" + }, + "dea430a7-3": { + "renderedLength": 18, + "gzipLength": 38, + "brotliLength": 22, + "metaUid": "dea430a7-2" + }, + "dea430a7-5": { + "renderedLength": 12, + "gzipLength": 32, + "brotliLength": 16, + "metaUid": "dea430a7-4" + }, + "dea430a7-7": { + "renderedLength": 12, + "gzipLength": 32, + "brotliLength": 16, + "metaUid": "dea430a7-6" + } + }, + "nodeMetas": { + "dea430a7-0": { + "id": "/test/gh59/src/components/index.js", + "moduleParts": { + "components/index.js": "dea430a7-1" + }, + "imported": [ + { + "uid": "dea430a7-4" + }, + { + "uid": "dea430a7-6" + } + ], + "importedBy": [ + { + "uid": "dea430a7-2" + } + ], + "isEntry": true + }, + "dea430a7-2": { + "id": "/test/gh59/src/index.js", + "moduleParts": { + "index.js": "dea430a7-3" + }, + "imported": [ + { + "uid": "dea430a7-0" + } + ], + "importedBy": [], + "isEntry": true + }, + "dea430a7-4": { + "id": "/test/gh59/src/components/A.js", + "moduleParts": { + "components/A.js": "dea430a7-5" + }, + "imported": [], + "importedBy": [ + { + "uid": "dea430a7-0" + } + ], + "isEntry": true + }, + "dea430a7-6": { + "id": "/test/gh59/src/components/B.js", + "moduleParts": { + "components/B.js": "dea430a7-7" + }, + "imported": [], + "importedBy": [ + { + "uid": "dea430a7-0" + } + ], + "isEntry": true + } + }, + "env": { + "rollup": "4.29.1" + }, + "options": { + "gzip": true, + "brotli": true, + "sourcemap": false + } +}" +`; + +exports[`GH-59 > test - "sunburst" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ - - - + function requirePicomatch$1 () { + if (hasRequiredPicomatch$1) return picomatch_1$1; + hasRequiredPicomatch$1 = 1; -" -`; + const scan = /*@__PURE__*/ requireScan(); + const parse = /*@__PURE__*/ requireParse(); + const utils = /*@__PURE__*/ requireUtils(); + const constants = /*@__PURE__*/ requireConstants(); + const isObject = val => val && typeof val === 'object' && !Array.isArray(val); -exports[`GH-59 > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "components/index.js", - "children": [ - { - "name": "test/gh59/src/components/index.js", - "uid": "dea430a7-1" - } - ] - }, - { - "name": "index.js", - "children": [ - { - "name": "test/gh59/src/index.js", - "uid": "dea430a7-3" - } - ] - }, - { - "name": "components/A.js", - "children": [ - { - "name": "test/gh59/src/components/A.js", - "uid": "dea430a7-5" - } - ] - }, - { - "name": "components/B.js", - "children": [ - { - "name": "test/gh59/src/components/B.js", - "uid": "dea430a7-7" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "dea430a7-1": { - "renderedLength": 0, - "gzipLength": 0, - "brotliLength": 0, - "metaUid": "dea430a7-0" - }, - "dea430a7-3": { - "renderedLength": 18, - "gzipLength": 38, - "brotliLength": 22, - "metaUid": "dea430a7-2" - }, - "dea430a7-5": { - "renderedLength": 12, - "gzipLength": 32, - "brotliLength": 16, - "metaUid": "dea430a7-4" - }, - "dea430a7-7": { - "renderedLength": 12, - "gzipLength": 32, - "brotliLength": 16, - "metaUid": "dea430a7-6" - } - }, - "nodeMetas": { - "dea430a7-0": { - "id": "/test/gh59/src/components/index.js", - "moduleParts": { - "components/index.js": "dea430a7-1" - }, - "imported": [ - { - "uid": "dea430a7-4" - }, - { - "uid": "dea430a7-6" - } - ], - "importedBy": [ - { - "uid": "dea430a7-2" - } - ], - "isEntry": true - }, - "dea430a7-2": { - "id": "/test/gh59/src/index.js", - "moduleParts": { - "index.js": "dea430a7-3" - }, - "imported": [ - { - "uid": "dea430a7-0" - } - ], - "importedBy": [], - "isEntry": true - }, - "dea430a7-4": { - "id": "/test/gh59/src/components/A.js", - "moduleParts": { - "components/A.js": "dea430a7-5" - }, - "imported": [], - "importedBy": [ - { - "uid": "dea430a7-0" - } - ], - "isEntry": true - }, - "dea430a7-6": { - "id": "/test/gh59/src/components/B.js", - "moduleParts": { - "components/B.js": "dea430a7-7" - }, - "imported": [], - "importedBy": [ - { - "uid": "dea430a7-0" - } - ], - "isEntry": true - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; + /** + * Creates a matcher function from one or more glob patterns. The + * returned function takes a string to match as its first argument, + * and returns true if the string is a match. The returned matcher + * function also takes a boolean as the second argument that, when true, + * returns an object with additional information. + * + * \`\`\`js + * const picomatch = require('picomatch'); + * // picomatch(glob[, options]); + * + * const isMatch = picomatch('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * \`\`\` + * @name picomatch + * @param {String|Array} \`globs\` One or more glob patterns. + * @param {Object=} \`options\` + * @return {Function=} Returns a matcher function. + * @api public + */ + + const picomatch = (glob, options, returnState = false) => { + if (Array.isArray(glob)) { + const fns = glob.map(input => picomatch(input, options, returnState)); + const arrayMatcher = str => { + for (const isMatch of fns) { + const state = isMatch(str); + if (state) return state; + } + return false; + }; + return arrayMatcher; + } + + const isState = isObject(glob) && glob.tokens && glob.input; + + if (glob === '' || (typeof glob !== 'string' && !isState)) { + throw new TypeError('Expected pattern to be a non-empty string'); + } + + const opts = options || {}; + const posix = opts.windows; + const regex = isState + ? picomatch.compileRe(glob, options) + : picomatch.makeRe(glob, options, false, true); + + const state = regex.state; + delete regex.state; + + let isIgnored = () => false; + if (opts.ignore) { + const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; + isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); + } + + const matcher = (input, returnObject = false) => { + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const result = { glob, state, regex, posix, input, output, match, isMatch }; -exports[`GH-59 > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- + + + - let dx = r * Math.cos(a0), - dy = r * Math.sin(a0), - x0 = x + dx, - y0 = y + dy, - cw = 1 ^ ccw, - da = ccw ? a0 - a1 : a1 - a0; +" +`; - // Is this path empty? Move to (x0,y0). - if (this._x1 === null) { - this._append\`M\${x0},\${y0}\`; - } +exports[`GH-59 > test - "treemap" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + - case '**/*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${slashDot}\${ONE_CHAR}\${star}\`; +" +`; - case '**/*.*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${slashDot}\${star}\${DOT_LITERAL}\${ONE_CHAR}\${star}\`; +exports[`GH-69 > test - "list" 1`] = ` +"dynamic-AB-Kuj6Y.js: + /test/gh69/dynamic.js: + rendered: 6 + gzip: 26 + brotli: 10 +main.js: + /test/gh69/lib.js: + rendered: 86 + gzip: 73 + brotli: 67 + /test/gh69/main.js: + rendered: 84 + gzip: 98 + brotli: 88 +" +`; - case '**/.*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${DOT_LITERAL}\${ONE_CHAR}\${star}\`; +exports[`GH-69 > test - "network" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + + +" +`; + +exports[`GH-69 > test - "raw-data" 1`] = ` +"{ + "version": 2, + "tree": { + "name": "root", + "children": [ + { + "name": "main.js", + "children": [ + { + "name": "test/gh69", + "children": [ + { + "uid": "9be6dbea-1", + "name": "lib.js" + }, + { + "uid": "9be6dbea-3", + "name": "main.js" + } + ] + } + ] + }, + { + "name": "dynamic-AB-Kuj6Y.js", + "children": [ + { + "name": "test/gh69/dynamic.js", + "uid": "9be6dbea-5" + } + ] + } + ], + "isRoot": true + }, + "nodeParts": { + "9be6dbea-1": { + "renderedLength": 86, + "gzipLength": 73, + "brotliLength": 67, + "metaUid": "9be6dbea-0" + }, + "9be6dbea-3": { + "renderedLength": 84, + "gzipLength": 98, + "brotliLength": 88, + "metaUid": "9be6dbea-2" + }, + "9be6dbea-5": { + "renderedLength": 6, + "gzipLength": 26, + "brotliLength": 10, + "metaUid": "9be6dbea-4" + } + }, + "nodeMetas": { + "9be6dbea-0": { + "id": "/test/gh69/lib.js", + "moduleParts": { + "main.js": "9be6dbea-1" + }, + "imported": [], + "importedBy": [ + { + "uid": "9be6dbea-2" + }, + { + "uid": "9be6dbea-4" + } + ] + }, + "9be6dbea-2": { + "id": "/test/gh69/main.js", + "moduleParts": { + "main.js": "9be6dbea-3" + }, + "imported": [ + { + "uid": "9be6dbea-0" + }, + { + "uid": "9be6dbea-4", + "dynamic": true + } + ], + "importedBy": [], + "isEntry": true + }, + "9be6dbea-4": { + "id": "/test/gh69/dynamic.js", + "moduleParts": { + "dynamic-AB-Kuj6Y.js": "9be6dbea-5" + }, + "imported": [ + { + "uid": "9be6dbea-0" + } + ], + "importedBy": [ + { + "uid": "9be6dbea-2" + } + ] + } + }, + "env": { + "rollup": "4.29.1" + }, + "options": { + "gzip": true, + "brotli": true, + "sourcemap": false + } +}" +`; + +exports[`GH-69 > test - "sunburst" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ - - - + if (isIgnored(input)) { + if (typeof opts.onIgnore === 'function') { + opts.onIgnore(result); + } + result.isMatch = false; + return returnObject ? result : false; + } -" -`; + if (typeof opts.onMatch === 'function') { + opts.onMatch(result); + } + return returnObject ? result : true; + }; + + if (returnState) { + matcher.state = state; + } + + return matcher; + }; + + /** + * Test \`input\` with the given \`regex\`. This is used by the main + * \`picomatch()\` function to test the input string. + * + * \`\`\`js + * const picomatch = require('picomatch'); + * // picomatch.test(input, regex[, options]); + * + * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\\/([^/]*?))$/)); + * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } + * \`\`\` + * @param {String} \`input\` String to test. + * @param {RegExp} \`regex\` + * @return {Object} Returns an object with matching info. + * @api public + */ + + picomatch.test = (input, regex, options, { glob, posix } = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected input to be a string'); + } + + if (input === '') { + return { isMatch: false, output: '' }; + } + + const opts = options || {}; + const format = opts.format || (posix ? utils.toPosixSlashes : null); + let match = input === glob; + let output = (match && format) ? format(input) : input; + + if (match === false) { + output = format ? format(input) : input; + match = output === glob; + } + + if (match === false || opts.capture === true) { + if (opts.matchBase === true || opts.basename === true) { + match = picomatch.matchBase(input, regex, options, posix); + } else { + match = regex.exec(output); + } + } + + return { isMatch: Boolean(match), match, output }; + }; + + /** + * Match the basename of a filepath. + * + * \`\`\`js + * const picomatch = require('picomatch'); + * // picomatch.matchBase(input, glob[, options]); + * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true + * \`\`\` + * @param {String} \`input\` String to test. + * @param {RegExp|String} \`glob\` Glob pattern or regex created by [.makeRe](#makeRe). + * @return {Boolean} + * @api public + */ + + picomatch.matchBase = (input, glob, options) => { + const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); + return regex.test(utils.basename(input)); + }; + + /** + * Returns true if **any** of the given glob \`patterns\` match the specified \`string\`. + * + * \`\`\`js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * \`\`\` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match \`str\` + * @api public + */ + + picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); -exports[`GH-69 > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "main.js", - "children": [ - { - "name": "test/gh69", - "children": [ - { - "uid": "9be6dbea-1", - "name": "lib.js" - }, - { - "uid": "9be6dbea-3", - "name": "main.js" - } - ] - } - ] - }, - { - "name": "dynamic-AB-Kuj6Y.js", - "children": [ - { - "name": "test/gh69/dynamic.js", - "uid": "9be6dbea-5" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "9be6dbea-1": { - "renderedLength": 86, - "gzipLength": 73, - "brotliLength": 67, - "metaUid": "9be6dbea-0" - }, - "9be6dbea-3": { - "renderedLength": 84, - "gzipLength": 98, - "brotliLength": 88, - "metaUid": "9be6dbea-2" - }, - "9be6dbea-5": { - "renderedLength": 6, - "gzipLength": 26, - "brotliLength": 10, - "metaUid": "9be6dbea-4" - } - }, - "nodeMetas": { - "9be6dbea-0": { - "id": "/test/gh69/lib.js", - "moduleParts": { - "main.js": "9be6dbea-1" - }, - "imported": [], - "importedBy": [ - { - "uid": "9be6dbea-2" - }, - { - "uid": "9be6dbea-4" - } - ] - }, - "9be6dbea-2": { - "id": "/test/gh69/main.js", - "moduleParts": { - "main.js": "9be6dbea-3" - }, - "imported": [ - { - "uid": "9be6dbea-0" - }, - { - "uid": "9be6dbea-4", - "dynamic": true - } - ], - "importedBy": [], - "isEntry": true - }, - "9be6dbea-4": { - "id": "/test/gh69/dynamic.js", - "moduleParts": { - "dynamic-AB-Kuj6Y.js": "9be6dbea-5" - }, - "imported": [ - { - "uid": "9be6dbea-0" - } - ], - "importedBy": [ - { - "uid": "9be6dbea-2" - } - ] - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; + /** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * \`\`\`js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * \`\`\` + * @param {String} \`pattern\` + * @param {Object} \`options\` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ -exports[`GH-69 > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- + + + - let dx = r * Math.cos(a0), - dy = r * Math.sin(a0), - x0 = x + dx, - y0 = y + dy, - cw = 1 ^ ccw, - da = ccw ? a0 - a1 : a1 - a0; +" +`; - // Is this path empty? Move to (x0,y0). - if (this._x1 === null) { - this._append\`M\${x0},\${y0}\`; - } +exports[`GH-69 > test - "treemap" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + - case '**/.*': - return \`(?:\${nodot}\${globstar(opts)}\${SLASH_LITERAL})?\${DOT_LITERAL}\${ONE_CHAR}\${star}\`; +" +`; - default: { - const match = /^(.*?)\\.(\\w+)$/.exec(str); - if (!match) return; +exports[`GH-93 > test - "list" 1`] = ` +"main.js: + /test/gh93/main.js: + rendered: 50 + gzip: 66 + brotli: 54 +virtual-id-a3e40_3s.js: + virtual-id: + rendered: 26 + gzip: 46 + brotli: 30 +" +`; - const source = create(match[1]); - if (!source) return; +exports[`GH-93 > test - "network" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ + + + + +" +`; + +exports[`GH-93 > test - "raw-data" 1`] = ` +"{ + "version": 2, + "tree": { + "name": "root", + "children": [ + { + "name": "main.js", + "children": [ + { + "name": "test/gh93/main.js", + "uid": "3acc92b5-1" + } + ] + }, + { + "name": "virtual-id-a3e40_3s.js", + "children": [ + { + "uid": "3acc92b5-3", + "name": "virtual-id" + } + ] + } + ], + "isRoot": true + }, + "nodeParts": { + "3acc92b5-1": { + "renderedLength": 50, + "gzipLength": 66, + "brotliLength": 54, + "metaUid": "3acc92b5-0" + }, + "3acc92b5-3": { + "renderedLength": 26, + "gzipLength": 46, + "brotliLength": 30, + "metaUid": "3acc92b5-2" + } + }, + "nodeMetas": { + "3acc92b5-0": { + "id": "/test/gh93/main.js", + "moduleParts": { + "main.js": "3acc92b5-1" + }, + "imported": [], + "importedBy": [], + "isEntry": true + }, + "3acc92b5-2": { + "id": "virtual-id", + "moduleParts": { + "virtual-id-a3e40_3s.js": "3acc92b5-3" + }, + "imported": [], + "importedBy": [], + "isEntry": true + } + }, + "env": { + "rollup": "4.29.1" + }, + "options": { + "gzip": true, + "brotli": true, + "sourcemap": false + } +}" +`; + +exports[`GH-93 > test - "sunburst" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+ - - - + /** + * Returns true if **any** of the given glob \`patterns\` match the specified \`string\`. + * + * \`\`\`js + * const picomatch = require('picomatch'); + * // picomatch.isMatch(string, patterns[, options]); + * + * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false + * \`\`\` + * @param {String|Array} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match \`str\` + * @api public + */ -" -`; + picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); -exports[`GH-93 > test - "raw-data" 1`] = ` -"{ - "version": 2, - "tree": { - "name": "root", - "children": [ - { - "name": "main.js", - "children": [ - { - "name": "test/gh93/main.js", - "uid": "3acc92b5-1" - } - ] - }, - { - "name": "virtual-id-a3e40_3s.js", - "children": [ - { - "uid": "3acc92b5-3", - "name": "virtual-id" - } - ] - } - ], - "isRoot": true - }, - "nodeParts": { - "3acc92b5-1": { - "renderedLength": 50, - "gzipLength": 66, - "brotliLength": 54, - "metaUid": "3acc92b5-0" - }, - "3acc92b5-3": { - "renderedLength": 26, - "gzipLength": 46, - "brotliLength": 30, - "metaUid": "3acc92b5-2" - } - }, - "nodeMetas": { - "3acc92b5-0": { - "id": "/test/gh93/main.js", - "moduleParts": { - "main.js": "3acc92b5-1" - }, - "imported": [], - "importedBy": [], - "isEntry": true - }, - "3acc92b5-2": { - "id": "virtual-id", - "moduleParts": { - "virtual-id-a3e40_3s.js": "3acc92b5-3" - }, - "imported": [], - "importedBy": [], - "isEntry": true - } - }, - "env": { - "rollup": "4.29.1" - }, - "options": { - "gzip": true, - "brotli": true, - "sourcemap": false - } -}" -`; + /** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * \`\`\`js + * const picomatch = require('picomatch'); + * const result = picomatch.parse(pattern[, options]); + * \`\`\` + * @param {String} \`pattern\` + * @param {Object} \`options\` + * @return {Object} Returns an object with useful properties and output to be used as a regex source string. + * @api public + */ -exports[`GH-93 > test - "sunburst" 1`] = ` -" - - - - - - - Rollup Visualizer - - - -
- + + + - let dx = r * Math.cos(a0), - dy = r * Math.sin(a0), - x0 = x + dx, - y0 = y + dy, - cw = 1 ^ ccw, - da = ccw ? a0 - a1 : a1 - a0; +" +`; - // Is this path empty? Move to (x0,y0). - if (this._x1 === null) { - this._append\`M\${x0},\${y0}\`; - } +exports[`GH-93 > test - "treemap" 1`] = ` +" + + + + + + + Rollup Visualizer + + + +
+