@automattic/charts 0.53.0 → 0.53.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/charts/bar-chart/index.cjs +5 -5
  3. package/dist/charts/bar-chart/index.d.cts +1 -1
  4. package/dist/charts/bar-chart/index.d.ts +1 -1
  5. package/dist/charts/bar-chart/index.js +4 -4
  6. package/dist/charts/bar-list-chart/index.cjs +6 -6
  7. package/dist/charts/bar-list-chart/index.d.cts +1 -1
  8. package/dist/charts/bar-list-chart/index.d.ts +1 -1
  9. package/dist/charts/bar-list-chart/index.js +5 -5
  10. package/dist/charts/conversion-funnel-chart/index.cjs +4 -4
  11. package/dist/charts/conversion-funnel-chart/index.d.cts +1 -1
  12. package/dist/charts/conversion-funnel-chart/index.d.ts +1 -1
  13. package/dist/charts/conversion-funnel-chart/index.js +3 -3
  14. package/dist/charts/geo-chart/index.cjs +13 -0
  15. package/dist/charts/geo-chart/index.cjs.map +1 -0
  16. package/dist/charts/geo-chart/index.css +8 -0
  17. package/dist/charts/geo-chart/index.css.map +1 -0
  18. package/dist/charts/geo-chart/index.d.cts +62 -0
  19. package/dist/charts/geo-chart/index.d.ts +62 -0
  20. package/dist/charts/geo-chart/index.js +13 -0
  21. package/dist/charts/geo-chart/index.js.map +1 -0
  22. package/dist/charts/leaderboard-chart/index.cjs +5 -5
  23. package/dist/charts/leaderboard-chart/index.d.cts +2 -2
  24. package/dist/charts/leaderboard-chart/index.d.ts +2 -2
  25. package/dist/charts/leaderboard-chart/index.js +4 -4
  26. package/dist/charts/line-chart/index.cjs +5 -5
  27. package/dist/charts/line-chart/index.d.cts +1 -1
  28. package/dist/charts/line-chart/index.d.ts +1 -1
  29. package/dist/charts/line-chart/index.js +4 -4
  30. package/dist/charts/pie-chart/index.cjs +6 -6
  31. package/dist/charts/pie-chart/index.d.cts +1 -1
  32. package/dist/charts/pie-chart/index.d.ts +1 -1
  33. package/dist/charts/pie-chart/index.js +5 -5
  34. package/dist/charts/pie-semi-circle-chart/index.cjs +6 -6
  35. package/dist/charts/pie-semi-circle-chart/index.d.cts +1 -1
  36. package/dist/charts/pie-semi-circle-chart/index.d.ts +1 -1
  37. package/dist/charts/pie-semi-circle-chart/index.js +5 -5
  38. package/dist/{chunk-ERGEUE7R.cjs → chunk-4KEE36W3.cjs} +19 -19
  39. package/dist/chunk-4KEE36W3.cjs.map +1 -0
  40. package/dist/{chunk-4RYV2TII.js → chunk-6RKPV3UP.js} +10 -10
  41. package/dist/{chunk-VER6S543.js → chunk-ALDWCNLH.js} +3 -3
  42. package/dist/chunk-CLSMJQCO.cjs +121 -0
  43. package/dist/chunk-CLSMJQCO.cjs.map +1 -0
  44. package/dist/{chunk-2FRTJVQ3.js → chunk-DCZ47KPZ.js} +6 -6
  45. package/dist/chunk-DCZ47KPZ.js.map +1 -0
  46. package/dist/{chunk-GWNXOI4M.cjs → chunk-DDV5726Q.cjs} +25 -25
  47. package/dist/{chunk-GWNXOI4M.cjs.map → chunk-DDV5726Q.cjs.map} +1 -1
  48. package/dist/{chunk-O2BJMTIS.js → chunk-DYMJWNYM.js} +2 -2
  49. package/dist/{chunk-A7X3CNEO.cjs → chunk-FVWTBK44.cjs} +6 -6
  50. package/dist/{chunk-A7X3CNEO.cjs.map → chunk-FVWTBK44.cjs.map} +1 -1
  51. package/dist/{chunk-ZN7KVU4R.cjs → chunk-GX4XTD6V.cjs} +76 -76
  52. package/dist/{chunk-ZN7KVU4R.cjs.map → chunk-GX4XTD6V.cjs.map} +1 -1
  53. package/dist/{chunk-VTMJWCCW.js → chunk-H6XRINJE.js} +10 -10
  54. package/dist/{chunk-CQPKK55N.js → chunk-HPJ5XSZM.js} +60 -60
  55. package/dist/{chunk-CQPKK55N.js.map → chunk-HPJ5XSZM.js.map} +1 -1
  56. package/dist/{chunk-6QCSXXDY.cjs → chunk-JWMWOBAX.cjs} +23 -23
  57. package/dist/{chunk-6QCSXXDY.cjs.map → chunk-JWMWOBAX.cjs.map} +1 -1
  58. package/dist/{chunk-DY7IVYWP.js → chunk-KBORJZKC.js} +8 -8
  59. package/dist/{chunk-W4ZYJ74Q.js → chunk-KORG7ITC.js} +3 -3
  60. package/dist/{chunk-AHUSYMYS.cjs → chunk-LNLHCZ6F.cjs} +28 -28
  61. package/dist/{chunk-AHUSYMYS.cjs.map → chunk-LNLHCZ6F.cjs.map} +1 -1
  62. package/dist/chunk-RDJ5PKC5.js +121 -0
  63. package/dist/chunk-RDJ5PKC5.js.map +1 -0
  64. package/dist/{chunk-P3QEXFTA.js → chunk-TE63Y5PX.js} +9 -1
  65. package/dist/chunk-TE63Y5PX.js.map +1 -0
  66. package/dist/{chunk-O23EGQ3H.cjs → chunk-UWAZGLHG.cjs} +22 -22
  67. package/dist/{chunk-O23EGQ3H.cjs.map → chunk-UWAZGLHG.cjs.map} +1 -1
  68. package/dist/{chunk-W3H42XRV.cjs → chunk-WKN6C4ZE.cjs} +10 -10
  69. package/dist/{chunk-W3H42XRV.cjs.map → chunk-WKN6C4ZE.cjs.map} +1 -1
  70. package/dist/{chunk-RHQIACQT.js → chunk-Z34VYZGR.js} +9 -9
  71. package/dist/{chunk-NYZFVI2P.cjs → chunk-ZPJHWKEK.cjs} +9 -9
  72. package/dist/{chunk-NYZFVI2P.cjs.map → chunk-ZPJHWKEK.cjs.map} +1 -1
  73. package/dist/{chunk-DAKYGZG6.cjs → chunk-ZVGEDXDP.cjs} +10 -2
  74. package/dist/chunk-ZVGEDXDP.cjs.map +1 -0
  75. package/dist/components/legend/index.cjs +4 -4
  76. package/dist/components/legend/index.d.cts +1 -1
  77. package/dist/components/legend/index.d.ts +1 -1
  78. package/dist/components/legend/index.js +3 -3
  79. package/dist/components/tooltip/index.d.cts +1 -1
  80. package/dist/components/tooltip/index.d.ts +1 -1
  81. package/dist/hooks/index.cjs +3 -3
  82. package/dist/hooks/index.d.cts +1 -1
  83. package/dist/hooks/index.d.ts +1 -1
  84. package/dist/hooks/index.js +2 -2
  85. package/dist/index.cjs +26 -126
  86. package/dist/index.cjs.map +1 -1
  87. package/dist/index.d.cts +15 -55
  88. package/dist/index.d.ts +15 -55
  89. package/dist/index.js +38 -138
  90. package/dist/index.js.map +1 -1
  91. package/dist/{leaderboard-chart-3dKYMfoP.d.cts → leaderboard-chart-CN80sJmQ.d.cts} +1 -1
  92. package/dist/{leaderboard-chart-BqH8BLiG.d.ts → leaderboard-chart-DPi2ueOg.d.ts} +1 -1
  93. package/dist/providers/index.cjs +3 -3
  94. package/dist/providers/index.d.cts +2 -2
  95. package/dist/providers/index.d.ts +2 -2
  96. package/dist/providers/index.js +2 -2
  97. package/dist/{themes-ChB_VjWt.d.ts → themes-AriuFXQ2.d.ts} +2 -2
  98. package/dist/{themes-DijSDhqQ.d.cts → themes-Dzg0wE3B.d.cts} +2 -2
  99. package/dist/{types-sQ20gAeB.d.cts → types-D1lTxRyg.d.cts} +1 -1
  100. package/dist/{types-sQ20gAeB.d.ts → types-D1lTxRyg.d.ts} +1 -1
  101. package/dist/utils/index.cjs +4 -2
  102. package/dist/utils/index.cjs.map +1 -1
  103. package/dist/utils/index.d.cts +11 -2
  104. package/dist/utils/index.d.ts +11 -2
  105. package/dist/utils/index.js +3 -1
  106. package/package.json +31 -23
  107. package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +2 -5
  108. package/src/charts/sparkline/sparkline.tsx +2 -0
  109. package/src/charts/sparkline/types.ts +8 -0
  110. package/src/utils/color-utils.ts +19 -0
  111. package/src/utils/test/color-utils.test.ts +232 -0
  112. package/dist/chunk-2FRTJVQ3.js.map +0 -1
  113. package/dist/chunk-DAKYGZG6.cjs.map +0 -1
  114. package/dist/chunk-ERGEUE7R.cjs.map +0 -1
  115. package/dist/chunk-P3QEXFTA.js.map +0 -1
  116. /package/dist/{chunk-4RYV2TII.js.map → chunk-6RKPV3UP.js.map} +0 -0
  117. /package/dist/{chunk-VER6S543.js.map → chunk-ALDWCNLH.js.map} +0 -0
  118. /package/dist/{chunk-O2BJMTIS.js.map → chunk-DYMJWNYM.js.map} +0 -0
  119. /package/dist/{chunk-VTMJWCCW.js.map → chunk-H6XRINJE.js.map} +0 -0
  120. /package/dist/{chunk-DY7IVYWP.js.map → chunk-KBORJZKC.js.map} +0 -0
  121. /package/dist/{chunk-W4ZYJ74Q.js.map → chunk-KORG7ITC.js.map} +0 -0
  122. /package/dist/{chunk-RHQIACQT.js.map → chunk-Z34VYZGR.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/jetpack/jetpack/projects/js-packages/charts/dist/chunk-AHUSYMYS.cjs","../src/charts/line-chart/line-chart.tsx","../src/charts/private/default-glyph/default-glyph.tsx","../src/charts/line-chart/line-chart.module.scss","../src/charts/line-chart/private/line-chart-annotation-label-popover.tsx","../src/charts/line-chart/private/line-chart-annotations-overlay.tsx","../src/charts/line-chart/private/line-chart-annotation.tsx","../src/charts/line-chart/private/line-chart-glyph.tsx"],"names":["jsx","useEffect","useRef","yMax","xMax","x","y","yMin","xMin","jsxs","useContext"],"mappings":"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","file":"/home/runner/work/jetpack/jetpack/projects/js-packages/charts/dist/chunk-AHUSYMYS.cjs","sourcesContent":[null,"import { formatNumberCompact, formatNumber } from '@automattic/number-formatters';\nimport { curveCatmullRom, curveLinear, curveMonotoneX } from '@visx/curve';\nimport { LinearGradient } from '@visx/gradient';\nimport { scaleTime } from '@visx/scale';\nimport { XYChart, AreaSeries, Grid, Axis, DataContext } from '@visx/xychart';\nimport { __ } from '@wordpress/i18n';\nimport clsx from 'clsx';\nimport { differenceInHours, differenceInYears } from 'date-fns';\nimport { useMemo, useContext, forwardRef, useImperativeHandle, useState, useRef } from 'react';\nimport { Legend, useChartLegendItems } from '../../components/legend';\nimport { AccessibleTooltip, useKeyboardNavigation } from '../../components/tooltip';\nimport {\n\tuseXYChartTheme,\n\tuseChartDataTransform,\n\tuseChartMargin,\n\tuseElementHeight,\n\tusePrefersReducedMotion,\n} from '../../hooks';\nimport {\n\tGlobalChartsProvider,\n\tGlobalChartsContext,\n\tuseChartId,\n\tuseChartRegistration,\n\tuseGlobalChartsContext,\n\tuseGlobalChartsTheme,\n} from '../../providers';\nimport { attachSubComponents } from '../../utils';\nimport { DefaultGlyph } from '../private/default-glyph';\nimport { SingleChartContext, type SingleChartRef } from '../private/single-chart-context';\nimport { withResponsive } from '../private/with-responsive';\nimport styles from './line-chart.module.scss';\nimport { LineChartAnnotation, LineChartAnnotationsOverlay, LineChartGlyph } from './private';\nimport type { CurveType, RenderLineGlyphProps, LineChartProps, TooltipDatum } from './types';\nimport type { DataPoint, DataPointDate, SeriesData, Optional } from '../../types';\nimport type { ResponsiveConfig } from '../private/with-responsive';\nimport type { TickFormatter } from '@visx/axis';\nimport type { GlyphProps } from '@visx/xychart';\nimport type { RenderTooltipParams } from '@visx/xychart/lib/components/Tooltip';\nimport type { FC, Ref } from 'react';\n\nconst X_TICK_WIDTH = 60;\n\nconst defaultRenderGlyph = < Datum extends object >( props: RenderLineGlyphProps< Datum > ) => {\n\treturn <DefaultGlyph { ...props } key={ props.key } />;\n};\n\nconst toNumber = ( val?: number | string | null ): number | undefined => {\n\tconst num = typeof val === 'number' ? val : parseFloat( val );\n\treturn isNaN( num ) ? undefined : num;\n};\n\n/**\n * Determines the curve type for the line chart based on the provided type and smoothing parameters\n *\n * @param {CurveType} type - The explicit curve type to use\n * @param {boolean} smoothing - Legacy smoothing parameter\n * @return The curve function to use for the line\n */\nconst getCurveType = ( type?: CurveType, smoothing?: boolean ) => {\n\t// If no type specified, use legacy smoothing behavior\n\tif ( ! type ) {\n\t\treturn smoothing ? curveCatmullRom : curveLinear;\n\t}\n\n\t// Handle explicit curve types\n\tswitch ( type ) {\n\t\tcase 'smooth':\n\t\t\treturn curveCatmullRom;\n\t\tcase 'monotone':\n\t\t\treturn curveMonotoneX;\n\t\tcase 'linear':\n\t\t\treturn curveLinear;\n\t\tdefault:\n\t\t\treturn curveLinear;\n\t}\n};\n\nconst renderDefaultTooltip = ( params: RenderTooltipParams< DataPointDate > ) => {\n\tconst { tooltipData } = params;\n\tconst nearestDatum = tooltipData?.nearestDatum?.datum;\n\tif ( ! nearestDatum ) return null;\n\n\tconst tooltipPoints: TooltipDatum[] = Object.entries( tooltipData?.datumByKey || {} )\n\t\t.map( ( [ key, { datum } ] ) => ( {\n\t\t\tkey,\n\t\t\tvalue: datum.value as number,\n\t\t} ) )\n\t\t.sort( ( a, b ) => b.value - a.value );\n\n\treturn (\n\t\t<div className={ styles[ 'line-chart__tooltip' ] }>\n\t\t\t<div className={ styles[ 'line-chart__tooltip-date' ] }>\n\t\t\t\t{ nearestDatum.date?.toLocaleDateString() }\n\t\t\t</div>\n\t\t\t{ tooltipPoints.map( point => (\n\t\t\t\t<div key={ point.key } className={ styles[ 'line-chart__tooltip-row' ] }>\n\t\t\t\t\t<span className={ styles[ 'line-chart__tooltip-label' ] }>{ point.key }:</span>\n\t\t\t\t\t<span className={ styles[ 'line-chart__tooltip-value' ] }>\n\t\t\t\t\t\t{ formatNumber( point.value ) }\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t) ) }\n\t\t</div>\n\t);\n};\n\nconst formatYearTick = ( timestamp: number ) => {\n\tconst date = new Date( timestamp );\n\treturn date.toLocaleDateString( undefined, {\n\t\tyear: 'numeric',\n\t} );\n};\n\nconst formatDateTick = ( timestamp: number ) => {\n\tconst date = new Date( timestamp );\n\treturn date.toLocaleDateString( undefined, {\n\t\tmonth: 'short',\n\t\tday: 'numeric',\n\t} );\n};\n\nconst formatHourTick = ( timestamp: number ) => {\n\tconst date = new Date( timestamp );\n\treturn date.toLocaleTimeString( undefined, {\n\t\thour: 'numeric',\n\t\thour12: true,\n\t} );\n};\n\nconst getFormatter = ( sortedData: ReturnType< typeof useChartDataTransform > ) => {\n\tconst minX = Math.min( ...sortedData.map( datom => datom.data.at( 0 )?.date ) );\n\tconst maxX = Math.max( ...sortedData.map( datom => datom.data.at( -1 )?.date ) );\n\n\tconst diffInHours = Math.abs( differenceInHours( maxX, minX ) );\n\tif ( diffInHours <= 24 ) {\n\t\treturn formatHourTick;\n\t}\n\n\tconst diffInYears = Math.abs( differenceInYears( maxX, minX ) );\n\tif ( diffInYears <= 1 ) {\n\t\treturn formatDateTick;\n\t}\n\n\treturn formatYearTick;\n};\n\nconst guessOptimalNumTicks = (\n\tdata: ReturnType< typeof useChartDataTransform >,\n\tchartWidth: number,\n\ttickFormatter: ( timestamp: number, index?: number, values?: unknown ) => string\n) => {\n\tconst minX = Math.min( ...data.map( datom => datom.data.at( 0 )?.date ) );\n\tconst maxX = Math.max( ...data.map( datom => datom.data.at( -1 )?.date ) );\n\tconst xScale = scaleTime( { domain: [ minX, maxX ] } );\n\n\t// Calculate upper bound of tick numbers based on data points and chart width\n\tconst upperBound = Math.min(\n\t\tdata[ 0 ]?.data.length || 3, // A sane fallback to avoid NaN when no data is present\n\t\tMath.ceil( chartWidth / X_TICK_WIDTH )\n\t);\n\tlet secondBestGuess = 1; // a tick number that's no greater than upperBound\n\n\tfor ( let numTicks = upperBound; numTicks > 1; --numTicks ) {\n\t\tconst ticks = xScale.ticks( numTicks ).map( d => tickFormatter( d.getTime() ) );\n\n\t\t// The .ticks() function doesn't properly respect the requested number of ticks, so we need to check the length\n\t\tif ( ticks.length > upperBound ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tsecondBestGuess = Math.max( secondBestGuess, ticks.length );\n\n\t\tconst uniqueTicks = Array.from( new Set( ticks ) );\n\t\tif ( uniqueTicks.length === 1 ) {\n\t\t\t// All ticks are the same, so skip further processing\n\t\t\treturn 1;\n\t\t}\n\n\t\t// Example: OCT 1 JAN 1 APR 1 JUL 1 OCT 1\n\t\t// Here, the two OCTs are not duplicates as they represent October of two different years.\n\t\tconst hasConsecutiveDuplicate = ticks.some(\n\t\t\t( tick, idx ) => idx > 0 && tick === ticks[ idx - 1 ]\n\t\t);\n\n\t\tif ( hasConsecutiveDuplicate ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn ticks.length;\n\t}\n\n\treturn secondBestGuess;\n};\n\nconst validateData = ( data: SeriesData[] ) => {\n\tif ( ! data?.length ) return 'No data available';\n\n\tconst hasInvalidData = data.some( series =>\n\t\tseries.data.some(\n\t\t\t( point: DataPointDate | DataPoint ) =>\n\t\t\t\tisNaN( point.value as number ) ||\n\t\t\t\tpoint.value === null ||\n\t\t\t\tpoint.value === undefined ||\n\t\t\t\t( 'date' in point && point.date && isNaN( point.date.getTime() ) )\n\t\t)\n\t);\n\n\tif ( hasInvalidData ) return 'Invalid data';\n\treturn null;\n};\n\n// Inner component to access DataContext and provide scale data to ref\nconst LineChartScalesRef: FC< {\n\tchartRef?: Ref< SingleChartRef >;\n\twidth: number;\n\theight: number;\n\tmargin?: { top?: number; right?: number; bottom?: number; left?: number };\n} > = ( { chartRef, width, height, margin } ) => {\n\tconst context = useContext( DataContext );\n\n\tuseImperativeHandle(\n\t\tchartRef,\n\t\t() => ( {\n\t\t\tgetScales: () => {\n\t\t\t\tif ( ! context?.xScale || ! context?.yScale ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\txScale: context.xScale,\n\t\t\t\t\tyScale: context.yScale,\n\t\t\t\t};\n\t\t\t},\n\t\t\tgetChartDimensions: () => ( {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tmargin: margin || {},\n\t\t\t} ),\n\t\t} ),\n\t\t[ context, width, height, margin ]\n\t);\n\n\treturn null; // This component only provides the ref interface\n};\n\nconst LineChartInternal = forwardRef< SingleChartRef, LineChartProps >(\n\t(\n\t\t{\n\t\t\tdata,\n\t\t\tchartId: providedChartId,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tclassName,\n\t\t\tmargin,\n\t\t\twithTooltips = true,\n\t\t\twithTooltipCrosshairs,\n\t\t\tshowLegend = false,\n\t\t\tlegendOrientation = 'horizontal',\n\t\t\tlegendAlignment = 'center',\n\t\t\tlegendPosition = 'bottom',\n\t\t\tlegendMaxWidth,\n\t\t\tlegendTextOverflow = 'wrap',\n\t\t\tlegendItemClassName,\n\t\t\trenderGlyph = defaultRenderGlyph,\n\t\t\tglyphStyle = {},\n\t\t\tlegendShape = 'line',\n\t\t\twithLegendGlyph = false,\n\t\t\twithGradientFill = false,\n\t\t\tsmoothing = true,\n\t\t\tcurveType,\n\t\t\trenderTooltip = renderDefaultTooltip,\n\t\t\twithStartGlyphs = false,\n\t\t\twithEndGlyphs = false,\n\t\t\tlegendInteractive = false,\n\t\t\tanimation,\n\t\t\toptions = {},\n\t\t\tonPointerDown = undefined,\n\t\t\tonPointerUp = undefined,\n\t\t\tonPointerMove = undefined,\n\t\t\tonPointerOut = undefined,\n\t\t\tchildren,\n\t\t\tgridVisibility,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst providerTheme = useGlobalChartsTheme();\n\t\tconst theme = useXYChartTheme( data );\n\t\tconst chartId = useChartId( providedChartId );\n\t\tconst [ legendRef, legendHeight ] = useElementHeight< HTMLDivElement >();\n\t\tconst chartRef = useRef< HTMLDivElement >( null );\n\t\tconst [ selectedIndex, setSelectedIndex ] = useState< number | undefined >( undefined );\n\t\tconst [ isNavigating, setIsNavigating ] = useState( false );\n\t\tconst internalChartRef = useRef< SingleChartRef >( null );\n\n\t\t// Forward the external ref to the internal ref\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ( {\n\t\t\t\tgetScales: () => internalChartRef.current?.getScales() || null,\n\t\t\t\tgetChartDimensions: () =>\n\t\t\t\t\tinternalChartRef.current?.getChartDimensions() || { width: 0, height: 0, margin: {} },\n\t\t\t} ),\n\t\t\t[ internalChartRef ]\n\t\t);\n\n\t\tconst dataSorted = useChartDataTransform( data );\n\t\tconst { getElementStyles, isSeriesVisible } = useGlobalChartsContext();\n\n\t\t// Add visibility information to series when using interactive legends\n\t\tconst seriesWithVisibility = useMemo( () => {\n\t\t\tif ( ! chartId || ! legendInteractive ) {\n\t\t\t\treturn dataSorted.map( ( series, index ) => ( { series, index, isVisible: true } ) );\n\t\t\t}\n\t\t\treturn dataSorted.map( ( series, index ) => ( {\n\t\t\t\tseries,\n\t\t\t\tindex,\n\t\t\t\tisVisible: isSeriesVisible( chartId, series.label ),\n\t\t\t} ) );\n\t\t}, [ dataSorted, chartId, isSeriesVisible, legendInteractive ] );\n\n\t\t// Check if all series are hidden\n\t\tconst allSeriesHidden = useMemo( () => {\n\t\t\treturn seriesWithVisibility.every( ( { isVisible } ) => ! isVisible );\n\t\t}, [ seriesWithVisibility ] );\n\n\t\t// Use the keyboard navigation hook\n\t\tconst { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation( {\n\t\t\tselectedIndex,\n\t\t\tsetSelectedIndex,\n\t\t\tisNavigating,\n\t\t\tsetIsNavigating,\n\t\t\tchartRef,\n\t\t\ttotalPoints: dataSorted[ 0 ]?.data.length || 0,\n\t\t} );\n\n\t\tconst chartOptions = useMemo( () => {\n\t\t\tconst formatter = options?.axis?.x?.tickFormat || getFormatter( dataSorted );\n\n\t\t\treturn {\n\t\t\t\taxis: {\n\t\t\t\t\tx: {\n\t\t\t\t\t\torientation: 'bottom' as const,\n\t\t\t\t\t\tnumTicks: guessOptimalNumTicks( dataSorted, width, formatter ),\n\t\t\t\t\t\ttickFormat: formatter,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t...options?.axis?.x,\n\t\t\t\t\t},\n\t\t\t\t\ty: {\n\t\t\t\t\t\torientation: 'left' as const,\n\t\t\t\t\t\tnumTicks: 4,\n\t\t\t\t\t\ttickFormat: formatNumberCompact as TickFormatter< number >,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t...options?.axis?.y,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\txScale: {\n\t\t\t\t\ttype: 'time' as const,\n\t\t\t\t\t...options?.xScale,\n\t\t\t\t},\n\t\t\t\tyScale: {\n\t\t\t\t\ttype: 'linear' as const,\n\t\t\t\t\tnice: true,\n\t\t\t\t\tzero: false,\n\t\t\t\t\t...options?.yScale,\n\t\t\t\t},\n\t\t\t};\n\t\t}, [ options, dataSorted, width ] );\n\n\t\tconst tooltipRenderGlyph = useMemo( () => {\n\t\t\treturn ( props: GlyphProps< DataPointDate > ) => {\n\t\t\t\tconst seriesIndex = dataSorted.findIndex(\n\t\t\t\t\tseries =>\n\t\t\t\t\t\tseries.label === props.key || series.data.includes( props.datum as DataPointDate )\n\t\t\t\t);\n\n\t\t\t\tconst seriesData = dataSorted[ seriesIndex ];\n\n\t\t\t\tconst { color, glyph: themeGlyph } = getElementStyles( {\n\t\t\t\t\tdata: seriesData,\n\t\t\t\t\tindex: seriesIndex,\n\t\t\t\t} );\n\n\t\t\t\tconst propsWithResolvedColor = { ...props, color };\n\n\t\t\t\treturn themeGlyph\n\t\t\t\t\t? themeGlyph( propsWithResolvedColor )\n\t\t\t\t\t: renderGlyph( propsWithResolvedColor );\n\t\t\t};\n\t\t}, [ dataSorted, renderGlyph, getElementStyles ] );\n\n\t\tconst defaultMargin = useChartMargin( height, chartOptions, dataSorted, theme );\n\n\t\tconst error = validateData( dataSorted );\n\t\tconst isDataValid = ! error;\n\n\t\t// Memoize legend options to prevent unnecessary re-calculations\n\t\tconst legendOptions = useMemo(\n\t\t\t() => ( {\n\t\t\t\twithGlyph: withLegendGlyph,\n\t\t\t\tglyphSize: Math.max( 0, toNumber( glyphStyle?.radius ) ?? 4 ),\n\t\t\t\trenderGlyph,\n\t\t\t} ),\n\t\t\t[ withLegendGlyph, glyphStyle?.radius, renderGlyph ]\n\t\t);\n\n\t\t// Create legend items using the reusable hook\n\t\tconst legendItems = useChartLegendItems( dataSorted, legendOptions, legendShape );\n\n\t\t// Memoize metadata to prevent unnecessary re-registration\n\t\tconst chartMetadata = useMemo(\n\t\t\t() => ( {\n\t\t\t\twithGradientFill,\n\t\t\t\tsmoothing,\n\t\t\t\tcurveType,\n\t\t\t\twithStartGlyphs,\n\t\t\t\twithEndGlyphs,\n\t\t\t\twithLegendGlyph,\n\t\t\t} ),\n\t\t\t[ withGradientFill, smoothing, curveType, withStartGlyphs, withEndGlyphs, withLegendGlyph ]\n\t\t);\n\n\t\t// Register chart with context only if data is valid\n\t\tuseChartRegistration( {\n\t\t\tchartId,\n\t\t\tlegendItems,\n\t\t\tchartType: 'line',\n\t\t\tisDataValid,\n\t\t\tmetadata: chartMetadata,\n\t\t} );\n\n\t\tconst prefersReducedMotion = usePrefersReducedMotion();\n\n\t\tconst accessors = {\n\t\t\txAccessor: ( d: DataPointDate ) => d?.date,\n\t\t\tyAccessor: ( d: DataPointDate ) => d?.value,\n\t\t};\n\n\t\t// Create a custom renderTooltip that includes focus capability\n\t\tif ( error ) {\n\t\t\treturn <div className={ clsx( 'line-chart', styles[ 'line-chart' ] ) }>{ error }</div>;\n\t\t}\n\n\t\treturn (\n\t\t\t<SingleChartContext.Provider\n\t\t\t\tvalue={ {\n\t\t\t\t\tchartId,\n\t\t\t\t\tchartRef: internalChartRef,\n\t\t\t\t\tchartWidth: width,\n\t\t\t\t\tchartHeight: height - ( showLegend ? legendHeight : 0 ),\n\t\t\t\t} }\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx(\n\t\t\t\t\t\t'line-chart',\n\t\t\t\t\t\tstyles[ 'line-chart' ],\n\t\t\t\t\t\t{ [ styles[ 'line-chart--animated' ] ]: animation && ! prefersReducedMotion },\n\t\t\t\t\t\t{ [ styles[ 'line-chart--legend-top' ] ]: showLegend && legendPosition === 'top' },\n\t\t\t\t\t\tclassName\n\t\t\t\t\t) }\n\t\t\t\t\tdata-testid=\"line-chart\"\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\trole=\"grid\"\n\t\t\t\t\t\taria-label={ __( 'Line chart', 'jetpack-charts' ) }\n\t\t\t\t\t\ttabIndex={ 0 }\n\t\t\t\t\t\tonKeyDown={ onChartKeyDown }\n\t\t\t\t\t\tonFocus={ onChartFocus }\n\t\t\t\t\t\tonBlur={ onChartBlur }\n\t\t\t\t\t\tref={ chartRef }\n\t\t\t\t\t>\n\t\t\t\t\t\t<XYChart\n\t\t\t\t\t\t\ttheme={ theme }\n\t\t\t\t\t\t\twidth={ width }\n\t\t\t\t\t\t\theight={ height - ( showLegend ? legendHeight : 0 ) }\n\t\t\t\t\t\t\tmargin={ {\n\t\t\t\t\t\t\t\t...defaultMargin,\n\t\t\t\t\t\t\t\t...margin,\n\t\t\t\t\t\t\t\t...( showLegend && legendPosition === 'top'\n\t\t\t\t\t\t\t\t\t? { top: ( defaultMargin.top || 0 ) + legendHeight }\n\t\t\t\t\t\t\t\t\t: {} ),\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t// xScale and yScale could be set in Axis as well, but they are `scale` props there.\n\t\t\t\t\t\t\txScale={ chartOptions.xScale }\n\t\t\t\t\t\t\tyScale={ chartOptions.yScale }\n\t\t\t\t\t\t\tonPointerDown={ onPointerDown }\n\t\t\t\t\t\t\tonPointerUp={ onPointerUp }\n\t\t\t\t\t\t\tonPointerMove={ onPointerMove }\n\t\t\t\t\t\t\tonPointerOut={ onPointerOut }\n\t\t\t\t\t\t\tpointerEventsDataKey=\"nearest\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ gridVisibility !== 'none' && <Grid columns={ false } numTicks={ 4 } /> }\n\t\t\t\t\t\t\t{ chartOptions.axis.x.display && <Axis { ...chartOptions.axis.x } /> }\n\t\t\t\t\t\t\t{ chartOptions.axis.y.display && <Axis { ...chartOptions.axis.y } /> }\n\n\t\t\t\t\t\t\t{ allSeriesHidden ? (\n\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\tx={ width / 2 }\n\t\t\t\t\t\t\t\t\ty={ ( height - ( showLegend ? legendHeight : 0 ) ) / 2 }\n\t\t\t\t\t\t\t\t\ttextAnchor=\"middle\"\n\t\t\t\t\t\t\t\t\tfill={ providerTheme.gridStyles?.stroke || '#ccc' }\n\t\t\t\t\t\t\t\t\tfontSize=\"14\"\n\t\t\t\t\t\t\t\t\tfontFamily=\"-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t\t\t\t'All series are hidden. Click legend items to show data.',\n\t\t\t\t\t\t\t\t\t\t'jetpack-charts'\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t) : null }\n\n\t\t\t\t\t\t\t{ seriesWithVisibility.map( ( { series: seriesData, index, isVisible } ) => {\n\t\t\t\t\t\t\t\t// Skip rendering invisible series\n\t\t\t\t\t\t\t\tif ( ! isVisible ) {\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst { color, lineStyles, glyph } = getElementStyles( {\n\t\t\t\t\t\t\t\t\tdata: seriesData,\n\t\t\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t\tconst lineProps = {\n\t\t\t\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\t\t\t\t...lineStyles,\n\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<g key={ seriesData?.label || index }>\n\t\t\t\t\t\t\t\t\t\t{ withGradientFill && (\n\t\t\t\t\t\t\t\t\t\t\t<LinearGradient\n\t\t\t\t\t\t\t\t\t\t\t\tid={ `area-gradient-${ chartId }-${ index + 1 }` }\n\t\t\t\t\t\t\t\t\t\t\t\tfrom={ color }\n\t\t\t\t\t\t\t\t\t\t\t\tfromOpacity={ 0.4 }\n\t\t\t\t\t\t\t\t\t\t\t\ttoOpacity={ 0.1 }\n\t\t\t\t\t\t\t\t\t\t\t\tto={ providerTheme.backgroundColor }\n\t\t\t\t\t\t\t\t\t\t\t\t{ ...seriesData.options?.gradient }\n\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"line-gradient\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{ seriesData.options?.gradient?.stops?.map( ( stop, stopIndex ) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={ `${ stop.offset }-${ stop.color || color }` }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\toffset={ stop.offset }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstopColor={ stop.color || color }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstopOpacity={ stop.opacity ?? 1 }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-testid={ `line-gradient-stop-${ chartId }-${ index }-${ stopIndex }` }\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t\t\t\t</LinearGradient>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t\t<AreaSeries\n\t\t\t\t\t\t\t\t\t\t\tkey={ seriesData?.label }\n\t\t\t\t\t\t\t\t\t\t\tdataKey={ seriesData?.label }\n\t\t\t\t\t\t\t\t\t\t\tdata={ seriesData.data as DataPointDate[] }\n\t\t\t\t\t\t\t\t\t\t\t{ ...accessors }\n\t\t\t\t\t\t\t\t\t\t\tfill={\n\t\t\t\t\t\t\t\t\t\t\t\twithGradientFill\n\t\t\t\t\t\t\t\t\t\t\t\t\t? `url(#area-gradient-${ chartId }-${ index + 1 })`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'transparent'\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\trenderLine={ true }\n\t\t\t\t\t\t\t\t\t\t\tcurve={ getCurveType( curveType, smoothing ) }\n\t\t\t\t\t\t\t\t\t\t\tlineProps={ lineProps }\n\t\t\t\t\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t\t\t\t\t{ withStartGlyphs && (\n\t\t\t\t\t\t\t\t\t\t\t<LineChartGlyph\n\t\t\t\t\t\t\t\t\t\t\t\tindex={ index }\n\t\t\t\t\t\t\t\t\t\t\t\tdata={ seriesData }\n\t\t\t\t\t\t\t\t\t\t\t\tcolor={ color }\n\t\t\t\t\t\t\t\t\t\t\t\trenderGlyph={ glyph ?? renderGlyph }\n\t\t\t\t\t\t\t\t\t\t\t\taccessors={ accessors }\n\t\t\t\t\t\t\t\t\t\t\t\tglyphStyle={ glyphStyle }\n\t\t\t\t\t\t\t\t\t\t\t\tposition=\"start\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\n\t\t\t\t\t\t\t\t\t\t{ withEndGlyphs && (\n\t\t\t\t\t\t\t\t\t\t\t<LineChartGlyph\n\t\t\t\t\t\t\t\t\t\t\t\tindex={ index }\n\t\t\t\t\t\t\t\t\t\t\t\tdata={ seriesData }\n\t\t\t\t\t\t\t\t\t\t\t\tcolor={ color }\n\t\t\t\t\t\t\t\t\t\t\t\trenderGlyph={ glyph ?? renderGlyph }\n\t\t\t\t\t\t\t\t\t\t\t\taccessors={ accessors }\n\t\t\t\t\t\t\t\t\t\t\t\tglyphStyle={ glyphStyle }\n\t\t\t\t\t\t\t\t\t\t\t\tposition=\"end\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} ) }\n\n\t\t\t\t\t\t\t{ withTooltips && (\n\t\t\t\t\t\t\t\t<AccessibleTooltip\n\t\t\t\t\t\t\t\t\tdetectBounds\n\t\t\t\t\t\t\t\t\tsnapTooltipToDatumX\n\t\t\t\t\t\t\t\t\tsnapTooltipToDatumY\n\t\t\t\t\t\t\t\t\tshowSeriesGlyphs\n\t\t\t\t\t\t\t\t\trenderTooltip={ renderTooltip }\n\t\t\t\t\t\t\t\t\trenderGlyph={ tooltipRenderGlyph }\n\t\t\t\t\t\t\t\t\tglyphStyle={ glyphStyle }\n\t\t\t\t\t\t\t\t\tshowVerticalCrosshair={ withTooltipCrosshairs?.showVertical }\n\t\t\t\t\t\t\t\t\tshowHorizontalCrosshair={ withTooltipCrosshairs?.showHorizontal }\n\t\t\t\t\t\t\t\t\tselectedIndex={ selectedIndex }\n\t\t\t\t\t\t\t\t\ttooltipRef={ tooltipRef }\n\t\t\t\t\t\t\t\t\tkeyboardFocusedClassName={ styles[ 'line-chart__tooltip--keyboard-focused' ] }\n\t\t\t\t\t\t\t\t\tseries={ dataSorted }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) }\n\n\t\t\t\t\t\t\t{ /* Component to expose scale data via ref */ }\n\t\t\t\t\t\t\t<LineChartScalesRef\n\t\t\t\t\t\t\t\tchartRef={ internalChartRef }\n\t\t\t\t\t\t\t\twidth={ width }\n\t\t\t\t\t\t\t\theight={ height }\n\t\t\t\t\t\t\t\tmargin={ margin }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</XYChart>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{ showLegend && (\n\t\t\t\t\t\t<Legend\n\t\t\t\t\t\t\torientation={ legendOrientation }\n\t\t\t\t\t\t\talignment={ legendAlignment }\n\t\t\t\t\t\t\tposition={ legendPosition }\n\t\t\t\t\t\t\tmaxWidth={ legendMaxWidth }\n\t\t\t\t\t\t\ttextOverflow={ legendTextOverflow }\n\t\t\t\t\t\t\tlegendItemClassName={ legendItemClassName }\n\t\t\t\t\t\t\tclassName={ styles[ 'line-chart-legend' ] }\n\t\t\t\t\t\t\tshape={ legendShape }\n\t\t\t\t\t\t\tchartId={ chartId }\n\t\t\t\t\t\t\tinteractive={ legendInteractive }\n\t\t\t\t\t\t\tref={ legendRef }\n\t\t\t\t\t\t/>\n\t\t\t\t\t) }\n\n\t\t\t\t\t{ children }\n\t\t\t\t</div>\n\t\t\t</SingleChartContext.Provider>\n\t\t);\n\t}\n);\n\n// Component type definitions for composition API\ntype LineChartAnnotationComponents = {\n\tAnnotationsOverlay: typeof LineChartAnnotationsOverlay;\n\tAnnotation: typeof LineChartAnnotation;\n\tLegend: typeof Legend;\n};\n\ntype LineChartBaseProps = Optional< LineChartProps, 'width' | 'height' | 'size' >;\n\ntype LineChartComponent = React.ForwardRefExoticComponent<\n\tLineChartBaseProps & React.RefAttributes< SingleChartRef >\n> &\n\tLineChartAnnotationComponents;\n\ntype LineChartResponsiveComponent = React.ForwardRefExoticComponent<\n\tLineChartBaseProps & ResponsiveConfig & React.RefAttributes< SingleChartRef >\n> &\n\tLineChartAnnotationComponents;\n\nconst LineChartWithProvider = forwardRef< SingleChartRef, LineChartProps >( ( props, ref ) => {\n\tconst existingContext = useContext( GlobalChartsContext );\n\n\t// If we're already in a GlobalChartsProvider context, render the core component directly\n\tif ( existingContext ) {\n\t\treturn <LineChartInternal { ...props } ref={ ref } />;\n\t}\n\n\t// Otherwise, wrap with our own GlobalChartsProvider\n\treturn (\n\t\t<GlobalChartsProvider>\n\t\t\t<LineChartInternal { ...props } ref={ ref } />\n\t\t</GlobalChartsProvider>\n\t);\n} );\n\nLineChartWithProvider.displayName = 'LineChart';\n\nconst LineChart = attachSubComponents( LineChartWithProvider, {\n\tLegend: Legend,\n\tAnnotationsOverlay: LineChartAnnotationsOverlay,\n\tAnnotation: LineChartAnnotation,\n} ) as LineChartComponent;\n\nconst LineChartResponsive = attachSubComponents(\n\twithResponsive< LineChartProps >( LineChartWithProvider ),\n\t{\n\t\tLegend: Legend,\n\t\tAnnotationsOverlay: LineChartAnnotationsOverlay,\n\t\tAnnotation: LineChartAnnotation,\n\t}\n) as LineChartResponsiveComponent;\n\nexport { LineChartResponsive as default, LineChart as LineChartUnresponsive };\n","import { DataContext } from '@visx/xychart';\nimport { useContext } from 'react';\nimport type { RenderLineGlyphProps } from '../../line-chart';\n\nexport const DefaultGlyph = < Datum extends object >( props: RenderLineGlyphProps< Datum > ) => {\n\tconst { theme } = useContext( DataContext ) || {};\n\tconst position = props.position || 'start';\n\n\treturn (\n\t\t<circle\n\t\t\tcx={ props.x }\n\t\t\tcy={ props.y }\n\t\t\tr={ props.size }\n\t\t\tfill={ props.color }\n\t\t\tstroke={ theme?.backgroundColor }\n\t\t\tstrokeWidth={ 1.5 }\n\t\t\tpaintOrder=\"fill\"\n\t\t\tdata-testid={ `${ position }-glyph-${ props.index }` }\n\t\t\t{ ...props.glyphStyle }\n\t\t/>\n\t);\n};\n","import 'css-chunk:src/charts/line-chart/line-chart.module.scss';export default {\n \"line-chart\": \"a8ccharts-v-oO8E\",\n \"line-chart--animated\": \"a8ccharts-QrkuTW\",\n \"rise\": \"a8ccharts--rxDU3\",\n \"line-chart--legend-top\": \"a8ccharts-3l-pKy\",\n \"line-chart__tooltip\": \"a8ccharts-Tu0rR-\",\n \"line-chart__annotation-label-popover\": \"a8ccharts--RSWXi\",\n \"line-chart__tooltip-date\": \"a8ccharts-Q-b5A1\",\n \"line-chart__tooltip-row\": \"a8ccharts-19N7T9\",\n \"line-chart__tooltip-label\": \"a8ccharts-HOAXrD\",\n \"line-chart__annotations-overlay\": \"a8ccharts-rQiY8O\",\n \"line-chart__annotation-label\": \"a8ccharts-8AKWOe\",\n \"line-chart__annotation-label-trigger-button\": \"a8ccharts-7mh3Cl\",\n \"line-chart__annotation-label-popover--visible\": \"a8ccharts-VAeVuJ\",\n \"line-chart__annotation-label-popover--safari\": \"a8ccharts-TEe-iV\",\n \"line-chart__annotation-label-popover-header\": \"a8ccharts-LAUpx7\",\n \"line-chart__annotation-label-popover-content\": \"a8ccharts-b76gEu\",\n \"line-chart__annotation-label-popover-close-button\": \"a8ccharts-LIpFoS\"\n};","import { __ } from '@wordpress/i18n';\nimport clsx from 'clsx';\nimport Gridicon from 'gridicons';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport { isSafari } from '../../../utils';\nimport styles from '../line-chart.module.scss';\nimport type { ButtonWithPopover, PopoverElement, ToggleEvent } from '../../../types';\nimport type { FC } from 'react';\n\nexport const POPOVER_BUTTON_SIZE = 44;\n\ninterface LineChartAnnotationLabelWithPopoverProps {\n\ttitle: string;\n\tsubtitle?: string;\n\trenderLabel: FC< { title: string; subtitle?: string } >;\n\trenderLabelPopover: FC< { title: string; subtitle?: string } >;\n}\n\nconst LineChartAnnotationLabelWithPopover: FC< LineChartAnnotationLabelWithPopoverProps > = ( {\n\ttitle,\n\tsubtitle,\n\trenderLabel,\n\trenderLabelPopover,\n} ) => {\n\tconst popoverId = useId();\n\tconst buttonRef = useRef< HTMLButtonElement >( null );\n\tconst popoverRef = useRef< HTMLDivElement >( null );\n\tconst [ isPositioned, setIsPositioned ] = useState( false );\n\tconst isBrowserSafari = isSafari();\n\n\tuseEffect( () => {\n\t\tconst button = buttonRef.current;\n\t\tconst popover = popoverRef.current;\n\n\t\tif ( ! button || ! popover ) return;\n\n\t\tconst positionPopover = () => {\n\t\t\t// Popover positioning in Safari is complicated due to issues with SVG foreign objects (https://bugs.webkit.org/show_bug.cgi?id=23113), so let it be positioned in the centre of the viewport.\n\t\t\tif ( ! isBrowserSafari ) {\n\t\t\t\tconst buttonRect = button.getBoundingClientRect();\n\t\t\t\tpopover.style.left = `${ buttonRect.right }px`;\n\t\t\t\tpopover.style.top = `${ buttonRect.top }px`;\n\t\t\t}\n\n\t\t\tsetIsPositioned( true );\n\t\t};\n\n\t\t// Position when popover shows\n\t\tpopover.addEventListener( 'toggle', ( e: ToggleEvent ) => {\n\t\t\tif ( e.newState === 'open' ) {\n\t\t\t\tpositionPopover();\n\t\t\t}\n\t\t} );\n\n\t\t// Initial positioning if already open\n\t\ttry {\n\t\t\tif ( popover.matches( ':popover-open' ) ) {\n\t\t\t\tpositionPopover();\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors in test environments (e.g., JSDOM does not support :popover-open)\n\t\t}\n\t}, [ isBrowserSafari ] );\n\n\treturn (\n\t\t<div className={ styles[ 'line-chart__annotation-label' ] }>\n\t\t\t<button\n\t\t\t\tref={ buttonRef }\n\t\t\t\t{ ...( { popovertarget: popoverId } as ButtonWithPopover ) }\n\t\t\t\tclassName={ styles[ 'line-chart__annotation-label-trigger-button' ] }\n\t\t\t\tstyle={ {\n\t\t\t\t\twidth: `${ POPOVER_BUTTON_SIZE }px`,\n\t\t\t\t\theight: `${ POPOVER_BUTTON_SIZE }px`,\n\t\t\t\t\ttransform: `translate(${ POPOVER_BUTTON_SIZE / 2 }px, 0)`,\n\t\t\t\t} }\n\t\t\t\taria-label={ title || __( 'View details', 'jetpack-charts' ) }\n\t\t\t>\n\t\t\t\t{ renderLabel( { title, subtitle } ) }\n\t\t\t</button>\n\t\t\t<div\n\t\t\t\tref={ popoverRef }\n\t\t\t\tid={ popoverId }\n\t\t\t\t{ ...( { popover: 'auto' } as PopoverElement ) }\n\t\t\t\tclassName={ clsx(\n\t\t\t\t\tstyles[ 'line-chart__annotation-label-popover' ],\n\t\t\t\t\tisPositioned && styles[ 'line-chart__annotation-label-popover--visible' ],\n\t\t\t\t\tisBrowserSafari && styles[ 'line-chart__annotation-label-popover--safari' ]\n\t\t\t\t) }\n\t\t\t\tdata-testid=\"line-chart-annotation-label-popover\"\n\t\t\t>\n\t\t\t\t<div className={ styles[ 'line-chart__annotation-label-popover-header' ] }>\n\t\t\t\t\t<div className={ styles[ 'line-chart__annotation-label-popover-content' ] }>\n\t\t\t\t\t\t{ renderLabelPopover( { title, subtitle } ) }\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\t{ ...( {\n\t\t\t\t\t\t\tpopovertarget: popoverId,\n\t\t\t\t\t\t\tpopovertargetaction: 'hide',\n\t\t\t\t\t\t} as ButtonWithPopover ) }\n\t\t\t\t\t\tclassName={ styles[ 'line-chart__annotation-label-popover-close-button' ] }\n\t\t\t\t\t\taria-label={ __( 'Close', 'jetpack-charts' ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<Gridicon icon=\"cross\" size={ 16 } />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nexport default LineChartAnnotationLabelWithPopover;\n","import { DataContext } from '@visx/xychart';\nimport { useEffect, useState, useCallback } from 'react';\nimport { useSingleChartContext } from '../../private/single-chart-context';\nimport styles from '../line-chart.module.scss';\nimport type { AxisScale } from '@visx/axis';\nimport type { FC, ReactNode } from 'react';\n\nexport interface LineChartAnnotationsProps {\n\tchildren?: ReactNode;\n}\n\ninterface ScaleData {\n\txScale: AxisScale< Date >;\n\tyScale: AxisScale< number >;\n}\n\nconst LineChartAnnotationsOverlay: FC< LineChartAnnotationsProps > = ( { children } ) => {\n\tconst { chartRef, chartWidth, chartHeight } = useSingleChartContext();\n\n\tconst [ scales, setScales ] = useState< ScaleData | null >( null );\n\tconst [ scalesStable, setScalesStable ] = useState< boolean >( false );\n\n\t// Create a signature for scale data to enable easy comparison\n\tconst createScaleSignature = useCallback( ( scaleData: ScaleData ) => {\n\t\tconst xDomain = scaleData.xScale.domain();\n\t\tconst yDomain = scaleData.yScale.domain();\n\t\tconst xRange = scaleData.xScale.range();\n\t\tconst yRange = scaleData.yScale.range();\n\n\t\treturn `${ xDomain.join( ',' ) }-${ yDomain.join( ',' ) }-${ xRange.join(\n\t\t\t','\n\t\t) }-${ yRange.join( ',' ) }`;\n\t}, [] );\n\n\t// Get scales from chart ref and return them with signature for comparison\n\tconst getScalesData = useCallback( () => {\n\t\tif ( chartRef?.current ) {\n\t\t\tconst scaleData = chartRef.current.getScales();\n\n\t\t\tif ( scaleData ) {\n\t\t\t\tconst scaleInfo = {\n\t\t\t\t\txScale: scaleData.xScale as AxisScale< Date >,\n\t\t\t\t\tyScale: scaleData.yScale as AxisScale< number >,\n\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tscales: scaleInfo,\n\t\t\t\t\tsignature: createScaleSignature( scaleInfo ),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}, [ chartRef, createScaleSignature ] );\n\n\t// The chart resizes on render so we need to monitor the scales until they stabilize\n\tuseEffect( () => {\n\t\tlet timeoutId: number | null = null;\n\t\tlet lastSignature: string | null = null;\n\t\tlet retryCount = 0;\n\t\tconst maxRetries = 20; // 20 * 50ms = 1 second max\n\t\tconst checkInterval = 50; // Check every 50ms\n\n\t\t// Reset stability state when monitoring starts\n\t\tsetScalesStable( false );\n\n\t\tconst monitorScales = () => {\n\t\t\tconst currentScaleData = getScalesData();\n\n\t\t\t// If we got scales, compare signatures\n\t\t\tif ( currentScaleData ) {\n\t\t\t\t// Check if scales have settled by comparing signatures\n\t\t\t\tconst scalesSettled = lastSignature && currentScaleData.signature === lastSignature;\n\n\t\t\t\tif ( scalesSettled ) {\n\t\t\t\t\t// Scales have stabilized, mark as stable\n\t\t\t\t\tsetScalesStable( true );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Update scales and remember signature for next comparison\n\t\t\t\tsetScales( currentScaleData.scales );\n\t\t\t\tlastSignature = currentScaleData.signature;\n\t\t\t}\n\n\t\t\t// Continue monitoring if we haven't exceeded max retries\n\t\t\tif ( retryCount < maxRetries ) {\n\t\t\t\tretryCount++;\n\t\t\t\ttimeoutId = setTimeout( monitorScales, checkInterval ) as unknown as number;\n\t\t\t}\n\t\t};\n\n\t\tmonitorScales();\n\n\t\treturn () => {\n\t\t\tif ( timeoutId ) {\n\t\t\t\tclearTimeout( timeoutId );\n\t\t\t}\n\t\t};\n\t}, [ getScalesData, chartWidth, chartHeight ] );\n\n\t// Early return if no chart data available\n\tif ( ! chartRef || ! children ) {\n\t\treturn null;\n\t}\n\n\tif ( ! scales || ! scalesStable ) {\n\t\treturn null;\n\t}\n\n\t// Create a DataContext value that mimics what visx provides\n\t// We're intentionally providing minimal context for annotations to work\n\tconst dataContextValue = {\n\t\txScale: scales.xScale,\n\t\tyScale: scales.yScale,\n\t\tmargin: { top: 0, right: 0, bottom: 0, left: 0 },\n\t\twidth: chartWidth,\n\t\theight: chartHeight,\n\t} as unknown as Parameters< typeof DataContext.Provider >[ 0 ][ 'value' ];\n\n\treturn (\n\t\t<DataContext.Provider value={ dataContextValue }>\n\t\t\t<svg\n\t\t\t\twidth={ chartWidth }\n\t\t\t\theight={ chartHeight }\n\t\t\t\tclassName={ styles[ 'line-chart__annotations-overlay' ] }\n\t\t\t\tdata-testid=\"line-chart-annotations-overlay\"\n\t\t\t>\n\t\t\t\t{ children }\n\t\t\t</svg>\n\t\t</DataContext.Provider>\n\t);\n};\n\nexport default LineChartAnnotationsOverlay;\n","import {\n\tAnnotation,\n\tCircleSubject,\n\tConnector,\n\tHtmlLabel,\n\tLabel,\n\tLineSubject,\n} from '@visx/annotation';\nimport { DataContext } from '@visx/xychart';\nimport merge from 'deepmerge';\nimport { useContext, useRef, useEffect, useState, useMemo } from 'react';\nimport { useGlobalChartsTheme } from '../../../providers';\nimport { isSafari } from '../../../utils';\nimport LineChartAnnotationLabelWithPopover, {\n\tPOPOVER_BUTTON_SIZE,\n} from './line-chart-annotation-label-popover';\nimport type { LineChartAnnotationProps } from '../types';\nimport type { LabelProps } from '@visx/annotation/lib/components/Label';\nimport type { TextProps } from '@visx/text';\nimport type { FC } from 'react';\n\ntype SubjectType = 'circle' | 'line-vertical' | 'line-horizontal';\n\nconst ANNOTATION_MAX_WIDTH = 125; // visx default\nconst ANNOTATION_INIT_HEIGHT = 100;\n\nexport const getLabelPosition = ( {\n\tsubjectType,\n\tx,\n\txMax,\n\ty,\n\tyMin,\n\tyMax,\n\tmaxWidth,\n\theight,\n}: {\n\tsubjectType: SubjectType;\n\tx: number;\n\txMax: number;\n\ty: number;\n\tyMin: number;\n\tyMax: number;\n\tmaxWidth?: number;\n\theight?: number | null;\n} ): {\n\tdx: number;\n\tdy: number;\n\tisFlippedHorizontally: boolean;\n\tisFlippedVertically: boolean;\n} => {\n\tconst annotationMaxWidth = maxWidth ?? ANNOTATION_MAX_WIDTH;\n\tconst annotationHeight = height ?? ANNOTATION_INIT_HEIGHT;\n\tlet dx = 15;\n\tlet dy = 15;\n\tlet isFlippedHorizontally = false;\n\tlet isFlippedVertically = false;\n\n\tif ( subjectType === 'line-horizontal' ) {\n\t\tdx = 0;\n\t\tdy = 20;\n\t}\n\n\tif ( subjectType === 'line-vertical' ) {\n\t\tdx = 20;\n\t\tdy = 0;\n\t}\n\n\t// Smart horizontal positioning: if annotation would extend beyond right edge, position it to the left\n\t// Account for the connector offset (dx) in boundary calculations\n\tconst effectiveX = x + dx;\n\n\tif ( effectiveX + annotationMaxWidth > xMax ) {\n\t\tisFlippedHorizontally = true;\n\n\t\tif ( subjectType === 'circle' ) {\n\t\t\tdx = -dx; // Just flip to the left side with same offset\n\t\t} else if ( subjectType === 'line-vertical' ) {\n\t\t\tdx = -20; // Position to the left of the line\n\t\t}\n\t}\n\n\t// Smart vertical positioning: check both top and bottom edges\n\t// For circle annotations, they are positioned below by default (dy > 0)\n\t// Only flip when close to bottom edge to position above\n\tif ( subjectType === 'circle' ) {\n\t\t// Check if positioning below would extend beyond bottom edge\n\t\tif ( y + dy + annotationHeight > yMin ) {\n\t\t\t// Too close to bottom edge, position above\n\t\t\tisFlippedVertically = true;\n\t\t\tdy = -Math.abs( dy ); // Ensure negative value to position above the point\n\t\t}\n\t\t// When close to top edge, keep default below positioning (no flip needed)\n\t} else if ( y - annotationHeight < yMax ) {\n\t\t// Too close to top edge, position below\n\t\tif ( subjectType === 'line-horizontal' ) {\n\t\t\tisFlippedVertically = true;\n\t\t\tdy = Math.abs( dy ); // Ensure positive value to position below the point\n\t\t} else if ( subjectType === 'line-vertical' ) {\n\t\t\tisFlippedVertically = true; // For anchor adjustment only\n\t\t}\n\t} else if ( y + annotationHeight > yMin ) {\n\t\t// Too close to bottom edge, position above\n\t\tif ( subjectType === 'line-horizontal' ) {\n\t\t\tisFlippedVertically = true;\n\t\t\tdy = -Math.abs( dy ); // Ensure negative value to position above the point\n\t\t} else if ( subjectType === 'line-vertical' ) {\n\t\t\tisFlippedVertically = true; // For anchor adjustment only\n\t\t}\n\t}\n\n\treturn { dx, dy, isFlippedHorizontally, isFlippedVertically };\n};\n\nconst getHorizontalAnchor = (\n\tsubjectType: SubjectType,\n\tisFlippedHorizontally: boolean\n): LabelProps[ 'horizontalAnchor' ] => {\n\tif ( subjectType === 'line-horizontal' ) {\n\t\treturn isFlippedHorizontally ? 'end' : 'start';\n\t}\n\n\treturn undefined;\n};\n\nconst getVerticalAnchor = (\n\tsubjectType: SubjectType,\n\tisFlippedVertically: boolean,\n\ty: number,\n\tyMax: number,\n\theight: number\n): TextProps[ 'verticalAnchor' ] => {\n\tif ( subjectType === 'line-vertical' ) {\n\t\tif ( isFlippedVertically ) {\n\t\t\t// If flipped due to top edge, anchor to top; if flipped due to bottom edge, anchor to bottom\n\t\t\treturn y - height < yMax ? 'start' : 'end';\n\t\t}\n\n\t\treturn 'start';\n\t}\n\n\treturn undefined;\n};\n\nconst LineChartAnnotation: FC< LineChartAnnotationProps > = ( {\n\tdatum,\n\ttitle,\n\tsubtitle,\n\tsubjectType = 'circle',\n\tstyles: datumStyles,\n\ttestId,\n\trenderLabel,\n\trenderLabelPopover,\n} ) => {\n\tconst providerTheme = useGlobalChartsTheme();\n\tconst { xScale, yScale } = useContext( DataContext ) || {};\n\tconst labelRef = useRef< SVGGElement >( null );\n\tconst [ height, setHeight ] = useState< number | null >( null );\n\n\t// Deep merge styles to preserve nested object properties\n\tconst styles = merge( providerTheme.annotationStyles ?? {}, datumStyles ?? {} );\n\n\t// Measure the label height once after initial render\n\tuseEffect( () => {\n\t\tif ( labelRef.current?.getBBox ) {\n\t\t\tconst bbox = labelRef.current.getBBox();\n\t\t\tsetHeight( bbox.height );\n\t\t}\n\t}, [] );\n\n\tconst positionData = useMemo( () => {\n\t\tif ( ! datum || ! datum.date || datum.value == null || ! xScale || ! yScale ) return null;\n\n\t\tconst x = xScale( datum.date );\n\t\tconst y = yScale( datum.value );\n\n\t\tif ( typeof x !== 'number' || typeof y !== 'number' ) return null;\n\n\t\tconst [ yMin, yMax ] = yScale.range().map( Number );\n\t\tconst [ xMin, xMax ] = xScale.range().map( Number );\n\n\t\t// If a custom label is provided, use the provided position\n\t\tif ( renderLabel ) {\n\t\t\treturn {\n\t\t\t\tx,\n\t\t\t\tdx: 0,\n\t\t\t\ty,\n\t\t\t\tdy: 0,\n\t\t\t\tyMin,\n\t\t\t\tyMax,\n\t\t\t\txMin,\n\t\t\t\txMax,\n\t\t\t\tisFlippedHorizontally: false,\n\t\t\t\tisFlippedVertically: false,\n\t\t\t};\n\t\t}\n\n\t\tconst position = getLabelPosition( {\n\t\t\tsubjectType,\n\t\t\tx,\n\t\t\txMax,\n\t\t\ty,\n\t\t\tyMin,\n\t\t\tyMax,\n\t\t\tmaxWidth: styles?.label?.maxWidth,\n\t\t\theight,\n\t\t} );\n\n\t\treturn { x, y, yMin, yMax, xMin, xMax, ...position };\n\t}, [ datum, xScale, yScale, subjectType, styles?.label?.maxWidth, height, renderLabel ] );\n\n\tif ( ! positionData ) return null;\n\n\tconst { x, y, yMin, yMax, xMin, xMax, dx, dy, isFlippedHorizontally, isFlippedVertically } =\n\t\tpositionData;\n\n\tconst getLabelY = () => {\n\t\tconst labelY = styles?.label?.y;\n\n\t\tif ( labelY === 'start' ) return yMax;\n\t\tif ( labelY === 'end' ) return yMin;\n\n\t\treturn labelY;\n\t};\n\n\tconst getLabelX = () => {\n\t\tconst labelX = styles?.label?.x;\n\n\t\tif ( labelX === 'start' ) return xMin;\n\t\tif ( labelX === 'end' ) return xMax;\n\n\t\treturn labelX;\n\t};\n\n\tconst labelPosition = {\n\t\tx: getLabelX(),\n\t\ty: getLabelY(),\n\t};\n\n\t// Safari has a bug where children of an SVG foreignObject are not positioned correctly https://bugs.webkit.org/show_bug.cgi?id=23113\n\t// This is a workaround to position the label correctly\n\tconst getSafariHTMLLabelPosition = () => {\n\t\tconst labelWidth = POPOVER_BUTTON_SIZE;\n\t\tconst labelHeight = POPOVER_BUTTON_SIZE;\n\n\t\treturn isSafari()\n\t\t\t? {\n\t\t\t\t\ttransform: `translate(${\n\t\t\t\t\t\tx +\n\t\t\t\t\t\t( dx || 0 ) +\n\t\t\t\t\t\t( typeof labelPosition.x === 'number' ? labelPosition.x - x : 0 ) -\n\t\t\t\t\t\tlabelWidth\n\t\t\t\t\t}px, ${\n\t\t\t\t\t\ty +\n\t\t\t\t\t\t( dy || 0 ) +\n\t\t\t\t\t\t( typeof labelPosition.y === 'number' ? labelPosition.y - y : 0 ) -\n\t\t\t\t\t\tlabelHeight\n\t\t\t\t\t}px)`,\n\t\t\t\t\twidth: labelWidth,\n\t\t\t\t\theight: labelHeight,\n\t\t\t }\n\t\t\t: undefined;\n\t};\n\n\treturn (\n\t\t<g data-testid={ testId }>\n\t\t\t<Annotation x={ x } y={ y } dx={ dx } dy={ dy }>\n\t\t\t\t<Connector { ...styles?.connector } />\n\t\t\t\t{ subjectType === 'circle' && <CircleSubject { ...styles?.circleSubject } /> }\n\t\t\t\t{ subjectType === 'line-vertical' && (\n\t\t\t\t\t<LineSubject\n\t\t\t\t\t\tmin={ yMax }\n\t\t\t\t\t\tmax={ yMin }\n\t\t\t\t\t\t{ ...{ ...styles?.lineSubject, orientation: 'vertical' } }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t\t{ subjectType === 'line-horizontal' && (\n\t\t\t\t\t<LineSubject\n\t\t\t\t\t\tmin={ xMin }\n\t\t\t\t\t\tmax={ xMax }\n\t\t\t\t\t\t{ ...{ ...styles?.lineSubject, orientation: 'horizontal' } }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t\t{ renderLabel ? (\n\t\t\t\t\t<HtmlLabel { ...styles?.label } { ...labelPosition }>\n\t\t\t\t\t\t<div style={ getSafariHTMLLabelPosition() }>\n\t\t\t\t\t\t\t{ renderLabelPopover ? (\n\t\t\t\t\t\t\t\t<LineChartAnnotationLabelWithPopover\n\t\t\t\t\t\t\t\t\ttitle={ title }\n\t\t\t\t\t\t\t\t\tsubtitle={ subtitle }\n\t\t\t\t\t\t\t\t\trenderLabel={ renderLabel }\n\t\t\t\t\t\t\t\t\trenderLabelPopover={ renderLabelPopover }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\trenderLabel( { title, subtitle } )\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</HtmlLabel>\n\t\t\t\t) : (\n\t\t\t\t\t<g ref={ labelRef }>\n\t\t\t\t\t\t<Label\n\t\t\t\t\t\t\ttitle={ title }\n\t\t\t\t\t\t\tsubtitle={ subtitle }\n\t\t\t\t\t\t\t{ ...styles?.label }\n\t\t\t\t\t\t\t{ ...labelPosition }\n\t\t\t\t\t\t\thorizontalAnchor={ getHorizontalAnchor( subjectType, isFlippedHorizontally ) }\n\t\t\t\t\t\t\tverticalAnchor={ getVerticalAnchor(\n\t\t\t\t\t\t\t\tsubjectType,\n\t\t\t\t\t\t\t\tisFlippedVertically,\n\t\t\t\t\t\t\t\ty,\n\t\t\t\t\t\t\t\tyMax,\n\t\t\t\t\t\t\t\theight ?? ANNOTATION_INIT_HEIGHT\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</g>\n\t\t\t\t) }\n\t\t\t</Annotation>\n\t\t</g>\n\t);\n};\n\nexport default LineChartAnnotation;\n","import { DataContext } from '@visx/xychart';\nimport { useContext } from 'react';\nimport type { LineChartGlyphProps } from '../types';\nimport type { FC } from 'react';\n\nconst toNumber = ( val?: number | string | null ): number | undefined => {\n\tconst num = typeof val === 'number' ? val : parseFloat( val );\n\treturn isNaN( num ) ? undefined : num;\n};\n\nconst LineChartGlyph: FC< LineChartGlyphProps > = ( {\n\tdata,\n\tindex,\n\tcolor,\n\tglyphStyle,\n\trenderGlyph,\n\taccessors,\n\tposition,\n} ) => {\n\tconst { xScale, yScale } = useContext( DataContext ) || {};\n\tif ( ! xScale || ! yScale ) return null;\n\n\tif ( data.data.length === 0 ) return null;\n\n\tconst point = position === 'start' ? data.data[ 0 ] : data.data[ data.data.length - 1 ];\n\n\tconst x = xScale( accessors.xAccessor( point ) );\n\tconst y = yScale( accessors.yAccessor( point ) );\n\n\tif ( typeof x !== 'number' || typeof y !== 'number' ) return null;\n\n\tconst size = Math.max( 0, toNumber( glyphStyle?.radius ) ?? 4 );\n\n\treturn renderGlyph( {\n\t\tkey: `${ position }-glyph-${ data.label }`,\n\t\tindex,\n\t\tdatum: point,\n\t\tcolor,\n\t\tsize,\n\t\tx,\n\t\ty,\n\t\tglyphStyle,\n\t\tposition,\n\t} );\n};\n\nexport default LineChartGlyph;\n"]}
1
+ {"version":3,"sources":["/home/runner/work/jetpack/jetpack/projects/js-packages/charts/dist/chunk-LNLHCZ6F.cjs","../src/charts/line-chart/line-chart.tsx","../src/charts/private/default-glyph/default-glyph.tsx","../src/charts/line-chart/line-chart.module.scss","../src/charts/line-chart/private/line-chart-annotation-label-popover.tsx","../src/charts/line-chart/private/line-chart-annotations-overlay.tsx","../src/charts/line-chart/private/line-chart-annotation.tsx","../src/charts/line-chart/private/line-chart-glyph.tsx"],"names":["jsx","useEffect","useRef","yMax","xMax","x","y","yMin","xMin","jsxs","useContext"],"mappings":"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","file":"/home/runner/work/jetpack/jetpack/projects/js-packages/charts/dist/chunk-LNLHCZ6F.cjs","sourcesContent":[null,"import { formatNumberCompact, formatNumber } from '@automattic/number-formatters';\nimport { curveCatmullRom, curveLinear, curveMonotoneX } from '@visx/curve';\nimport { LinearGradient } from '@visx/gradient';\nimport { scaleTime } from '@visx/scale';\nimport { XYChart, AreaSeries, Grid, Axis, DataContext } from '@visx/xychart';\nimport { __ } from '@wordpress/i18n';\nimport clsx from 'clsx';\nimport { differenceInHours, differenceInYears } from 'date-fns';\nimport { useMemo, useContext, forwardRef, useImperativeHandle, useState, useRef } from 'react';\nimport { Legend, useChartLegendItems } from '../../components/legend';\nimport { AccessibleTooltip, useKeyboardNavigation } from '../../components/tooltip';\nimport {\n\tuseXYChartTheme,\n\tuseChartDataTransform,\n\tuseChartMargin,\n\tuseElementHeight,\n\tusePrefersReducedMotion,\n} from '../../hooks';\nimport {\n\tGlobalChartsProvider,\n\tGlobalChartsContext,\n\tuseChartId,\n\tuseChartRegistration,\n\tuseGlobalChartsContext,\n\tuseGlobalChartsTheme,\n} from '../../providers';\nimport { attachSubComponents } from '../../utils';\nimport { DefaultGlyph } from '../private/default-glyph';\nimport { SingleChartContext, type SingleChartRef } from '../private/single-chart-context';\nimport { withResponsive } from '../private/with-responsive';\nimport styles from './line-chart.module.scss';\nimport { LineChartAnnotation, LineChartAnnotationsOverlay, LineChartGlyph } from './private';\nimport type { CurveType, RenderLineGlyphProps, LineChartProps, TooltipDatum } from './types';\nimport type { DataPoint, DataPointDate, SeriesData, Optional } from '../../types';\nimport type { ResponsiveConfig } from '../private/with-responsive';\nimport type { TickFormatter } from '@visx/axis';\nimport type { GlyphProps } from '@visx/xychart';\nimport type { RenderTooltipParams } from '@visx/xychart/lib/components/Tooltip';\nimport type { FC, Ref } from 'react';\n\nconst X_TICK_WIDTH = 60;\n\nconst defaultRenderGlyph = < Datum extends object >( props: RenderLineGlyphProps< Datum > ) => {\n\treturn <DefaultGlyph { ...props } key={ props.key } />;\n};\n\nconst toNumber = ( val?: number | string | null ): number | undefined => {\n\tconst num = typeof val === 'number' ? val : parseFloat( val );\n\treturn isNaN( num ) ? undefined : num;\n};\n\n/**\n * Determines the curve type for the line chart based on the provided type and smoothing parameters\n *\n * @param {CurveType} type - The explicit curve type to use\n * @param {boolean} smoothing - Legacy smoothing parameter\n * @return The curve function to use for the line\n */\nconst getCurveType = ( type?: CurveType, smoothing?: boolean ) => {\n\t// If no type specified, use legacy smoothing behavior\n\tif ( ! type ) {\n\t\treturn smoothing ? curveCatmullRom : curveLinear;\n\t}\n\n\t// Handle explicit curve types\n\tswitch ( type ) {\n\t\tcase 'smooth':\n\t\t\treturn curveCatmullRom;\n\t\tcase 'monotone':\n\t\t\treturn curveMonotoneX;\n\t\tcase 'linear':\n\t\t\treturn curveLinear;\n\t\tdefault:\n\t\t\treturn curveLinear;\n\t}\n};\n\nconst renderDefaultTooltip = ( params: RenderTooltipParams< DataPointDate > ) => {\n\tconst { tooltipData } = params;\n\tconst nearestDatum = tooltipData?.nearestDatum?.datum;\n\tif ( ! nearestDatum ) return null;\n\n\tconst tooltipPoints: TooltipDatum[] = Object.entries( tooltipData?.datumByKey || {} )\n\t\t.map( ( [ key, { datum } ] ) => ( {\n\t\t\tkey,\n\t\t\tvalue: datum.value as number,\n\t\t} ) )\n\t\t.sort( ( a, b ) => b.value - a.value );\n\n\treturn (\n\t\t<div className={ styles[ 'line-chart__tooltip' ] }>\n\t\t\t<div className={ styles[ 'line-chart__tooltip-date' ] }>\n\t\t\t\t{ nearestDatum.date?.toLocaleDateString() }\n\t\t\t</div>\n\t\t\t{ tooltipPoints.map( point => (\n\t\t\t\t<div key={ point.key } className={ styles[ 'line-chart__tooltip-row' ] }>\n\t\t\t\t\t<span className={ styles[ 'line-chart__tooltip-label' ] }>{ point.key }:</span>\n\t\t\t\t\t<span className={ styles[ 'line-chart__tooltip-value' ] }>\n\t\t\t\t\t\t{ formatNumber( point.value ) }\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t) ) }\n\t\t</div>\n\t);\n};\n\nconst formatYearTick = ( timestamp: number ) => {\n\tconst date = new Date( timestamp );\n\treturn date.toLocaleDateString( undefined, {\n\t\tyear: 'numeric',\n\t} );\n};\n\nconst formatDateTick = ( timestamp: number ) => {\n\tconst date = new Date( timestamp );\n\treturn date.toLocaleDateString( undefined, {\n\t\tmonth: 'short',\n\t\tday: 'numeric',\n\t} );\n};\n\nconst formatHourTick = ( timestamp: number ) => {\n\tconst date = new Date( timestamp );\n\treturn date.toLocaleTimeString( undefined, {\n\t\thour: 'numeric',\n\t\thour12: true,\n\t} );\n};\n\nconst getFormatter = ( sortedData: ReturnType< typeof useChartDataTransform > ) => {\n\tconst minX = Math.min( ...sortedData.map( datom => datom.data.at( 0 )?.date ) );\n\tconst maxX = Math.max( ...sortedData.map( datom => datom.data.at( -1 )?.date ) );\n\n\tconst diffInHours = Math.abs( differenceInHours( maxX, minX ) );\n\tif ( diffInHours <= 24 ) {\n\t\treturn formatHourTick;\n\t}\n\n\tconst diffInYears = Math.abs( differenceInYears( maxX, minX ) );\n\tif ( diffInYears <= 1 ) {\n\t\treturn formatDateTick;\n\t}\n\n\treturn formatYearTick;\n};\n\nconst guessOptimalNumTicks = (\n\tdata: ReturnType< typeof useChartDataTransform >,\n\tchartWidth: number,\n\ttickFormatter: ( timestamp: number, index?: number, values?: unknown ) => string\n) => {\n\tconst minX = Math.min( ...data.map( datom => datom.data.at( 0 )?.date ) );\n\tconst maxX = Math.max( ...data.map( datom => datom.data.at( -1 )?.date ) );\n\tconst xScale = scaleTime( { domain: [ minX, maxX ] } );\n\n\t// Calculate upper bound of tick numbers based on data points and chart width\n\tconst upperBound = Math.min(\n\t\tdata[ 0 ]?.data.length || 3, // A sane fallback to avoid NaN when no data is present\n\t\tMath.ceil( chartWidth / X_TICK_WIDTH )\n\t);\n\tlet secondBestGuess = 1; // a tick number that's no greater than upperBound\n\n\tfor ( let numTicks = upperBound; numTicks > 1; --numTicks ) {\n\t\tconst ticks = xScale.ticks( numTicks ).map( d => tickFormatter( d.getTime() ) );\n\n\t\t// The .ticks() function doesn't properly respect the requested number of ticks, so we need to check the length\n\t\tif ( ticks.length > upperBound ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tsecondBestGuess = Math.max( secondBestGuess, ticks.length );\n\n\t\tconst uniqueTicks = Array.from( new Set( ticks ) );\n\t\tif ( uniqueTicks.length === 1 ) {\n\t\t\t// All ticks are the same, so skip further processing\n\t\t\treturn 1;\n\t\t}\n\n\t\t// Example: OCT 1 JAN 1 APR 1 JUL 1 OCT 1\n\t\t// Here, the two OCTs are not duplicates as they represent October of two different years.\n\t\tconst hasConsecutiveDuplicate = ticks.some(\n\t\t\t( tick, idx ) => idx > 0 && tick === ticks[ idx - 1 ]\n\t\t);\n\n\t\tif ( hasConsecutiveDuplicate ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\treturn ticks.length;\n\t}\n\n\treturn secondBestGuess;\n};\n\nconst validateData = ( data: SeriesData[] ) => {\n\tif ( ! data?.length ) return 'No data available';\n\n\tconst hasInvalidData = data.some( series =>\n\t\tseries.data.some(\n\t\t\t( point: DataPointDate | DataPoint ) =>\n\t\t\t\tisNaN( point.value as number ) ||\n\t\t\t\tpoint.value === null ||\n\t\t\t\tpoint.value === undefined ||\n\t\t\t\t( 'date' in point && point.date && isNaN( point.date.getTime() ) )\n\t\t)\n\t);\n\n\tif ( hasInvalidData ) return 'Invalid data';\n\treturn null;\n};\n\n// Inner component to access DataContext and provide scale data to ref\nconst LineChartScalesRef: FC< {\n\tchartRef?: Ref< SingleChartRef >;\n\twidth: number;\n\theight: number;\n\tmargin?: { top?: number; right?: number; bottom?: number; left?: number };\n} > = ( { chartRef, width, height, margin } ) => {\n\tconst context = useContext( DataContext );\n\n\tuseImperativeHandle(\n\t\tchartRef,\n\t\t() => ( {\n\t\t\tgetScales: () => {\n\t\t\t\tif ( ! context?.xScale || ! context?.yScale ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\txScale: context.xScale,\n\t\t\t\t\tyScale: context.yScale,\n\t\t\t\t};\n\t\t\t},\n\t\t\tgetChartDimensions: () => ( {\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\tmargin: margin || {},\n\t\t\t} ),\n\t\t} ),\n\t\t[ context, width, height, margin ]\n\t);\n\n\treturn null; // This component only provides the ref interface\n};\n\nconst LineChartInternal = forwardRef< SingleChartRef, LineChartProps >(\n\t(\n\t\t{\n\t\t\tdata,\n\t\t\tchartId: providedChartId,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tclassName,\n\t\t\tmargin,\n\t\t\twithTooltips = true,\n\t\t\twithTooltipCrosshairs,\n\t\t\tshowLegend = false,\n\t\t\tlegendOrientation = 'horizontal',\n\t\t\tlegendAlignment = 'center',\n\t\t\tlegendPosition = 'bottom',\n\t\t\tlegendMaxWidth,\n\t\t\tlegendTextOverflow = 'wrap',\n\t\t\tlegendItemClassName,\n\t\t\trenderGlyph = defaultRenderGlyph,\n\t\t\tglyphStyle = {},\n\t\t\tlegendShape = 'line',\n\t\t\twithLegendGlyph = false,\n\t\t\twithGradientFill = false,\n\t\t\tsmoothing = true,\n\t\t\tcurveType,\n\t\t\trenderTooltip = renderDefaultTooltip,\n\t\t\twithStartGlyphs = false,\n\t\t\twithEndGlyphs = false,\n\t\t\tlegendInteractive = false,\n\t\t\tanimation,\n\t\t\toptions = {},\n\t\t\tonPointerDown = undefined,\n\t\t\tonPointerUp = undefined,\n\t\t\tonPointerMove = undefined,\n\t\t\tonPointerOut = undefined,\n\t\t\tchildren,\n\t\t\tgridVisibility,\n\t\t},\n\t\tref\n\t) => {\n\t\tconst providerTheme = useGlobalChartsTheme();\n\t\tconst theme = useXYChartTheme( data );\n\t\tconst chartId = useChartId( providedChartId );\n\t\tconst [ legendRef, legendHeight ] = useElementHeight< HTMLDivElement >();\n\t\tconst chartRef = useRef< HTMLDivElement >( null );\n\t\tconst [ selectedIndex, setSelectedIndex ] = useState< number | undefined >( undefined );\n\t\tconst [ isNavigating, setIsNavigating ] = useState( false );\n\t\tconst internalChartRef = useRef< SingleChartRef >( null );\n\n\t\t// Forward the external ref to the internal ref\n\t\tuseImperativeHandle(\n\t\t\tref,\n\t\t\t() => ( {\n\t\t\t\tgetScales: () => internalChartRef.current?.getScales() || null,\n\t\t\t\tgetChartDimensions: () =>\n\t\t\t\t\tinternalChartRef.current?.getChartDimensions() || { width: 0, height: 0, margin: {} },\n\t\t\t} ),\n\t\t\t[ internalChartRef ]\n\t\t);\n\n\t\tconst dataSorted = useChartDataTransform( data );\n\t\tconst { getElementStyles, isSeriesVisible } = useGlobalChartsContext();\n\n\t\t// Add visibility information to series when using interactive legends\n\t\tconst seriesWithVisibility = useMemo( () => {\n\t\t\tif ( ! chartId || ! legendInteractive ) {\n\t\t\t\treturn dataSorted.map( ( series, index ) => ( { series, index, isVisible: true } ) );\n\t\t\t}\n\t\t\treturn dataSorted.map( ( series, index ) => ( {\n\t\t\t\tseries,\n\t\t\t\tindex,\n\t\t\t\tisVisible: isSeriesVisible( chartId, series.label ),\n\t\t\t} ) );\n\t\t}, [ dataSorted, chartId, isSeriesVisible, legendInteractive ] );\n\n\t\t// Check if all series are hidden\n\t\tconst allSeriesHidden = useMemo( () => {\n\t\t\treturn seriesWithVisibility.every( ( { isVisible } ) => ! isVisible );\n\t\t}, [ seriesWithVisibility ] );\n\n\t\t// Use the keyboard navigation hook\n\t\tconst { tooltipRef, onChartFocus, onChartBlur, onChartKeyDown } = useKeyboardNavigation( {\n\t\t\tselectedIndex,\n\t\t\tsetSelectedIndex,\n\t\t\tisNavigating,\n\t\t\tsetIsNavigating,\n\t\t\tchartRef,\n\t\t\ttotalPoints: dataSorted[ 0 ]?.data.length || 0,\n\t\t} );\n\n\t\tconst chartOptions = useMemo( () => {\n\t\t\tconst formatter = options?.axis?.x?.tickFormat || getFormatter( dataSorted );\n\n\t\t\treturn {\n\t\t\t\taxis: {\n\t\t\t\t\tx: {\n\t\t\t\t\t\torientation: 'bottom' as const,\n\t\t\t\t\t\tnumTicks: guessOptimalNumTicks( dataSorted, width, formatter ),\n\t\t\t\t\t\ttickFormat: formatter,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t...options?.axis?.x,\n\t\t\t\t\t},\n\t\t\t\t\ty: {\n\t\t\t\t\t\torientation: 'left' as const,\n\t\t\t\t\t\tnumTicks: 4,\n\t\t\t\t\t\ttickFormat: formatNumberCompact as TickFormatter< number >,\n\t\t\t\t\t\tdisplay: true,\n\t\t\t\t\t\t...options?.axis?.y,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\txScale: {\n\t\t\t\t\ttype: 'time' as const,\n\t\t\t\t\t...options?.xScale,\n\t\t\t\t},\n\t\t\t\tyScale: {\n\t\t\t\t\ttype: 'linear' as const,\n\t\t\t\t\tnice: true,\n\t\t\t\t\tzero: false,\n\t\t\t\t\t...options?.yScale,\n\t\t\t\t},\n\t\t\t};\n\t\t}, [ options, dataSorted, width ] );\n\n\t\tconst tooltipRenderGlyph = useMemo( () => {\n\t\t\treturn ( props: GlyphProps< DataPointDate > ) => {\n\t\t\t\tconst seriesIndex = dataSorted.findIndex(\n\t\t\t\t\tseries =>\n\t\t\t\t\t\tseries.label === props.key || series.data.includes( props.datum as DataPointDate )\n\t\t\t\t);\n\n\t\t\t\tconst seriesData = dataSorted[ seriesIndex ];\n\n\t\t\t\tconst { color, glyph: themeGlyph } = getElementStyles( {\n\t\t\t\t\tdata: seriesData,\n\t\t\t\t\tindex: seriesIndex,\n\t\t\t\t} );\n\n\t\t\t\tconst propsWithResolvedColor = { ...props, color };\n\n\t\t\t\treturn themeGlyph\n\t\t\t\t\t? themeGlyph( propsWithResolvedColor )\n\t\t\t\t\t: renderGlyph( propsWithResolvedColor );\n\t\t\t};\n\t\t}, [ dataSorted, renderGlyph, getElementStyles ] );\n\n\t\tconst defaultMargin = useChartMargin( height, chartOptions, dataSorted, theme );\n\n\t\tconst error = validateData( dataSorted );\n\t\tconst isDataValid = ! error;\n\n\t\t// Memoize legend options to prevent unnecessary re-calculations\n\t\tconst legendOptions = useMemo(\n\t\t\t() => ( {\n\t\t\t\twithGlyph: withLegendGlyph,\n\t\t\t\tglyphSize: Math.max( 0, toNumber( glyphStyle?.radius ) ?? 4 ),\n\t\t\t\trenderGlyph,\n\t\t\t} ),\n\t\t\t[ withLegendGlyph, glyphStyle?.radius, renderGlyph ]\n\t\t);\n\n\t\t// Create legend items using the reusable hook\n\t\tconst legendItems = useChartLegendItems( dataSorted, legendOptions, legendShape );\n\n\t\t// Memoize metadata to prevent unnecessary re-registration\n\t\tconst chartMetadata = useMemo(\n\t\t\t() => ( {\n\t\t\t\twithGradientFill,\n\t\t\t\tsmoothing,\n\t\t\t\tcurveType,\n\t\t\t\twithStartGlyphs,\n\t\t\t\twithEndGlyphs,\n\t\t\t\twithLegendGlyph,\n\t\t\t} ),\n\t\t\t[ withGradientFill, smoothing, curveType, withStartGlyphs, withEndGlyphs, withLegendGlyph ]\n\t\t);\n\n\t\t// Register chart with context only if data is valid\n\t\tuseChartRegistration( {\n\t\t\tchartId,\n\t\t\tlegendItems,\n\t\t\tchartType: 'line',\n\t\t\tisDataValid,\n\t\t\tmetadata: chartMetadata,\n\t\t} );\n\n\t\tconst prefersReducedMotion = usePrefersReducedMotion();\n\n\t\tconst accessors = {\n\t\t\txAccessor: ( d: DataPointDate ) => d?.date,\n\t\t\tyAccessor: ( d: DataPointDate ) => d?.value,\n\t\t};\n\n\t\t// Create a custom renderTooltip that includes focus capability\n\t\tif ( error ) {\n\t\t\treturn <div className={ clsx( 'line-chart', styles[ 'line-chart' ] ) }>{ error }</div>;\n\t\t}\n\n\t\treturn (\n\t\t\t<SingleChartContext.Provider\n\t\t\t\tvalue={ {\n\t\t\t\t\tchartId,\n\t\t\t\t\tchartRef: internalChartRef,\n\t\t\t\t\tchartWidth: width,\n\t\t\t\t\tchartHeight: height - ( showLegend ? legendHeight : 0 ),\n\t\t\t\t} }\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={ clsx(\n\t\t\t\t\t\t'line-chart',\n\t\t\t\t\t\tstyles[ 'line-chart' ],\n\t\t\t\t\t\t{ [ styles[ 'line-chart--animated' ] ]: animation && ! prefersReducedMotion },\n\t\t\t\t\t\t{ [ styles[ 'line-chart--legend-top' ] ]: showLegend && legendPosition === 'top' },\n\t\t\t\t\t\tclassName\n\t\t\t\t\t) }\n\t\t\t\t\tdata-testid=\"line-chart\"\n\t\t\t\t\tstyle={ {\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight,\n\t\t\t\t\t} }\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\trole=\"grid\"\n\t\t\t\t\t\taria-label={ __( 'Line chart', 'jetpack-charts' ) }\n\t\t\t\t\t\ttabIndex={ 0 }\n\t\t\t\t\t\tonKeyDown={ onChartKeyDown }\n\t\t\t\t\t\tonFocus={ onChartFocus }\n\t\t\t\t\t\tonBlur={ onChartBlur }\n\t\t\t\t\t\tref={ chartRef }\n\t\t\t\t\t>\n\t\t\t\t\t\t<XYChart\n\t\t\t\t\t\t\ttheme={ theme }\n\t\t\t\t\t\t\twidth={ width }\n\t\t\t\t\t\t\theight={ height - ( showLegend ? legendHeight : 0 ) }\n\t\t\t\t\t\t\tmargin={ {\n\t\t\t\t\t\t\t\t...defaultMargin,\n\t\t\t\t\t\t\t\t...margin,\n\t\t\t\t\t\t\t\t...( showLegend && legendPosition === 'top'\n\t\t\t\t\t\t\t\t\t? { top: ( defaultMargin.top || 0 ) + legendHeight }\n\t\t\t\t\t\t\t\t\t: {} ),\n\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t// xScale and yScale could be set in Axis as well, but they are `scale` props there.\n\t\t\t\t\t\t\txScale={ chartOptions.xScale }\n\t\t\t\t\t\t\tyScale={ chartOptions.yScale }\n\t\t\t\t\t\t\tonPointerDown={ onPointerDown }\n\t\t\t\t\t\t\tonPointerUp={ onPointerUp }\n\t\t\t\t\t\t\tonPointerMove={ onPointerMove }\n\t\t\t\t\t\t\tonPointerOut={ onPointerOut }\n\t\t\t\t\t\t\tpointerEventsDataKey=\"nearest\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ gridVisibility !== 'none' && <Grid columns={ false } numTicks={ 4 } /> }\n\t\t\t\t\t\t\t{ chartOptions.axis.x.display && <Axis { ...chartOptions.axis.x } /> }\n\t\t\t\t\t\t\t{ chartOptions.axis.y.display && <Axis { ...chartOptions.axis.y } /> }\n\n\t\t\t\t\t\t\t{ allSeriesHidden ? (\n\t\t\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t\t\tx={ width / 2 }\n\t\t\t\t\t\t\t\t\ty={ ( height - ( showLegend ? legendHeight : 0 ) ) / 2 }\n\t\t\t\t\t\t\t\t\ttextAnchor=\"middle\"\n\t\t\t\t\t\t\t\t\tfill={ providerTheme.gridStyles?.stroke || '#ccc' }\n\t\t\t\t\t\t\t\t\tfontSize=\"14\"\n\t\t\t\t\t\t\t\t\tfontFamily=\"-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ __(\n\t\t\t\t\t\t\t\t\t\t'All series are hidden. Click legend items to show data.',\n\t\t\t\t\t\t\t\t\t\t'jetpack-charts'\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t</text>\n\t\t\t\t\t\t\t) : null }\n\n\t\t\t\t\t\t\t{ seriesWithVisibility.map( ( { series: seriesData, index, isVisible } ) => {\n\t\t\t\t\t\t\t\t// Skip rendering invisible series\n\t\t\t\t\t\t\t\tif ( ! isVisible ) {\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tconst { color, lineStyles, glyph } = getElementStyles( {\n\t\t\t\t\t\t\t\t\tdata: seriesData,\n\t\t\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\t\tconst lineProps = {\n\t\t\t\t\t\t\t\t\tstroke: color,\n\t\t\t\t\t\t\t\t\t...lineStyles,\n\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<g key={ seriesData?.label || index }>\n\t\t\t\t\t\t\t\t\t\t{ withGradientFill && (\n\t\t\t\t\t\t\t\t\t\t\t<LinearGradient\n\t\t\t\t\t\t\t\t\t\t\t\tid={ `area-gradient-${ chartId }-${ index + 1 }` }\n\t\t\t\t\t\t\t\t\t\t\t\tfrom={ color }\n\t\t\t\t\t\t\t\t\t\t\t\tfromOpacity={ 0.4 }\n\t\t\t\t\t\t\t\t\t\t\t\ttoOpacity={ 0.1 }\n\t\t\t\t\t\t\t\t\t\t\t\tto={ providerTheme.backgroundColor }\n\t\t\t\t\t\t\t\t\t\t\t\t{ ...seriesData.options?.gradient }\n\t\t\t\t\t\t\t\t\t\t\t\tdata-testid=\"line-gradient\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{ seriesData.options?.gradient?.stops?.map( ( stop, stopIndex ) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t<stop\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={ `${ stop.offset }-${ stop.color || color }` }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\toffset={ stop.offset }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstopColor={ stop.color || color }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tstopOpacity={ stop.opacity ?? 1 }\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdata-testid={ `line-gradient-stop-${ chartId }-${ index }-${ stopIndex }` }\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t\t\t\t</LinearGradient>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t\t<AreaSeries\n\t\t\t\t\t\t\t\t\t\t\tkey={ seriesData?.label }\n\t\t\t\t\t\t\t\t\t\t\tdataKey={ seriesData?.label }\n\t\t\t\t\t\t\t\t\t\t\tdata={ seriesData.data as DataPointDate[] }\n\t\t\t\t\t\t\t\t\t\t\t{ ...accessors }\n\t\t\t\t\t\t\t\t\t\t\tfill={\n\t\t\t\t\t\t\t\t\t\t\t\twithGradientFill\n\t\t\t\t\t\t\t\t\t\t\t\t\t? `url(#area-gradient-${ chartId }-${ index + 1 })`\n\t\t\t\t\t\t\t\t\t\t\t\t\t: 'transparent'\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\trenderLine={ true }\n\t\t\t\t\t\t\t\t\t\t\tcurve={ getCurveType( curveType, smoothing ) }\n\t\t\t\t\t\t\t\t\t\t\tlineProps={ lineProps }\n\t\t\t\t\t\t\t\t\t\t/>\n\n\t\t\t\t\t\t\t\t\t\t{ withStartGlyphs && (\n\t\t\t\t\t\t\t\t\t\t\t<LineChartGlyph\n\t\t\t\t\t\t\t\t\t\t\t\tindex={ index }\n\t\t\t\t\t\t\t\t\t\t\t\tdata={ seriesData }\n\t\t\t\t\t\t\t\t\t\t\t\tcolor={ color }\n\t\t\t\t\t\t\t\t\t\t\t\trenderGlyph={ glyph ?? renderGlyph }\n\t\t\t\t\t\t\t\t\t\t\t\taccessors={ accessors }\n\t\t\t\t\t\t\t\t\t\t\t\tglyphStyle={ glyphStyle }\n\t\t\t\t\t\t\t\t\t\t\t\tposition=\"start\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\n\t\t\t\t\t\t\t\t\t\t{ withEndGlyphs && (\n\t\t\t\t\t\t\t\t\t\t\t<LineChartGlyph\n\t\t\t\t\t\t\t\t\t\t\t\tindex={ index }\n\t\t\t\t\t\t\t\t\t\t\t\tdata={ seriesData }\n\t\t\t\t\t\t\t\t\t\t\t\tcolor={ color }\n\t\t\t\t\t\t\t\t\t\t\t\trenderGlyph={ glyph ?? renderGlyph }\n\t\t\t\t\t\t\t\t\t\t\t\taccessors={ accessors }\n\t\t\t\t\t\t\t\t\t\t\t\tglyphStyle={ glyphStyle }\n\t\t\t\t\t\t\t\t\t\t\t\tposition=\"end\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</g>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t} ) }\n\n\t\t\t\t\t\t\t{ withTooltips && (\n\t\t\t\t\t\t\t\t<AccessibleTooltip\n\t\t\t\t\t\t\t\t\tdetectBounds\n\t\t\t\t\t\t\t\t\tsnapTooltipToDatumX\n\t\t\t\t\t\t\t\t\tsnapTooltipToDatumY\n\t\t\t\t\t\t\t\t\tshowSeriesGlyphs\n\t\t\t\t\t\t\t\t\trenderTooltip={ renderTooltip }\n\t\t\t\t\t\t\t\t\trenderGlyph={ tooltipRenderGlyph }\n\t\t\t\t\t\t\t\t\tglyphStyle={ glyphStyle }\n\t\t\t\t\t\t\t\t\tshowVerticalCrosshair={ withTooltipCrosshairs?.showVertical }\n\t\t\t\t\t\t\t\t\tshowHorizontalCrosshair={ withTooltipCrosshairs?.showHorizontal }\n\t\t\t\t\t\t\t\t\tselectedIndex={ selectedIndex }\n\t\t\t\t\t\t\t\t\ttooltipRef={ tooltipRef }\n\t\t\t\t\t\t\t\t\tkeyboardFocusedClassName={ styles[ 'line-chart__tooltip--keyboard-focused' ] }\n\t\t\t\t\t\t\t\t\tseries={ dataSorted }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) }\n\n\t\t\t\t\t\t\t{ /* Component to expose scale data via ref */ }\n\t\t\t\t\t\t\t<LineChartScalesRef\n\t\t\t\t\t\t\t\tchartRef={ internalChartRef }\n\t\t\t\t\t\t\t\twidth={ width }\n\t\t\t\t\t\t\t\theight={ height }\n\t\t\t\t\t\t\t\tmargin={ margin }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</XYChart>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t{ showLegend && (\n\t\t\t\t\t\t<Legend\n\t\t\t\t\t\t\torientation={ legendOrientation }\n\t\t\t\t\t\t\talignment={ legendAlignment }\n\t\t\t\t\t\t\tposition={ legendPosition }\n\t\t\t\t\t\t\tmaxWidth={ legendMaxWidth }\n\t\t\t\t\t\t\ttextOverflow={ legendTextOverflow }\n\t\t\t\t\t\t\tlegendItemClassName={ legendItemClassName }\n\t\t\t\t\t\t\tclassName={ styles[ 'line-chart-legend' ] }\n\t\t\t\t\t\t\tshape={ legendShape }\n\t\t\t\t\t\t\tchartId={ chartId }\n\t\t\t\t\t\t\tinteractive={ legendInteractive }\n\t\t\t\t\t\t\tref={ legendRef }\n\t\t\t\t\t\t/>\n\t\t\t\t\t) }\n\n\t\t\t\t\t{ children }\n\t\t\t\t</div>\n\t\t\t</SingleChartContext.Provider>\n\t\t);\n\t}\n);\n\n// Component type definitions for composition API\ntype LineChartAnnotationComponents = {\n\tAnnotationsOverlay: typeof LineChartAnnotationsOverlay;\n\tAnnotation: typeof LineChartAnnotation;\n\tLegend: typeof Legend;\n};\n\ntype LineChartBaseProps = Optional< LineChartProps, 'width' | 'height' | 'size' >;\n\ntype LineChartComponent = React.ForwardRefExoticComponent<\n\tLineChartBaseProps & React.RefAttributes< SingleChartRef >\n> &\n\tLineChartAnnotationComponents;\n\ntype LineChartResponsiveComponent = React.ForwardRefExoticComponent<\n\tLineChartBaseProps & ResponsiveConfig & React.RefAttributes< SingleChartRef >\n> &\n\tLineChartAnnotationComponents;\n\nconst LineChartWithProvider = forwardRef< SingleChartRef, LineChartProps >( ( props, ref ) => {\n\tconst existingContext = useContext( GlobalChartsContext );\n\n\t// If we're already in a GlobalChartsProvider context, render the core component directly\n\tif ( existingContext ) {\n\t\treturn <LineChartInternal { ...props } ref={ ref } />;\n\t}\n\n\t// Otherwise, wrap with our own GlobalChartsProvider\n\treturn (\n\t\t<GlobalChartsProvider>\n\t\t\t<LineChartInternal { ...props } ref={ ref } />\n\t\t</GlobalChartsProvider>\n\t);\n} );\n\nLineChartWithProvider.displayName = 'LineChart';\n\nconst LineChart = attachSubComponents( LineChartWithProvider, {\n\tLegend: Legend,\n\tAnnotationsOverlay: LineChartAnnotationsOverlay,\n\tAnnotation: LineChartAnnotation,\n} ) as LineChartComponent;\n\nconst LineChartResponsive = attachSubComponents(\n\twithResponsive< LineChartProps >( LineChartWithProvider ),\n\t{\n\t\tLegend: Legend,\n\t\tAnnotationsOverlay: LineChartAnnotationsOverlay,\n\t\tAnnotation: LineChartAnnotation,\n\t}\n) as LineChartResponsiveComponent;\n\nexport { LineChartResponsive as default, LineChart as LineChartUnresponsive };\n","import { DataContext } from '@visx/xychart';\nimport { useContext } from 'react';\nimport type { RenderLineGlyphProps } from '../../line-chart';\n\nexport const DefaultGlyph = < Datum extends object >( props: RenderLineGlyphProps< Datum > ) => {\n\tconst { theme } = useContext( DataContext ) || {};\n\tconst position = props.position || 'start';\n\n\treturn (\n\t\t<circle\n\t\t\tcx={ props.x }\n\t\t\tcy={ props.y }\n\t\t\tr={ props.size }\n\t\t\tfill={ props.color }\n\t\t\tstroke={ theme?.backgroundColor }\n\t\t\tstrokeWidth={ 1.5 }\n\t\t\tpaintOrder=\"fill\"\n\t\t\tdata-testid={ `${ position }-glyph-${ props.index }` }\n\t\t\t{ ...props.glyphStyle }\n\t\t/>\n\t);\n};\n","import 'css-chunk:src/charts/line-chart/line-chart.module.scss';export default {\n \"line-chart\": \"a8ccharts-v-oO8E\",\n \"line-chart--animated\": \"a8ccharts-QrkuTW\",\n \"rise\": \"a8ccharts--rxDU3\",\n \"line-chart--legend-top\": \"a8ccharts-3l-pKy\",\n \"line-chart__tooltip\": \"a8ccharts-Tu0rR-\",\n \"line-chart__annotation-label-popover\": \"a8ccharts--RSWXi\",\n \"line-chart__tooltip-date\": \"a8ccharts-Q-b5A1\",\n \"line-chart__tooltip-row\": \"a8ccharts-19N7T9\",\n \"line-chart__tooltip-label\": \"a8ccharts-HOAXrD\",\n \"line-chart__annotations-overlay\": \"a8ccharts-rQiY8O\",\n \"line-chart__annotation-label\": \"a8ccharts-8AKWOe\",\n \"line-chart__annotation-label-trigger-button\": \"a8ccharts-7mh3Cl\",\n \"line-chart__annotation-label-popover--visible\": \"a8ccharts-VAeVuJ\",\n \"line-chart__annotation-label-popover--safari\": \"a8ccharts-TEe-iV\",\n \"line-chart__annotation-label-popover-header\": \"a8ccharts-LAUpx7\",\n \"line-chart__annotation-label-popover-content\": \"a8ccharts-b76gEu\",\n \"line-chart__annotation-label-popover-close-button\": \"a8ccharts-LIpFoS\"\n};","import { __ } from '@wordpress/i18n';\nimport clsx from 'clsx';\nimport Gridicon from 'gridicons';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport { isSafari } from '../../../utils';\nimport styles from '../line-chart.module.scss';\nimport type { ButtonWithPopover, PopoverElement, ToggleEvent } from '../../../types';\nimport type { FC } from 'react';\n\nexport const POPOVER_BUTTON_SIZE = 44;\n\ninterface LineChartAnnotationLabelWithPopoverProps {\n\ttitle: string;\n\tsubtitle?: string;\n\trenderLabel: FC< { title: string; subtitle?: string } >;\n\trenderLabelPopover: FC< { title: string; subtitle?: string } >;\n}\n\nconst LineChartAnnotationLabelWithPopover: FC< LineChartAnnotationLabelWithPopoverProps > = ( {\n\ttitle,\n\tsubtitle,\n\trenderLabel,\n\trenderLabelPopover,\n} ) => {\n\tconst popoverId = useId();\n\tconst buttonRef = useRef< HTMLButtonElement >( null );\n\tconst popoverRef = useRef< HTMLDivElement >( null );\n\tconst [ isPositioned, setIsPositioned ] = useState( false );\n\tconst isBrowserSafari = isSafari();\n\n\tuseEffect( () => {\n\t\tconst button = buttonRef.current;\n\t\tconst popover = popoverRef.current;\n\n\t\tif ( ! button || ! popover ) return;\n\n\t\tconst positionPopover = () => {\n\t\t\t// Popover positioning in Safari is complicated due to issues with SVG foreign objects (https://bugs.webkit.org/show_bug.cgi?id=23113), so let it be positioned in the centre of the viewport.\n\t\t\tif ( ! isBrowserSafari ) {\n\t\t\t\tconst buttonRect = button.getBoundingClientRect();\n\t\t\t\tpopover.style.left = `${ buttonRect.right }px`;\n\t\t\t\tpopover.style.top = `${ buttonRect.top }px`;\n\t\t\t}\n\n\t\t\tsetIsPositioned( true );\n\t\t};\n\n\t\t// Position when popover shows\n\t\tpopover.addEventListener( 'toggle', ( e: ToggleEvent ) => {\n\t\t\tif ( e.newState === 'open' ) {\n\t\t\t\tpositionPopover();\n\t\t\t}\n\t\t} );\n\n\t\t// Initial positioning if already open\n\t\ttry {\n\t\t\tif ( popover.matches( ':popover-open' ) ) {\n\t\t\t\tpositionPopover();\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors in test environments (e.g., JSDOM does not support :popover-open)\n\t\t}\n\t}, [ isBrowserSafari ] );\n\n\treturn (\n\t\t<div className={ styles[ 'line-chart__annotation-label' ] }>\n\t\t\t<button\n\t\t\t\tref={ buttonRef }\n\t\t\t\t{ ...( { popovertarget: popoverId } as ButtonWithPopover ) }\n\t\t\t\tclassName={ styles[ 'line-chart__annotation-label-trigger-button' ] }\n\t\t\t\tstyle={ {\n\t\t\t\t\twidth: `${ POPOVER_BUTTON_SIZE }px`,\n\t\t\t\t\theight: `${ POPOVER_BUTTON_SIZE }px`,\n\t\t\t\t\ttransform: `translate(${ POPOVER_BUTTON_SIZE / 2 }px, 0)`,\n\t\t\t\t} }\n\t\t\t\taria-label={ title || __( 'View details', 'jetpack-charts' ) }\n\t\t\t>\n\t\t\t\t{ renderLabel( { title, subtitle } ) }\n\t\t\t</button>\n\t\t\t<div\n\t\t\t\tref={ popoverRef }\n\t\t\t\tid={ popoverId }\n\t\t\t\t{ ...( { popover: 'auto' } as PopoverElement ) }\n\t\t\t\tclassName={ clsx(\n\t\t\t\t\tstyles[ 'line-chart__annotation-label-popover' ],\n\t\t\t\t\tisPositioned && styles[ 'line-chart__annotation-label-popover--visible' ],\n\t\t\t\t\tisBrowserSafari && styles[ 'line-chart__annotation-label-popover--safari' ]\n\t\t\t\t) }\n\t\t\t\tdata-testid=\"line-chart-annotation-label-popover\"\n\t\t\t>\n\t\t\t\t<div className={ styles[ 'line-chart__annotation-label-popover-header' ] }>\n\t\t\t\t\t<div className={ styles[ 'line-chart__annotation-label-popover-content' ] }>\n\t\t\t\t\t\t{ renderLabelPopover( { title, subtitle } ) }\n\t\t\t\t\t</div>\n\t\t\t\t\t<button\n\t\t\t\t\t\t{ ...( {\n\t\t\t\t\t\t\tpopovertarget: popoverId,\n\t\t\t\t\t\t\tpopovertargetaction: 'hide',\n\t\t\t\t\t\t} as ButtonWithPopover ) }\n\t\t\t\t\t\tclassName={ styles[ 'line-chart__annotation-label-popover-close-button' ] }\n\t\t\t\t\t\taria-label={ __( 'Close', 'jetpack-charts' ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<Gridicon icon=\"cross\" size={ 16 } />\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n\nexport default LineChartAnnotationLabelWithPopover;\n","import { DataContext } from '@visx/xychart';\nimport { useEffect, useState, useCallback } from 'react';\nimport { useSingleChartContext } from '../../private/single-chart-context';\nimport styles from '../line-chart.module.scss';\nimport type { AxisScale } from '@visx/axis';\nimport type { FC, ReactNode } from 'react';\n\nexport interface LineChartAnnotationsProps {\n\tchildren?: ReactNode;\n}\n\ninterface ScaleData {\n\txScale: AxisScale< Date >;\n\tyScale: AxisScale< number >;\n}\n\nconst LineChartAnnotationsOverlay: FC< LineChartAnnotationsProps > = ( { children } ) => {\n\tconst { chartRef, chartWidth, chartHeight } = useSingleChartContext();\n\n\tconst [ scales, setScales ] = useState< ScaleData | null >( null );\n\tconst [ scalesStable, setScalesStable ] = useState< boolean >( false );\n\n\t// Create a signature for scale data to enable easy comparison\n\tconst createScaleSignature = useCallback( ( scaleData: ScaleData ) => {\n\t\tconst xDomain = scaleData.xScale.domain();\n\t\tconst yDomain = scaleData.yScale.domain();\n\t\tconst xRange = scaleData.xScale.range();\n\t\tconst yRange = scaleData.yScale.range();\n\n\t\treturn `${ xDomain.join( ',' ) }-${ yDomain.join( ',' ) }-${ xRange.join(\n\t\t\t','\n\t\t) }-${ yRange.join( ',' ) }`;\n\t}, [] );\n\n\t// Get scales from chart ref and return them with signature for comparison\n\tconst getScalesData = useCallback( () => {\n\t\tif ( chartRef?.current ) {\n\t\t\tconst scaleData = chartRef.current.getScales();\n\n\t\t\tif ( scaleData ) {\n\t\t\t\tconst scaleInfo = {\n\t\t\t\t\txScale: scaleData.xScale as AxisScale< Date >,\n\t\t\t\t\tyScale: scaleData.yScale as AxisScale< number >,\n\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tscales: scaleInfo,\n\t\t\t\t\tsignature: createScaleSignature( scaleInfo ),\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}, [ chartRef, createScaleSignature ] );\n\n\t// The chart resizes on render so we need to monitor the scales until they stabilize\n\tuseEffect( () => {\n\t\tlet timeoutId: number | null = null;\n\t\tlet lastSignature: string | null = null;\n\t\tlet retryCount = 0;\n\t\tconst maxRetries = 20; // 20 * 50ms = 1 second max\n\t\tconst checkInterval = 50; // Check every 50ms\n\n\t\t// Reset stability state when monitoring starts\n\t\tsetScalesStable( false );\n\n\t\tconst monitorScales = () => {\n\t\t\tconst currentScaleData = getScalesData();\n\n\t\t\t// If we got scales, compare signatures\n\t\t\tif ( currentScaleData ) {\n\t\t\t\t// Check if scales have settled by comparing signatures\n\t\t\t\tconst scalesSettled = lastSignature && currentScaleData.signature === lastSignature;\n\n\t\t\t\tif ( scalesSettled ) {\n\t\t\t\t\t// Scales have stabilized, mark as stable\n\t\t\t\t\tsetScalesStable( true );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Update scales and remember signature for next comparison\n\t\t\t\tsetScales( currentScaleData.scales );\n\t\t\t\tlastSignature = currentScaleData.signature;\n\t\t\t}\n\n\t\t\t// Continue monitoring if we haven't exceeded max retries\n\t\t\tif ( retryCount < maxRetries ) {\n\t\t\t\tretryCount++;\n\t\t\t\ttimeoutId = setTimeout( monitorScales, checkInterval ) as unknown as number;\n\t\t\t}\n\t\t};\n\n\t\tmonitorScales();\n\n\t\treturn () => {\n\t\t\tif ( timeoutId ) {\n\t\t\t\tclearTimeout( timeoutId );\n\t\t\t}\n\t\t};\n\t}, [ getScalesData, chartWidth, chartHeight ] );\n\n\t// Early return if no chart data available\n\tif ( ! chartRef || ! children ) {\n\t\treturn null;\n\t}\n\n\tif ( ! scales || ! scalesStable ) {\n\t\treturn null;\n\t}\n\n\t// Create a DataContext value that mimics what visx provides\n\t// We're intentionally providing minimal context for annotations to work\n\tconst dataContextValue = {\n\t\txScale: scales.xScale,\n\t\tyScale: scales.yScale,\n\t\tmargin: { top: 0, right: 0, bottom: 0, left: 0 },\n\t\twidth: chartWidth,\n\t\theight: chartHeight,\n\t} as unknown as Parameters< typeof DataContext.Provider >[ 0 ][ 'value' ];\n\n\treturn (\n\t\t<DataContext.Provider value={ dataContextValue }>\n\t\t\t<svg\n\t\t\t\twidth={ chartWidth }\n\t\t\t\theight={ chartHeight }\n\t\t\t\tclassName={ styles[ 'line-chart__annotations-overlay' ] }\n\t\t\t\tdata-testid=\"line-chart-annotations-overlay\"\n\t\t\t>\n\t\t\t\t{ children }\n\t\t\t</svg>\n\t\t</DataContext.Provider>\n\t);\n};\n\nexport default LineChartAnnotationsOverlay;\n","import {\n\tAnnotation,\n\tCircleSubject,\n\tConnector,\n\tHtmlLabel,\n\tLabel,\n\tLineSubject,\n} from '@visx/annotation';\nimport { DataContext } from '@visx/xychart';\nimport merge from 'deepmerge';\nimport { useContext, useRef, useEffect, useState, useMemo } from 'react';\nimport { useGlobalChartsTheme } from '../../../providers';\nimport { isSafari } from '../../../utils';\nimport LineChartAnnotationLabelWithPopover, {\n\tPOPOVER_BUTTON_SIZE,\n} from './line-chart-annotation-label-popover';\nimport type { LineChartAnnotationProps } from '../types';\nimport type { LabelProps } from '@visx/annotation/lib/components/Label';\nimport type { TextProps } from '@visx/text';\nimport type { FC } from 'react';\n\ntype SubjectType = 'circle' | 'line-vertical' | 'line-horizontal';\n\nconst ANNOTATION_MAX_WIDTH = 125; // visx default\nconst ANNOTATION_INIT_HEIGHT = 100;\n\nexport const getLabelPosition = ( {\n\tsubjectType,\n\tx,\n\txMax,\n\ty,\n\tyMin,\n\tyMax,\n\tmaxWidth,\n\theight,\n}: {\n\tsubjectType: SubjectType;\n\tx: number;\n\txMax: number;\n\ty: number;\n\tyMin: number;\n\tyMax: number;\n\tmaxWidth?: number;\n\theight?: number | null;\n} ): {\n\tdx: number;\n\tdy: number;\n\tisFlippedHorizontally: boolean;\n\tisFlippedVertically: boolean;\n} => {\n\tconst annotationMaxWidth = maxWidth ?? ANNOTATION_MAX_WIDTH;\n\tconst annotationHeight = height ?? ANNOTATION_INIT_HEIGHT;\n\tlet dx = 15;\n\tlet dy = 15;\n\tlet isFlippedHorizontally = false;\n\tlet isFlippedVertically = false;\n\n\tif ( subjectType === 'line-horizontal' ) {\n\t\tdx = 0;\n\t\tdy = 20;\n\t}\n\n\tif ( subjectType === 'line-vertical' ) {\n\t\tdx = 20;\n\t\tdy = 0;\n\t}\n\n\t// Smart horizontal positioning: if annotation would extend beyond right edge, position it to the left\n\t// Account for the connector offset (dx) in boundary calculations\n\tconst effectiveX = x + dx;\n\n\tif ( effectiveX + annotationMaxWidth > xMax ) {\n\t\tisFlippedHorizontally = true;\n\n\t\tif ( subjectType === 'circle' ) {\n\t\t\tdx = -dx; // Just flip to the left side with same offset\n\t\t} else if ( subjectType === 'line-vertical' ) {\n\t\t\tdx = -20; // Position to the left of the line\n\t\t}\n\t}\n\n\t// Smart vertical positioning: check both top and bottom edges\n\t// For circle annotations, they are positioned below by default (dy > 0)\n\t// Only flip when close to bottom edge to position above\n\tif ( subjectType === 'circle' ) {\n\t\t// Check if positioning below would extend beyond bottom edge\n\t\tif ( y + dy + annotationHeight > yMin ) {\n\t\t\t// Too close to bottom edge, position above\n\t\t\tisFlippedVertically = true;\n\t\t\tdy = -Math.abs( dy ); // Ensure negative value to position above the point\n\t\t}\n\t\t// When close to top edge, keep default below positioning (no flip needed)\n\t} else if ( y - annotationHeight < yMax ) {\n\t\t// Too close to top edge, position below\n\t\tif ( subjectType === 'line-horizontal' ) {\n\t\t\tisFlippedVertically = true;\n\t\t\tdy = Math.abs( dy ); // Ensure positive value to position below the point\n\t\t} else if ( subjectType === 'line-vertical' ) {\n\t\t\tisFlippedVertically = true; // For anchor adjustment only\n\t\t}\n\t} else if ( y + annotationHeight > yMin ) {\n\t\t// Too close to bottom edge, position above\n\t\tif ( subjectType === 'line-horizontal' ) {\n\t\t\tisFlippedVertically = true;\n\t\t\tdy = -Math.abs( dy ); // Ensure negative value to position above the point\n\t\t} else if ( subjectType === 'line-vertical' ) {\n\t\t\tisFlippedVertically = true; // For anchor adjustment only\n\t\t}\n\t}\n\n\treturn { dx, dy, isFlippedHorizontally, isFlippedVertically };\n};\n\nconst getHorizontalAnchor = (\n\tsubjectType: SubjectType,\n\tisFlippedHorizontally: boolean\n): LabelProps[ 'horizontalAnchor' ] => {\n\tif ( subjectType === 'line-horizontal' ) {\n\t\treturn isFlippedHorizontally ? 'end' : 'start';\n\t}\n\n\treturn undefined;\n};\n\nconst getVerticalAnchor = (\n\tsubjectType: SubjectType,\n\tisFlippedVertically: boolean,\n\ty: number,\n\tyMax: number,\n\theight: number\n): TextProps[ 'verticalAnchor' ] => {\n\tif ( subjectType === 'line-vertical' ) {\n\t\tif ( isFlippedVertically ) {\n\t\t\t// If flipped due to top edge, anchor to top; if flipped due to bottom edge, anchor to bottom\n\t\t\treturn y - height < yMax ? 'start' : 'end';\n\t\t}\n\n\t\treturn 'start';\n\t}\n\n\treturn undefined;\n};\n\nconst LineChartAnnotation: FC< LineChartAnnotationProps > = ( {\n\tdatum,\n\ttitle,\n\tsubtitle,\n\tsubjectType = 'circle',\n\tstyles: datumStyles,\n\ttestId,\n\trenderLabel,\n\trenderLabelPopover,\n} ) => {\n\tconst providerTheme = useGlobalChartsTheme();\n\tconst { xScale, yScale } = useContext( DataContext ) || {};\n\tconst labelRef = useRef< SVGGElement >( null );\n\tconst [ height, setHeight ] = useState< number | null >( null );\n\n\t// Deep merge styles to preserve nested object properties\n\tconst styles = merge( providerTheme.annotationStyles ?? {}, datumStyles ?? {} );\n\n\t// Measure the label height once after initial render\n\tuseEffect( () => {\n\t\tif ( labelRef.current?.getBBox ) {\n\t\t\tconst bbox = labelRef.current.getBBox();\n\t\t\tsetHeight( bbox.height );\n\t\t}\n\t}, [] );\n\n\tconst positionData = useMemo( () => {\n\t\tif ( ! datum || ! datum.date || datum.value == null || ! xScale || ! yScale ) return null;\n\n\t\tconst x = xScale( datum.date );\n\t\tconst y = yScale( datum.value );\n\n\t\tif ( typeof x !== 'number' || typeof y !== 'number' ) return null;\n\n\t\tconst [ yMin, yMax ] = yScale.range().map( Number );\n\t\tconst [ xMin, xMax ] = xScale.range().map( Number );\n\n\t\t// If a custom label is provided, use the provided position\n\t\tif ( renderLabel ) {\n\t\t\treturn {\n\t\t\t\tx,\n\t\t\t\tdx: 0,\n\t\t\t\ty,\n\t\t\t\tdy: 0,\n\t\t\t\tyMin,\n\t\t\t\tyMax,\n\t\t\t\txMin,\n\t\t\t\txMax,\n\t\t\t\tisFlippedHorizontally: false,\n\t\t\t\tisFlippedVertically: false,\n\t\t\t};\n\t\t}\n\n\t\tconst position = getLabelPosition( {\n\t\t\tsubjectType,\n\t\t\tx,\n\t\t\txMax,\n\t\t\ty,\n\t\t\tyMin,\n\t\t\tyMax,\n\t\t\tmaxWidth: styles?.label?.maxWidth,\n\t\t\theight,\n\t\t} );\n\n\t\treturn { x, y, yMin, yMax, xMin, xMax, ...position };\n\t}, [ datum, xScale, yScale, subjectType, styles?.label?.maxWidth, height, renderLabel ] );\n\n\tif ( ! positionData ) return null;\n\n\tconst { x, y, yMin, yMax, xMin, xMax, dx, dy, isFlippedHorizontally, isFlippedVertically } =\n\t\tpositionData;\n\n\tconst getLabelY = () => {\n\t\tconst labelY = styles?.label?.y;\n\n\t\tif ( labelY === 'start' ) return yMax;\n\t\tif ( labelY === 'end' ) return yMin;\n\n\t\treturn labelY;\n\t};\n\n\tconst getLabelX = () => {\n\t\tconst labelX = styles?.label?.x;\n\n\t\tif ( labelX === 'start' ) return xMin;\n\t\tif ( labelX === 'end' ) return xMax;\n\n\t\treturn labelX;\n\t};\n\n\tconst labelPosition = {\n\t\tx: getLabelX(),\n\t\ty: getLabelY(),\n\t};\n\n\t// Safari has a bug where children of an SVG foreignObject are not positioned correctly https://bugs.webkit.org/show_bug.cgi?id=23113\n\t// This is a workaround to position the label correctly\n\tconst getSafariHTMLLabelPosition = () => {\n\t\tconst labelWidth = POPOVER_BUTTON_SIZE;\n\t\tconst labelHeight = POPOVER_BUTTON_SIZE;\n\n\t\treturn isSafari()\n\t\t\t? {\n\t\t\t\t\ttransform: `translate(${\n\t\t\t\t\t\tx +\n\t\t\t\t\t\t( dx || 0 ) +\n\t\t\t\t\t\t( typeof labelPosition.x === 'number' ? labelPosition.x - x : 0 ) -\n\t\t\t\t\t\tlabelWidth\n\t\t\t\t\t}px, ${\n\t\t\t\t\t\ty +\n\t\t\t\t\t\t( dy || 0 ) +\n\t\t\t\t\t\t( typeof labelPosition.y === 'number' ? labelPosition.y - y : 0 ) -\n\t\t\t\t\t\tlabelHeight\n\t\t\t\t\t}px)`,\n\t\t\t\t\twidth: labelWidth,\n\t\t\t\t\theight: labelHeight,\n\t\t\t }\n\t\t\t: undefined;\n\t};\n\n\treturn (\n\t\t<g data-testid={ testId }>\n\t\t\t<Annotation x={ x } y={ y } dx={ dx } dy={ dy }>\n\t\t\t\t<Connector { ...styles?.connector } />\n\t\t\t\t{ subjectType === 'circle' && <CircleSubject { ...styles?.circleSubject } /> }\n\t\t\t\t{ subjectType === 'line-vertical' && (\n\t\t\t\t\t<LineSubject\n\t\t\t\t\t\tmin={ yMax }\n\t\t\t\t\t\tmax={ yMin }\n\t\t\t\t\t\t{ ...{ ...styles?.lineSubject, orientation: 'vertical' } }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t\t{ subjectType === 'line-horizontal' && (\n\t\t\t\t\t<LineSubject\n\t\t\t\t\t\tmin={ xMin }\n\t\t\t\t\t\tmax={ xMax }\n\t\t\t\t\t\t{ ...{ ...styles?.lineSubject, orientation: 'horizontal' } }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t\t{ renderLabel ? (\n\t\t\t\t\t<HtmlLabel { ...styles?.label } { ...labelPosition }>\n\t\t\t\t\t\t<div style={ getSafariHTMLLabelPosition() }>\n\t\t\t\t\t\t\t{ renderLabelPopover ? (\n\t\t\t\t\t\t\t\t<LineChartAnnotationLabelWithPopover\n\t\t\t\t\t\t\t\t\ttitle={ title }\n\t\t\t\t\t\t\t\t\tsubtitle={ subtitle }\n\t\t\t\t\t\t\t\t\trenderLabel={ renderLabel }\n\t\t\t\t\t\t\t\t\trenderLabelPopover={ renderLabelPopover }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\trenderLabel( { title, subtitle } )\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</HtmlLabel>\n\t\t\t\t) : (\n\t\t\t\t\t<g ref={ labelRef }>\n\t\t\t\t\t\t<Label\n\t\t\t\t\t\t\ttitle={ title }\n\t\t\t\t\t\t\tsubtitle={ subtitle }\n\t\t\t\t\t\t\t{ ...styles?.label }\n\t\t\t\t\t\t\t{ ...labelPosition }\n\t\t\t\t\t\t\thorizontalAnchor={ getHorizontalAnchor( subjectType, isFlippedHorizontally ) }\n\t\t\t\t\t\t\tverticalAnchor={ getVerticalAnchor(\n\t\t\t\t\t\t\t\tsubjectType,\n\t\t\t\t\t\t\t\tisFlippedVertically,\n\t\t\t\t\t\t\t\ty,\n\t\t\t\t\t\t\t\tyMax,\n\t\t\t\t\t\t\t\theight ?? ANNOTATION_INIT_HEIGHT\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</g>\n\t\t\t\t) }\n\t\t\t</Annotation>\n\t\t</g>\n\t);\n};\n\nexport default LineChartAnnotation;\n","import { DataContext } from '@visx/xychart';\nimport { useContext } from 'react';\nimport type { LineChartGlyphProps } from '../types';\nimport type { FC } from 'react';\n\nconst toNumber = ( val?: number | string | null ): number | undefined => {\n\tconst num = typeof val === 'number' ? val : parseFloat( val );\n\treturn isNaN( num ) ? undefined : num;\n};\n\nconst LineChartGlyph: FC< LineChartGlyphProps > = ( {\n\tdata,\n\tindex,\n\tcolor,\n\tglyphStyle,\n\trenderGlyph,\n\taccessors,\n\tposition,\n} ) => {\n\tconst { xScale, yScale } = useContext( DataContext ) || {};\n\tif ( ! xScale || ! yScale ) return null;\n\n\tif ( data.data.length === 0 ) return null;\n\n\tconst point = position === 'start' ? data.data[ 0 ] : data.data[ data.data.length - 1 ];\n\n\tconst x = xScale( accessors.xAccessor( point ) );\n\tconst y = yScale( accessors.yAccessor( point ) );\n\n\tif ( typeof x !== 'number' || typeof y !== 'number' ) return null;\n\n\tconst size = Math.max( 0, toNumber( glyphStyle?.radius ) ?? 4 );\n\n\treturn renderGlyph( {\n\t\tkey: `${ position }-glyph-${ data.label }`,\n\t\tindex,\n\t\tdatum: point,\n\t\tcolor,\n\t\tsize,\n\t\tx,\n\t\ty,\n\t\tglyphStyle,\n\t\tposition,\n\t} );\n};\n\nexport default LineChartGlyph;\n"]}
@@ -0,0 +1,121 @@
1
+ import {
2
+ withResponsive
3
+ } from "./chunk-NONODB3K.js";
4
+ import {
5
+ GlobalChartsContext,
6
+ GlobalChartsProvider,
7
+ useGlobalChartsContext
8
+ } from "./chunk-DYMJWNYM.js";
9
+ import {
10
+ lightenHexColor,
11
+ normalizeColorToHex,
12
+ resolveCssVariable
13
+ } from "./chunk-TE63Y5PX.js";
14
+
15
+ // src/charts/geo-chart/geo-chart.tsx
16
+ import { __ } from "@wordpress/i18n";
17
+ import clsx from "clsx";
18
+ import { useContext, useMemo } from "react";
19
+ import { Chart } from "react-google-charts";
20
+
21
+ // src/charts/geo-chart/geo-chart.module.scss
22
+ var geo_chart_module_default = {
23
+ "container": "a8ccharts-JvcqOz"
24
+ };
25
+
26
+ // src/charts/geo-chart/geo-chart.tsx
27
+ import { jsx } from "react/jsx-runtime";
28
+ var DEFAULT_FEATURE_FILL_COLOR = "#ffffff";
29
+ var DEFAULT_BACKGROUND_COLOR = "#ffffff";
30
+ var GeoChartInternal = ({
31
+ className,
32
+ data,
33
+ width,
34
+ height,
35
+ region = "world",
36
+ resolution = "countries",
37
+ renderPlaceholder
38
+ }) => {
39
+ const {
40
+ getElementStyles,
41
+ theme: {
42
+ geoChart: { featureFillColor },
43
+ backgroundColor
44
+ }
45
+ } = useGlobalChartsContext();
46
+ const loadingPlaceholder = /* @__PURE__ */ jsx(
47
+ "div",
48
+ {
49
+ className: clsx("geo-chart", geo_chart_module_default.container, className),
50
+ "data-testid": "geo-chart-loading",
51
+ style: { width, height },
52
+ children: renderPlaceholder ? renderPlaceholder() : __("Loading map", "jetpack-charts")
53
+ }
54
+ );
55
+ const fullColorHex = getElementStyles({ index: 0 }).color;
56
+ const lightColorHex = lightenHexColor(fullColorHex, 0.8);
57
+ const backgroundColorHex = normalizeColorToHex(backgroundColor, null, resolveCssVariable) || DEFAULT_BACKGROUND_COLOR;
58
+ const defaultFillColorHex = normalizeColorToHex(featureFillColor, null, resolveCssVariable) || DEFAULT_FEATURE_FILL_COLOR;
59
+ const hasHtmlTooltips = useMemo(
60
+ () => data.length > 0 && data[0].some(
61
+ (col) => typeof col === "object" && col !== null && "role" in col && col.role === "tooltip" && "p" in col && typeof col.p === "object" && col.p !== null && "html" in col.p && col.p.html === true
62
+ ),
63
+ [data]
64
+ );
65
+ const options = useMemo(
66
+ () => ({
67
+ ...region !== "world" && { region },
68
+ ...resolution !== "countries" && { resolution },
69
+ colorAxis: { colors: [lightColorHex, fullColorHex] },
70
+ backgroundColor: backgroundColorHex,
71
+ datalessRegionColor: defaultFillColorHex,
72
+ defaultColor: defaultFillColorHex,
73
+ tooltip: { trigger: "focus", isHtml: hasHtmlTooltips },
74
+ legend: "none",
75
+ keepAspectRatio: true
76
+ }),
77
+ [
78
+ region,
79
+ resolution,
80
+ lightColorHex,
81
+ fullColorHex,
82
+ backgroundColorHex,
83
+ defaultFillColorHex,
84
+ hasHtmlTooltips
85
+ ]
86
+ );
87
+ return /* @__PURE__ */ jsx(
88
+ "div",
89
+ {
90
+ className: clsx("geo-chart", geo_chart_module_default.container, className),
91
+ "data-testid": "geo-chart",
92
+ style: { width, height, backgroundColor },
93
+ children: /* @__PURE__ */ jsx(
94
+ Chart,
95
+ {
96
+ chartType: "GeoChart",
97
+ width,
98
+ height,
99
+ data,
100
+ options,
101
+ loader: loadingPlaceholder
102
+ }
103
+ )
104
+ }
105
+ );
106
+ };
107
+ var GeoChartWithProvider = (props) => {
108
+ const existingContext = useContext(GlobalChartsContext);
109
+ if (existingContext) {
110
+ return /* @__PURE__ */ jsx(GeoChartInternal, { ...props });
111
+ }
112
+ return /* @__PURE__ */ jsx(GlobalChartsProvider, { children: /* @__PURE__ */ jsx(GeoChartInternal, { ...props }) });
113
+ };
114
+ GeoChartWithProvider.displayName = "GeoChart";
115
+ var GeoChartResponsive = withResponsive(GeoChartWithProvider);
116
+
117
+ export {
118
+ GeoChartWithProvider,
119
+ GeoChartResponsive
120
+ };
121
+ //# sourceMappingURL=chunk-RDJ5PKC5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/charts/geo-chart/geo-chart.tsx","../src/charts/geo-chart/geo-chart.module.scss"],"sourcesContent":["/**\n * External dependencies\n */\nimport { __ } from '@wordpress/i18n';\nimport clsx from 'clsx';\nimport { FC, useContext, useMemo } from 'react';\nimport { Chart, type GoogleChartOptions } from 'react-google-charts';\n/**\n * Internal dependencies\n */\nimport { GlobalChartsContext, GlobalChartsProvider, useGlobalChartsContext } from '../../providers';\nimport { lightenHexColor, normalizeColorToHex } from '../../utils/color-utils';\nimport { resolveCssVariable } from '../../utils/resolve-css-var';\nimport { withResponsive } from '../private/with-responsive';\nimport styles from './geo-chart.module.scss';\nimport { GeoChartProps } from './types';\n\nconst DEFAULT_FEATURE_FILL_COLOR = '#ffffff';\nconst DEFAULT_BACKGROUND_COLOR = '#ffffff';\n\n/**\n * Renders a geographical chart using Google Charts GeoChart to visualize data.\n *\n * Supports the full Google Charts data format including custom tooltips, formatted values,\n * and multiple data columns for maximum flexibility.\n *\n * Locations can be identified by full name (e.g., 'United States', 'California') or codes\n * (e.g., 'US', 'US-CA'). Full names are recommended for better readability in tooltips.\n *\n * @param props - The props for the GeoChart component\n * @param props.data - Data in Google Charts format (array of arrays with headers)\n * @param props.width - Width of the chart in pixels\n * @param props.height - Height of the chart in pixels\n * @param props.region - Region to display ('world', 'US', or ISO 3166-1 alpha-2 code)\n * @param props.resolution - Resolution level ('countries', 'provinces', or 'metros')\n * @param props.className - Additional CSS class name for the chart container\n * @param props.renderPlaceholder - Optional render function for the loading placeholder\n * @return A React component displaying an interactive map with data visualization\n */\nconst GeoChartInternal: FC< GeoChartProps > = ( {\n\tclassName,\n\tdata,\n\twidth,\n\theight,\n\tregion = 'world',\n\tresolution = 'countries',\n\trenderPlaceholder,\n} ) => {\n\tconst {\n\t\tgetElementStyles,\n\t\ttheme: {\n\t\t\tgeoChart: { featureFillColor },\n\t\t\tbackgroundColor,\n\t\t},\n\t} = useGlobalChartsContext();\n\n\t// Render loading placeholder\n\tconst loadingPlaceholder = (\n\t\t<div\n\t\t\tclassName={ clsx( 'geo-chart', styles.container, className ) }\n\t\t\tdata-testid=\"geo-chart-loading\"\n\t\t\tstyle={ { width, height } }\n\t\t>\n\t\t\t{ renderPlaceholder ? renderPlaceholder() : __( 'Loading map', 'jetpack-charts' ) }\n\t\t</div>\n\t);\n\n\t// Google charts doesn't accept CSS variables, so we need to convert them to hex colors\n\tconst fullColorHex = getElementStyles( { index: 0 } ).color;\n\tconst lightColorHex = lightenHexColor( fullColorHex, 0.8 );\n\t// Use normalizeColorToHex to ensure HSL/RGB values from CSS variables are converted to hex\n\tconst backgroundColorHex =\n\t\tnormalizeColorToHex( backgroundColor, null, resolveCssVariable ) || DEFAULT_BACKGROUND_COLOR;\n\tconst defaultFillColorHex =\n\t\tnormalizeColorToHex( featureFillColor, null, resolveCssVariable ) || DEFAULT_FEATURE_FILL_COLOR;\n\n\t// Check if data has HTML tooltips (column with role: 'tooltip' and p.html: true)\n\tconst hasHtmlTooltips = useMemo(\n\t\t() =>\n\t\t\tdata.length > 0 &&\n\t\t\tdata[ 0 ].some(\n\t\t\t\tcol =>\n\t\t\t\t\ttypeof col === 'object' &&\n\t\t\t\t\tcol !== null &&\n\t\t\t\t\t'role' in col &&\n\t\t\t\t\tcol.role === 'tooltip' &&\n\t\t\t\t\t'p' in col &&\n\t\t\t\t\ttypeof col.p === 'object' &&\n\t\t\t\t\tcol.p !== null &&\n\t\t\t\t\t'html' in col.p &&\n\t\t\t\t\tcol.p.html === true\n\t\t\t),\n\t\t[ data ]\n\t);\n\n\tconst options: GoogleChartOptions = useMemo(\n\t\t() => ( {\n\t\t\t...( region !== 'world' && { region } ),\n\t\t\t...( resolution !== 'countries' && { resolution } ),\n\t\t\tcolorAxis: { colors: [ lightColorHex, fullColorHex ] },\n\t\t\tbackgroundColor: backgroundColorHex,\n\t\t\tdatalessRegionColor: defaultFillColorHex,\n\t\t\tdefaultColor: defaultFillColorHex,\n\t\t\ttooltip: { trigger: 'focus', isHtml: hasHtmlTooltips },\n\t\t\tlegend: 'none',\n\t\t\tkeepAspectRatio: true,\n\t\t} ),\n\t\t[\n\t\t\tregion,\n\t\t\tresolution,\n\t\t\tlightColorHex,\n\t\t\tfullColorHex,\n\t\t\tbackgroundColorHex,\n\t\t\tdefaultFillColorHex,\n\t\t\thasHtmlTooltips,\n\t\t]\n\t);\n\n\treturn (\n\t\t<div\n\t\t\tclassName={ clsx( 'geo-chart', styles.container, className ) }\n\t\t\tdata-testid=\"geo-chart\"\n\t\t\tstyle={ { width, height, backgroundColor } }\n\t\t>\n\t\t\t<Chart\n\t\t\t\tchartType=\"GeoChart\"\n\t\t\t\twidth={ width }\n\t\t\t\theight={ height }\n\t\t\t\tdata={ data }\n\t\t\t\toptions={ options }\n\t\t\t\tloader={ loadingPlaceholder }\n\t\t\t/>\n\t\t</div>\n\t);\n};\n\nconst GeoChartWithProvider: FC< GeoChartProps > = props => {\n\tconst existingContext = useContext( GlobalChartsContext );\n\n\t// If we're already in a GlobalChartsProvider context, don't create a new one\n\tif ( existingContext ) {\n\t\treturn <GeoChartInternal { ...props } />;\n\t}\n\n\t// Otherwise, create our own GlobalChartsProvider\n\treturn (\n\t\t<GlobalChartsProvider>\n\t\t\t<GeoChartInternal { ...props } />\n\t\t</GlobalChartsProvider>\n\t);\n};\n\nGeoChartWithProvider.displayName = 'GeoChart';\n\nconst GeoChartResponsive = withResponsive< GeoChartProps >( GeoChartWithProvider );\n\nexport { GeoChartResponsive as default, GeoChartWithProvider as GeoChartUnresponsive };\n","import 'css-chunk:src/charts/geo-chart/geo-chart.module.scss';export default {\n \"container\": \"a8ccharts-JvcqOz\"\n};"],"mappings":";;;;;;;;;;;;;;;AAGA,SAAS,UAAU;AACnB,OAAO,UAAU;AACjB,SAAa,YAAY,eAAe;AACxC,SAAS,aAAsC;;;ACNe,IAAO,2BAAQ;AAAA,EAC3E,aAAa;AACf;;;ADwDE;AAzCF,IAAM,6BAA6B;AACnC,IAAM,2BAA2B;AAqBjC,IAAM,mBAAwC,CAAE;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,aAAa;AAAA,EACb;AACD,MAAO;AACN,QAAM;AAAA,IACL;AAAA,IACA,OAAO;AAAA,MACN,UAAU,EAAE,iBAAiB;AAAA,MAC7B;AAAA,IACD;AAAA,EACD,IAAI,uBAAuB;AAG3B,QAAM,qBACL;AAAA,IAAC;AAAA;AAAA,MACA,WAAY,KAAM,aAAa,yBAAO,WAAW,SAAU;AAAA,MAC3D,eAAY;AAAA,MACZ,OAAQ,EAAE,OAAO,OAAO;AAAA,MAEtB,8BAAoB,kBAAkB,IAAI,GAAI,eAAe,gBAAiB;AAAA;AAAA,EACjF;AAID,QAAM,eAAe,iBAAkB,EAAE,OAAO,EAAE,CAAE,EAAE;AACtD,QAAM,gBAAgB,gBAAiB,cAAc,GAAI;AAEzD,QAAM,qBACL,oBAAqB,iBAAiB,MAAM,kBAAmB,KAAK;AACrE,QAAM,sBACL,oBAAqB,kBAAkB,MAAM,kBAAmB,KAAK;AAGtE,QAAM,kBAAkB;AAAA,IACvB,MACC,KAAK,SAAS,KACd,KAAM,CAAE,EAAE;AAAA,MACT,SACC,OAAO,QAAQ,YACf,QAAQ,QACR,UAAU,OACV,IAAI,SAAS,aACb,OAAO,OACP,OAAO,IAAI,MAAM,YACjB,IAAI,MAAM,QACV,UAAU,IAAI,KACd,IAAI,EAAE,SAAS;AAAA,IACjB;AAAA,IACD,CAAE,IAAK;AAAA,EACR;AAEA,QAAM,UAA8B;AAAA,IACnC,OAAQ;AAAA,MACP,GAAK,WAAW,WAAW,EAAE,OAAO;AAAA,MACpC,GAAK,eAAe,eAAe,EAAE,WAAW;AAAA,MAChD,WAAW,EAAE,QAAQ,CAAE,eAAe,YAAa,EAAE;AAAA,MACrD,iBAAiB;AAAA,MACjB,qBAAqB;AAAA,MACrB,cAAc;AAAA,MACd,SAAS,EAAE,SAAS,SAAS,QAAQ,gBAAgB;AAAA,MACrD,QAAQ;AAAA,MACR,iBAAiB;AAAA,IAClB;AAAA,IACA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAY,KAAM,aAAa,yBAAO,WAAW,SAAU;AAAA,MAC3D,eAAY;AAAA,MACZ,OAAQ,EAAE,OAAO,QAAQ,gBAAgB;AAAA,MAEzC;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAS;AAAA;AAAA,MACV;AAAA;AAAA,EACD;AAEF;AAEA,IAAM,uBAA4C,WAAS;AAC1D,QAAM,kBAAkB,WAAY,mBAAoB;AAGxD,MAAK,iBAAkB;AACtB,WAAO,oBAAC,oBAAmB,GAAG,OAAQ;AAAA,EACvC;AAGA,SACC,oBAAC,wBACA,8BAAC,oBAAmB,GAAG,OAAQ,GAChC;AAEF;AAEA,qBAAqB,cAAc;AAEnC,IAAM,qBAAqB,eAAiC,oBAAqB;","names":[]}
@@ -181,6 +181,13 @@ var validateHexColor = (hex) => {
181
181
  }
182
182
  throw new Error("Hex color contains invalid characters. Only 0-9, a-f, A-F are allowed");
183
183
  };
184
+ var hexToRgba = (hex, alpha) => {
185
+ validateHexColor(hex);
186
+ if (typeof alpha !== "number" || isNaN(alpha)) {
187
+ throw new Error("Alpha must be a number");
188
+ }
189
+ return d3Color(hex).copy({ opacity: alpha }).formatRgb();
190
+ };
184
191
  var getColorDistance = (hsl1, hsl2) => {
185
192
  const [h1, s1, l1] = hsl1;
186
193
  const [h2, s2, l2] = hsl2;
@@ -326,6 +333,7 @@ export {
326
333
  mergeThemes,
327
334
  isValidHexColor,
328
335
  validateHexColor,
336
+ hexToRgba,
329
337
  getColorDistance,
330
338
  parseHslString,
331
339
  parseRgbString,
@@ -333,4 +341,4 @@ export {
333
341
  lightenHexColor,
334
342
  resolveCssVariable
335
343
  };
336
- //# sourceMappingURL=chunk-P3QEXFTA.js.map
344
+ //# sourceMappingURL=chunk-TE63Y5PX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/create-composition.ts","../src/utils/date-parsing.ts","../src/utils/format-metric-value.ts","../src/utils/format-percentage.ts","../src/utils/get-longest-tick-width.ts","../src/utils/get-styles.ts","../src/utils/is-safari.ts","../src/utils/merge-themes.ts","../src/utils/color-utils.ts","../src/utils/resolve-css-var.ts"],"sourcesContent":["/**\n * Utility function to create chart components with composition API.\n *\n * This function attaches subcomponents to a chart component to enable\n * dot notation access like <Chart.Legend />, <Chart.Tooltip />, etc.\n *\n * @param Chart - The main chart component\n * @param subComponents - Object containing subcomponents to attach\n * @return Chart component with attached subcomponents\n */\nexport function attachSubComponents< TChart, TSubComponents extends Record< string, unknown > >(\n\tChart: TChart,\n\tsubComponents: TSubComponents\n): TChart & TSubComponents {\n\treturn Object.assign( Chart, subComponents );\n}\n","/**\n * @file Date parsing utilities using date-fns for local timezone handling\n *\n * This module provides utilities for parsing various date string formats and converting\n * them to local timezone dates using the battle-tested date-fns library. For formats\n * without timezone info, they're treated as local. For formats with timezone info,\n * they're converted to the equivalent local time.\n *\n * Note: And specifically it prevents format `YYYY-MM-DD` being parsed as UTC date.\n *\n * Key Features:\n * - All parsed dates are in local timezone\n * - Converts timezone-aware strings to local equivalent\n * - Robust input validation and error handling using date-fns\n * - TypeScript type safety\n * - Much smaller codebase than custom parsing\n *\n * Supported Formats:\n * - YYYY-MM-DD (treated as local)\n * - YYYY-MM-DD HH:mm:ss (treated as local)\n * - YYYY-MM-DD HH:mm (treated as local)\n * - YYYY-MM-DDTHH:mm:ss (treated as local)\n * - YYYY-MM-DDTHH:mm:ss.SSS (treated as local)\n * - YYYY-MM-DDTHH:mm (treated as local)\n * - YYYY-MM-DDTHH:mm:ssZ (converted to local)\n * - YYYY-MM-DDTHH:mm:ss±HH:mm (converted to local)\n *\n * @example\n * ```typescript\n * parseAsLocalDate(\"2025-01-01\"); // Local timezone\n * parseAsLocalDate(\"2025-01-01 14:30:00\"); // Local timezone\n * parseAsLocalDate(\"2025-01-01 14:30\"); // Local timezone\n * parseAsLocalDate(\"2025-01-01T14:30:45.123\"); // Local timezone\n * parseAsLocalDate(\"2025-01-01T14:30:00Z\"); // UTC 14:30 → Local equivalent\n * parseAsLocalDate(\"2025-01-01T14:30:00+05:00\"); // +05:00 14:30 → Local equivalent\n * ```\n */\n\nimport { parse, parseISO, isValid } from 'date-fns';\n\n/**\n * Checks if a date string contains timezone information\n * @param {string} dateString - The date string to check for timezone information\n * @return {boolean} True if the date string contains timezone information, false otherwise\n */\nconst hasTimezone = ( dateString: string ): boolean => {\n\treturn /T.*[Z]$|T.*[+-]\\d{2}:?\\d{2}$/.test( dateString );\n};\n\n/**\n * Parses any supported date string format and returns a local timezone date\n *\n * Uses date-fns for robust parsing and validation. For strings without timezone\n * info, treats as local timezone. For strings with timezone info, converts to\n * local timezone equivalent.\n *\n * Supports:\n * - YYYY-MM-DD (local)\n * - YYYY-MM-DD HH:mm:ss (local)\n * - YYYY-MM-DD HH:mm (local)\n * - YYYY-MM-DDTHH:mm:ss (local)\n * - YYYY-MM-DDTHH:mm:ss.SSS (local)\n * - YYYY-MM-DDTHH:mm (local)\n * - YYYY-MM-DDTHH:mm:ssZ (UTC → local)\n * - YYYY-MM-DDTHH:mm:ss±HH:mm (offset → local)\n * @param {string} dateString - The date string to parse into a local timezone date\n * @return {Date} A Date object representing the parsed date in local timezone, or an invalid Date if parsing fails\n */\nexport const parseAsLocalDate = ( dateString: string ): Date => {\n\tconst trimmedString = dateString.trim();\n\n\t// If it has timezone information, parse as ISO and convert to local\n\tif ( hasTimezone( trimmedString ) ) {\n\t\tconst isoDate = parseISO( trimmedString );\n\n\t\tif ( ! isValid( isoDate ) ) {\n\t\t\treturn new Date( NaN );\n\t\t}\n\n\t\t// parseISO automatically converts to local timezone\n\t\treturn isoDate;\n\t}\n\n\t// For naive strings, try different local formats\n\tconst formats = [\n\t\t'yyyy-MM-dd', // 2025-01-01\n\t\t'yyyy-MM-dd HH:mm:ss', // 2025-01-01 14:30:45\n\t\t'yyyy-MM-dd HH:mm', // 2025-01-01 14:30\n\t\t\"yyyy-MM-dd'T'HH:mm:ss\", // 2025-01-01T14:30:45\n\t\t\"yyyy-MM-dd'T'HH:mm:ss.SSS\", // 2025-01-01T14:30:45.123\n\t\t\"yyyy-MM-dd'T'HH:mm\", // 2025-01-01T14:30\n\t];\n\n\tfor ( const format of formats ) {\n\t\tconst result = parse( trimmedString, format, new Date() );\n\t\tif ( isValid( result ) ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\t// If no format matched, return invalid date\n\treturn new Date( NaN );\n};\n","import { formatNumberCompact, formatNumber } from '@automattic/number-formatters';\n\n/**\n * Types for formatMetricValue\n */\nexport type MetricValueType = 'number' | 'average' | 'currency';\n\ntype FormatMetricValueOptions = {\n\tdecimals?: number;\n\tuseMultipliers?: boolean;\n\tsignDisplay?: Intl.NumberFormatOptions[ 'signDisplay' ];\n};\n\n/**\n * Format a numeric metric value based on type, precision and scale.\n * Supports currency, number and percentage, using `@automattic/number-formatters`.\n *\n * @param value - The value to format\n * @param type - The type of formatting to apply\n * @param options - Formatting options\n * @param options.decimals - Number of decimal places to show\n * @param options.useMultipliers - Whether to use K, M, B suffixes for large numbers\n * @param options.signDisplay - Controls when to display the sign (auto, always, never, exceptZero)\n * @return Formatted string\n */\nexport const formatMetricValue = (\n\tvalue: string | number,\n\ttype: MetricValueType = 'number',\n\t{ decimals, useMultipliers = false, signDisplay }: FormatMetricValueOptions = {}\n): string => {\n\tif ( value === null || value === undefined ) {\n\t\treturn '';\n\t}\n\n\tconst numericValue = Number( value );\n\tif ( isNaN( numericValue ) ) {\n\t\treturn '';\n\t}\n\n\tswitch ( type ) {\n\t\tcase 'currency': {\n\t\t\t// Basic currency formatting - can be enhanced with full currency support\n\t\t\tconst formatted = useMultipliers\n\t\t\t\t? formatNumberCompact( numericValue, {\n\t\t\t\t\t\tdecimals: decimals ?? 2,\n\t\t\t\t\t\tnumberFormatOptions: {\n\t\t\t\t\t\t\tmaximumFractionDigits: decimals ?? 2,\n\t\t\t\t\t\t\tsignDisplay,\n\t\t\t\t\t\t},\n\t\t\t\t } )\n\t\t\t\t: formatNumber( numericValue, {\n\t\t\t\t\t\tdecimals: decimals ?? 2,\n\t\t\t\t\t\tnumberFormatOptions: {\n\t\t\t\t\t\t\tsignDisplay,\n\t\t\t\t\t\t},\n\t\t\t\t } );\n\t\t\treturn `$${ formatted }`;\n\t\t}\n\n\t\tcase 'average': {\n\t\t\tif ( ! Number.isFinite( numericValue ) ) {\n\t\t\t\treturn '—';\n\t\t\t}\n\n\t\t\treturn formatNumber( numericValue, {\n\t\t\t\tdecimals: decimals ?? 0,\n\t\t\t\tnumberFormatOptions: {\n\t\t\t\t\tstyle: 'percent',\n\t\t\t\t\tsignDisplay: signDisplay ?? 'exceptZero',\n\t\t\t\t},\n\t\t\t} );\n\t\t}\n\n\t\tcase 'number':\n\t\tdefault: {\n\t\t\treturn useMultipliers\n\t\t\t\t? formatNumberCompact( numericValue, {\n\t\t\t\t\t\tdecimals: decimals ?? 0,\n\t\t\t\t\t\tnumberFormatOptions: {\n\t\t\t\t\t\t\tmaximumFractionDigits: decimals ?? 0,\n\t\t\t\t\t\t\tsignDisplay,\n\t\t\t\t\t\t},\n\t\t\t\t } )\n\t\t\t\t: formatNumber( numericValue, {\n\t\t\t\t\t\tdecimals: decimals ?? 0,\n\t\t\t\t\t\tnumberFormatOptions: {\n\t\t\t\t\t\t\tsignDisplay,\n\t\t\t\t\t\t},\n\t\t\t\t } );\n\t\t}\n\t}\n};\n","import { formatNumber } from '@automattic/number-formatters';\n\n/**\n * Format a percentage value with smart decimal handling.\n * Uses `@automattic/number-formatters` for consistent formatting.\n * Removes unnecessary trailing zeros and caps at 2 decimal places.\n *\n * @param value - The percentage value (0-100 range)\n * @return Formatted percentage string (e.g., \"30%\", \"30.1%\", \"30.25%\")\n */\nexport const formatPercentage = ( value: number ): string => {\n\t// Use formatNumber with percentage style, but convert from 0-100 range to 0-1 range\n\treturn formatNumber( value / 100, {\n\t\tnumberFormatOptions: {\n\t\t\tstyle: 'percent',\n\t\t\tminimumFractionDigits: 0,\n\t\t\tmaximumFractionDigits: 2,\n\t\t},\n\t} );\n};\n","import { getStringWidth } from '@visx/text';\nimport type { TickFormatter } from '@visx/axis';\nimport type { AnyD3Scale, ScaleInput } from '@visx/scale';\n\n/**\n * Returns the width of the longest tick.\n *\n * @param ticks - Ticks to get the width of.\n * @param formatTick - Function to format the tick.\n * @param {object} labelStyle - Style object for the label.\n * @return {number} - Width of the longest tick.\n */\nexport const getLongestTickWidth = < T extends AnyD3Scale >(\n\tticks: ScaleInput< T >[],\n\tformatTick: TickFormatter< ScaleInput< T > >,\n\tlabelStyle?: object\n) => {\n\tconst formattedTicks = ticks.map( tick => formatTick( tick, 0, [] ) );\n\tconst longestTick = formattedTicks.reduce(\n\t\t( longest, current ) => ( longest.length >= current.length ? longest : current ),\n\t\tformattedTicks[ 0 ]\n\t);\n\n\treturn getStringWidth( longestTick, labelStyle );\n};\n","import type { ChartTheme, SeriesData } from '../types';\nimport type { LegendShape } from '@visx/legend/lib/types';\nimport type { LineStyles } from '@visx/xychart';\n\n/**\n * Utility function to get consolidated line styles for a series\n * This consolidates the logic used by both LineChart and Legend components\n *\n * @param {SeriesData} seriesData - The series data containing styling options\n * @param {number} index - The index of the series in the data array\n * @param {ChartTheme} providerTheme - The chart theme configuration\n * @return {LineStyles} The consolidated line styles for the series\n */\nexport function getSeriesLineStyles(\n\tseriesData: SeriesData,\n\tindex: number,\n\tproviderTheme: ChartTheme\n): LineStyles {\n\t// Get theme-based line styles for line type\n\tconst themeSemanticLineStyle = providerTheme?.lineChart?.lineStyles?.[ seriesData.options?.type ];\n\n\t// Get theme-based line styles for index of series data\n\tconst themeSeriesLineStyle =\n\t\tproviderTheme?.seriesLineStyles?.[ index % providerTheme.seriesLineStyles.length ];\n\n\t// Priority order: custom series style > theme line type style > default theme series style\n\treturn (\n\t\tseriesData.options?.seriesLineStyle ?? themeSemanticLineStyle ?? themeSeriesLineStyle ?? {}\n\t);\n}\n\n/**\n * Utility function to get stroke color for a series\n *\n * @param {SeriesData} seriesData - The series data containing styling options\n * @param {number} index - The index of the series in the data array\n * @param {string[]} themeColors - Array of theme colors\n * @return {string} The stroke color for the series\n */\nexport function getSeriesStroke(\n\tseriesData: SeriesData,\n\tindex: number,\n\tthemeColors: string[]\n): string {\n\treturn seriesData.options?.stroke ?? themeColors[ index % themeColors.length ];\n}\n\n/**\n * Utility function to get shape styles for a legend item\n *\n * @param {SeriesData} series - The series data containing styling options\n * @param {number} index - The index of the series in the data array\n * @param {ChartTheme} theme - The chart theme configuration\n * @param {LegendShape} legendShape - The shape to use for the item (optional)\n * @return {Record< string, unknown >} The shape styles for the item\n */\nexport function getItemShapeStyles(\n\tseries: SeriesData,\n\tindex: number,\n\ttheme: ChartTheme,\n\tlegendShape?: LegendShape< SeriesData[], number >\n): Record< string, unknown > {\n\tconst seriesShapeStyles = series.options?.legendShapeStyle ?? {};\n\tconst lineStyles = legendShape === 'line' ? getSeriesLineStyles( series, index, theme ) : {};\n\tconst themeShapeStyles = theme.legendShapeStyles?.[ index ];\n\n\tconst itemShapeStyles = {\n\t\t...seriesShapeStyles,\n\t\t...lineStyles,\n\t};\n\n\t// Return item shape styles if they are not empty\n\tif (\n\t\tObject.values( itemShapeStyles ).some(\n\t\t\tvalue => value !== undefined && value !== null && value !== ''\n\t\t)\n\t) {\n\t\treturn itemShapeStyles;\n\t}\n\n\t// Fallback to theme shape styles if defined\n\treturn themeShapeStyles ?? {};\n}\n","export const isSafari = () => {\n\tif ( typeof navigator !== 'undefined' && navigator.userAgent ) {\n\t\treturn /^((?!chrome|android).)*safari/i.test( navigator.userAgent );\n\t}\n\treturn false;\n};\n","import deepmerge from 'deepmerge';\nimport type { ChartTheme, CompleteChartTheme } from '../types';\n\n/**\n * Merges chart themes with proper precedence.\n * The second theme (override) takes precedence over the first theme (base).\n *\n * @param baseTheme - Base theme object\n * @param overrideTheme - Theme to override base with (takes precedence)\n * @return Merged theme with overrideTheme values taking precedence\n */\nexport function mergeThemes(\n\tbaseTheme: CompleteChartTheme,\n\toverrideTheme: Partial< ChartTheme >\n): CompleteChartTheme;\nexport function mergeThemes(\n\tbaseTheme: ChartTheme,\n\toverrideTheme: Partial< ChartTheme >\n): ChartTheme;\nexport function mergeThemes(\n\tbaseTheme: ChartTheme,\n\toverrideTheme: Partial< ChartTheme >\n): ChartTheme {\n\t// Use deepmerge to properly merge nested objects, with overrideTheme taking precedence\n\treturn deepmerge( baseTheme, overrideTheme, {\n\t\t// Ensure arrays are replaced rather than concatenated\n\t\tarrayMerge: ( _destinationArray, sourceArray ) => sourceArray,\n\t} ) as ChartTheme;\n}\n","import { color as d3Color, hsl as d3Hsl } from '@visx/vendor/d3-color';\n\n/**\n * Check if a value is a valid 6-digit hex color\n * @param hex - The value to check\n * @return true if valid hex color format (e.g., '#ff0000')\n */\nexport const isValidHexColor = ( hex: unknown ): hex is string => {\n\treturn typeof hex === 'string' && /^#[0-9a-fA-F]{6}$/.test( hex );\n};\n\n/**\n * Validate hex color format, throwing descriptive errors if invalid\n * @param hex - The hex color string to validate\n * @throws {Error} if hex string is malformed\n */\nexport const validateHexColor = ( hex: unknown ): void => {\n\tif ( isValidHexColor( hex ) ) {\n\t\treturn;\n\t}\n\n\t// Provide specific error messages for common issues\n\tif ( typeof hex !== 'string' ) {\n\t\tthrow new Error( 'Hex color must be a string' );\n\t}\n\tif ( ! hex.startsWith( '#' ) ) {\n\t\tthrow new Error( 'Hex color must start with #' );\n\t}\n\tif ( hex.length !== 7 ) {\n\t\tthrow new Error( 'Hex color must be 7 characters long (e.g., #ff0000)' );\n\t}\n\tthrow new Error( 'Hex color contains invalid characters. Only 0-9, a-f, A-F are allowed' );\n};\n\n/**\n * Convert hex color to rgba with specified opacity.\n * This is genuinely reusable across chart components.\n * @param hex - The hex color string (e.g., '#ff0000')\n * @param alpha - The opacity value. Values outside the [0, 1] range will be clamped by the underlying d3 color library.\n * @return The rgba color string (e.g., 'rgba(255, 0, 0, 0.5)')\n * @throws {Error} if hex string is malformed or alpha is not a valid number\n */\nexport const hexToRgba = ( hex: string, alpha: number ): string => {\n\tvalidateHexColor( hex );\n\n\tif ( typeof alpha !== 'number' || isNaN( alpha ) ) {\n\t\tthrow new Error( 'Alpha must be a number' );\n\t}\n\n\t// Safe to use non-null assertion since validateHexColor ensures valid hex\n\treturn d3Color( hex )!.copy( { opacity: alpha } ).formatRgb();\n};\n\n/**\n * Calculate the perceptual distance between two HSL colors\n * @param hsl1 - first color in HSL format [h, s, l]\n * @param hsl2 - second color in HSL format [h, s, l]\n * @return distance value (0-100+, lower means more similar)\n */\nexport const getColorDistance = (\n\thsl1: [ number, number, number ],\n\thsl2: [ number, number, number ]\n): number => {\n\tconst [ h1, s1, l1 ] = hsl1;\n\tconst [ h2, s2, l2 ] = hsl2;\n\n\t// Calculate hue difference, accounting for circular nature (0° = 360°)\n\tlet hueDiff = Math.abs( h1 - h2 );\n\thueDiff = Math.min( hueDiff, 360 - hueDiff );\n\n\t// Weight the differences: hue is most important, then lightness, then saturation\n\tconst hueWeight = 2;\n\tconst lightnessWeight = 1;\n\tconst saturationWeight = 0.5;\n\n\treturn Math.sqrt(\n\t\tMath.pow( hueDiff * hueWeight, 2 ) +\n\t\t\tMath.pow( ( l1 - l2 ) * lightnessWeight, 2 ) +\n\t\t\tMath.pow( ( s1 - s2 ) * saturationWeight, 2 )\n\t);\n};\n\n/**\n * Parse an HSL string like 'hsl(120, 50%, 50%)' into an HSL tuple.\n *\n * @param hslString - HSL color string\n * @return HSL tuple [h, s, l] or null if invalid\n */\nexport const parseHslString = ( hslString: string ): [ number, number, number ] | null => {\n\tconst lower = hslString.toLowerCase().trim();\n\n\t// Check prefix - d3-color handles the parsing\n\tif ( ! lower.startsWith( 'hsl(' ) ) {\n\t\treturn null;\n\t}\n\n\tconst parsed = d3Hsl( lower );\n\n\t// d3Hsl returns NaN values for invalid colors\n\tif ( isNaN( parsed.h ) && isNaN( parsed.s ) && isNaN( parsed.l ) ) {\n\t\treturn null;\n\t}\n\n\t// Normalize hue to 0-360 range (d3 may return NaN for achromatic colors)\n\tconst h = isNaN( parsed.h ) ? 0 : ( ( parsed.h % 360 ) + 360 ) % 360;\n\n\t// d3-color uses 0-1 scale, convert to 0-100\n\treturn [ h, parsed.s * 100, parsed.l * 100 ];\n};\n\n/**\n * Parse an RGB string like 'rgb(255, 0, 0)' into a hex color.\n *\n * @param rgbString - RGB color string\n * @return hex color string or null if invalid\n */\nexport const parseRgbString = ( rgbString: string ): string | null => {\n\tconst lower = rgbString.toLowerCase().trim();\n\n\t// Check prefix - only handle rgb(), not rgba()\n\tif ( ! lower.startsWith( 'rgb(' ) || lower.startsWith( 'rgba(' ) ) {\n\t\treturn null;\n\t}\n\n\tconst parsed = d3Color( lower );\n\n\t// d3Color returns null for invalid colors\n\tif ( ! parsed ) {\n\t\treturn null;\n\t}\n\n\t// d3-color clamps values automatically\n\treturn parsed.formatHex();\n};\n\n/**\n * Normalize any CSS color value to a hex color string.\n * Handles hex colors, HSL strings, RGB strings, and CSS variables.\n *\n * @param color - Any CSS color value\n * @param element - Optional DOM element for resolving CSS variables\n * @param resolveCss - Function to resolve CSS variables (injected for testability)\n * @return hex color string, or the original value if conversion fails\n */\nexport const normalizeColorToHex = (\n\tcolor: string,\n\telement?: HTMLElement | null,\n\tresolveCss?: ( value: string, el?: HTMLElement | null ) => string | null\n): string => {\n\tif ( ! color || typeof color !== 'string' ) {\n\t\treturn '';\n\t}\n\n\t// Already a valid hex color (6-digit format)\n\tif ( /^#[0-9a-fA-F]{6}$/.test( color ) ) {\n\t\treturn color;\n\t}\n\n\tconst trimmed = color.trim().toLowerCase();\n\n\t// Handle 3-digit hex colors - expand to 6-digit\n\tif ( /^#[0-9a-f]{3}$/i.test( trimmed ) ) {\n\t\tconst r = trimmed[ 1 ];\n\t\tconst g = trimmed[ 2 ];\n\t\tconst b = trimmed[ 3 ];\n\t\treturn `#${ r }${ r }${ g }${ g }${ b }${ b }`;\n\t}\n\n\t// Handle CSS variables - must be resolved before d3-color can parse\n\tif ( trimmed.startsWith( '--' ) || trimmed.startsWith( 'var(' ) ) {\n\t\tif ( resolveCss ) {\n\t\t\tconst resolved = resolveCss( color, element );\n\t\t\tif ( resolved ) {\n\t\t\t\t// Recursively normalize the resolved value\n\t\t\t\treturn normalizeColorToHex( resolved, element, resolveCss );\n\t\t\t}\n\t\t}\n\t\t// Can't resolve CSS variable, return original\n\t\treturn color;\n\t}\n\n\t// Handle HSL and RGB strings using d3-color\n\tif ( trimmed.startsWith( 'hsl(' ) || trimmed.startsWith( 'rgb(' ) ) {\n\t\t// Reject rgba() - we only handle rgb()\n\t\tif ( trimmed.startsWith( 'rgba(' ) ) {\n\t\t\treturn color;\n\t\t}\n\t\tconst parsed = d3Color( trimmed );\n\t\tif ( parsed ) {\n\t\t\treturn parsed.formatHex();\n\t\t}\n\t\treturn color;\n\t}\n\n\t// Unknown format, return as-is\n\treturn color;\n};\n\n/**\n * Lighten a hex color by blending it with white.\n * Useful for creating color gradients or lighter variants.\n *\n * @param hex - Hex color string (e.g., '#98C8DF')\n * @param blend - Blend amount with white (0 = original color, 1 = white)\n * @return Lightened hex color string (e.g., '#cce4ef')\n * @throws {Error} if hex string is malformed\n */\nexport const lightenHexColor = ( hex: string, blend: number ): string => {\n\tvalidateHexColor( hex );\n\n\tconst r = parseInt( hex.slice( 1, 3 ), 16 );\n\tconst g = parseInt( hex.slice( 3, 5 ), 16 );\n\tconst b = parseInt( hex.slice( 5, 7 ), 16 );\n\n\t// Blend with white (255, 255, 255)\n\tconst newR = Math.round( r + ( 255 - r ) * blend );\n\tconst newG = Math.round( g + ( 255 - g ) * blend );\n\tconst newB = Math.round( b + ( 255 - b ) * blend );\n\n\treturn `#${ newR.toString( 16 ).padStart( 2, '0' ) }${ newG\n\t\t.toString( 16 )\n\t\t.padStart( 2, '0' ) }${ newB.toString( 16 ).padStart( 2, '0' ) }`;\n};\n","/**\n * Pattern for valid CSS custom property names (e.g., '--my-color', '--jp-gray-10')\n */\nconst CSS_VAR_NAME_PATTERN = /^--[\\w-]+$/;\n\n/**\n * Resolves a CSS custom property (variable) to its computed value.\n * Handles multiple formats:\n * - Plain variable names: '--my-color'\n * - CSS var() syntax: 'var(--my-color)'\n * - CSS var() with fallback: 'var(--my-color, #ffffff)'\n * - Regular values (returned as-is): '#ffffff', 'red'\n *\n * @param value - A CSS variable name, var() expression, or regular value\n * @param element - Optional DOM element to resolve the variable from (defaults to document.documentElement)\n * @return The resolved value, fallback value, or null if unresolvable\n */\nexport const resolveCssVariable = (\n\tvalue: string,\n\telement?: HTMLElement | null\n): string | null => {\n\tif ( ! value ) {\n\t\treturn null;\n\t}\n\n\t// Check if it's a var() expression: var(--name) or var(--name, fallback)\n\t// Parse manually to avoid regex backtracking vulnerabilities\n\tif ( value.startsWith( 'var(' ) && value.endsWith( ')' ) ) {\n\t\tconst parsed = parseVarExpression( value );\n\n\t\tif ( parsed ) {\n\t\t\tconst resolved = resolveVariableName( parsed.varName, element );\n\n\t\t\treturn resolved || parsed.fallback;\n\t\t}\n\t}\n\n\t// Check if it's a plain variable name (starts with --)\n\tif ( value.startsWith( '--' ) ) {\n\t\treturn resolveVariableName( value, element );\n\t}\n\n\t// Return regular values as-is (e.g., '#ffffff', 'red')\n\treturn value;\n};\n\n/**\n * Parses a var() expression into its variable name and optional fallback.\n * Uses string manipulation instead of complex regex to avoid ReDoS.\n *\n * @param expr - A var() expression like 'var(--name)' or 'var(--name, fallback)'\n * @return Parsed result or null if invalid\n */\nfunction parseVarExpression( expr: string ): { varName: string; fallback: string | null } | null {\n\t// Remove 'var(' prefix and ')' suffix\n\tconst inner = expr.slice( 4, -1 ).trim();\n\n\tif ( ! inner.startsWith( '--' ) ) {\n\t\treturn null;\n\t}\n\n\t// Find the comma separator (if any)\n\tconst commaIndex = inner.indexOf( ',' );\n\n\tif ( commaIndex === -1 ) {\n\t\t// No fallback: var(--name)\n\t\tconst varName = inner.trim();\n\t\t// Validate variable name format\n\t\tif ( ! CSS_VAR_NAME_PATTERN.test( varName ) ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn { varName, fallback: null };\n\t}\n\n\t// Has fallback: var(--name, fallback)\n\tconst varName = inner.slice( 0, commaIndex ).trim();\n\n\t// Validate variable name format\n\tif ( ! CSS_VAR_NAME_PATTERN.test( varName ) ) {\n\t\treturn null;\n\t}\n\n\tconst fallback = inner.slice( commaIndex + 1 ).trim();\n\n\treturn { varName, fallback: fallback || null };\n}\n\n/**\n * Resolves a plain CSS variable name to its computed value.\n *\n * @param varName - A CSS variable name like '--my-color'\n * @param element - Optional DOM element to resolve from\n * @return The computed value or null\n */\nfunction resolveVariableName( varName: string, element?: HTMLElement | null ): string | null {\n\tif ( typeof window === 'undefined' || typeof document === 'undefined' ) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst targetElement = element || document.documentElement;\n\t\tconst computedValue = getComputedStyle( targetElement ).getPropertyValue( varName ).trim();\n\n\t\treturn computedValue || null;\n\t} catch {\n\t\t// Return null if getComputedStyle throws (e.g., detached element)\n\t\treturn null;\n\t}\n}\n"],"mappings":";AAUO,SAAS,oBACf,OACA,eAC0B;AAC1B,SAAO,OAAO,OAAQ,OAAO,aAAc;AAC5C;;;ACuBA,SAAS,OAAO,UAAU,eAAe;AAOzC,IAAM,cAAc,CAAE,eAAiC;AACtD,SAAO,+BAA+B,KAAM,UAAW;AACxD;AAqBO,IAAM,mBAAmB,CAAE,eAA8B;AAC/D,QAAM,gBAAgB,WAAW,KAAK;AAGtC,MAAK,YAAa,aAAc,GAAI;AACnC,UAAM,UAAU,SAAU,aAAc;AAExC,QAAK,CAAE,QAAS,OAAQ,GAAI;AAC3B,aAAO,oBAAI,KAAM,GAAI;AAAA,IACtB;AAGA,WAAO;AAAA,EACR;AAGA,QAAM,UAAU;AAAA,IACf;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACD;AAEA,aAAY,UAAU,SAAU;AAC/B,UAAM,SAAS,MAAO,eAAe,QAAQ,oBAAI,KAAK,CAAE;AACxD,QAAK,QAAS,MAAO,GAAI;AACxB,aAAO;AAAA,IACR;AAAA,EACD;AAGA,SAAO,oBAAI,KAAM,GAAI;AACtB;;;ACtGA,SAAS,qBAAqB,oBAAoB;AAyB3C,IAAM,oBAAoB,CAChC,OACA,OAAwB,UACxB,EAAE,UAAU,iBAAiB,OAAO,YAAY,IAA8B,CAAC,MACnE;AACZ,MAAK,UAAU,QAAQ,UAAU,QAAY;AAC5C,WAAO;AAAA,EACR;AAEA,QAAM,eAAe,OAAQ,KAAM;AACnC,MAAK,MAAO,YAAa,GAAI;AAC5B,WAAO;AAAA,EACR;AAEA,UAAS,MAAO;AAAA,IACf,KAAK,YAAY;AAEhB,YAAM,YAAY,iBACf,oBAAqB,cAAc;AAAA,QACnC,UAAU,YAAY;AAAA,QACtB,qBAAqB;AAAA,UACpB,uBAAuB,YAAY;AAAA,UACnC;AAAA,QACD;AAAA,MACA,CAAE,IACF,aAAc,cAAc;AAAA,QAC5B,UAAU,YAAY;AAAA,QACtB,qBAAqB;AAAA,UACpB;AAAA,QACD;AAAA,MACA,CAAE;AACL,aAAO,IAAK,SAAU;AAAA,IACvB;AAAA,IAEA,KAAK,WAAW;AACf,UAAK,CAAE,OAAO,SAAU,YAAa,GAAI;AACxC,eAAO;AAAA,MACR;AAEA,aAAO,aAAc,cAAc;AAAA,QAClC,UAAU,YAAY;AAAA,QACtB,qBAAqB;AAAA,UACpB,OAAO;AAAA,UACP,aAAa,eAAe;AAAA,QAC7B;AAAA,MACD,CAAE;AAAA,IACH;AAAA,IAEA,KAAK;AAAA,IACL,SAAS;AACR,aAAO,iBACJ,oBAAqB,cAAc;AAAA,QACnC,UAAU,YAAY;AAAA,QACtB,qBAAqB;AAAA,UACpB,uBAAuB,YAAY;AAAA,UACnC;AAAA,QACD;AAAA,MACA,CAAE,IACF,aAAc,cAAc;AAAA,QAC5B,UAAU,YAAY;AAAA,QACtB,qBAAqB;AAAA,UACpB;AAAA,QACD;AAAA,MACA,CAAE;AAAA,IACN;AAAA,EACD;AACD;;;AC3FA,SAAS,gBAAAA,qBAAoB;AAUtB,IAAM,mBAAmB,CAAE,UAA2B;AAE5D,SAAOA,cAAc,QAAQ,KAAK;AAAA,IACjC,qBAAqB;AAAA,MACpB,OAAO;AAAA,MACP,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,IACxB;AAAA,EACD,CAAE;AACH;;;ACnBA,SAAS,sBAAsB;AAYxB,IAAM,sBAAsB,CAClC,OACA,YACA,eACI;AACJ,QAAM,iBAAiB,MAAM,IAAK,UAAQ,WAAY,MAAM,GAAG,CAAC,CAAE,CAAE;AACpE,QAAM,cAAc,eAAe;AAAA,IAClC,CAAE,SAAS,YAAe,QAAQ,UAAU,QAAQ,SAAS,UAAU;AAAA,IACvE,eAAgB,CAAE;AAAA,EACnB;AAEA,SAAO,eAAgB,aAAa,UAAW;AAChD;;;ACXO,SAAS,oBACf,YACA,OACA,eACa;AAEb,QAAM,yBAAyB,eAAe,WAAW,aAAc,WAAW,SAAS,IAAK;AAGhG,QAAM,uBACL,eAAe,mBAAoB,QAAQ,cAAc,iBAAiB,MAAO;AAGlF,SACC,WAAW,SAAS,mBAAmB,0BAA0B,wBAAwB,CAAC;AAE5F;AAUO,SAAS,gBACf,YACA,OACA,aACS;AACT,SAAO,WAAW,SAAS,UAAU,YAAa,QAAQ,YAAY,MAAO;AAC9E;AAWO,SAAS,mBACf,QACA,OACA,OACA,aAC4B;AAC5B,QAAM,oBAAoB,OAAO,SAAS,oBAAoB,CAAC;AAC/D,QAAM,aAAa,gBAAgB,SAAS,oBAAqB,QAAQ,OAAO,KAAM,IAAI,CAAC;AAC3F,QAAM,mBAAmB,MAAM,oBAAqB,KAAM;AAE1D,QAAM,kBAAkB;AAAA,IACvB,GAAG;AAAA,IACH,GAAG;AAAA,EACJ;AAGA,MACC,OAAO,OAAQ,eAAgB,EAAE;AAAA,IAChC,WAAS,UAAU,UAAa,UAAU,QAAQ,UAAU;AAAA,EAC7D,GACC;AACD,WAAO;AAAA,EACR;AAGA,SAAO,oBAAoB,CAAC;AAC7B;;;AClFO,IAAM,WAAW,MAAM;AAC7B,MAAK,OAAO,cAAc,eAAe,UAAU,WAAY;AAC9D,WAAO,iCAAiC,KAAM,UAAU,SAAU;AAAA,EACnE;AACA,SAAO;AACR;;;ACLA,OAAO,eAAe;AAmBf,SAAS,YACf,WACA,eACa;AAEb,SAAO,UAAW,WAAW,eAAe;AAAA;AAAA,IAE3C,YAAY,CAAE,mBAAmB,gBAAiB;AAAA,EACnD,CAAE;AACH;;;AC5BA,SAAS,SAAS,SAAS,OAAO,aAAa;AAOxC,IAAM,kBAAkB,CAAE,QAAiC;AACjE,SAAO,OAAO,QAAQ,YAAY,oBAAoB,KAAM,GAAI;AACjE;AAOO,IAAM,mBAAmB,CAAE,QAAwB;AACzD,MAAK,gBAAiB,GAAI,GAAI;AAC7B;AAAA,EACD;AAGA,MAAK,OAAO,QAAQ,UAAW;AAC9B,UAAM,IAAI,MAAO,4BAA6B;AAAA,EAC/C;AACA,MAAK,CAAE,IAAI,WAAY,GAAI,GAAI;AAC9B,UAAM,IAAI,MAAO,6BAA8B;AAAA,EAChD;AACA,MAAK,IAAI,WAAW,GAAI;AACvB,UAAM,IAAI,MAAO,qDAAsD;AAAA,EACxE;AACA,QAAM,IAAI,MAAO,uEAAwE;AAC1F;AAUO,IAAM,YAAY,CAAE,KAAa,UAA2B;AAClE,mBAAkB,GAAI;AAEtB,MAAK,OAAO,UAAU,YAAY,MAAO,KAAM,GAAI;AAClD,UAAM,IAAI,MAAO,wBAAyB;AAAA,EAC3C;AAGA,SAAO,QAAS,GAAI,EAAG,KAAM,EAAE,SAAS,MAAM,CAAE,EAAE,UAAU;AAC7D;AAQO,IAAM,mBAAmB,CAC/B,MACA,SACY;AACZ,QAAM,CAAE,IAAI,IAAI,EAAG,IAAI;AACvB,QAAM,CAAE,IAAI,IAAI,EAAG,IAAI;AAGvB,MAAI,UAAU,KAAK,IAAK,KAAK,EAAG;AAChC,YAAU,KAAK,IAAK,SAAS,MAAM,OAAQ;AAG3C,QAAM,YAAY;AAClB,QAAM,kBAAkB;AACxB,QAAM,mBAAmB;AAEzB,SAAO,KAAK;AAAA,IACX,KAAK,IAAK,UAAU,WAAW,CAAE,IAChC,KAAK,KAAO,KAAK,MAAO,iBAAiB,CAAE,IAC3C,KAAK,KAAO,KAAK,MAAO,kBAAkB,CAAE;AAAA,EAC9C;AACD;AAQO,IAAM,iBAAiB,CAAE,cAA0D;AACzF,QAAM,QAAQ,UAAU,YAAY,EAAE,KAAK;AAG3C,MAAK,CAAE,MAAM,WAAY,MAAO,GAAI;AACnC,WAAO;AAAA,EACR;AAEA,QAAM,SAAS,MAAO,KAAM;AAG5B,MAAK,MAAO,OAAO,CAAE,KAAK,MAAO,OAAO,CAAE,KAAK,MAAO,OAAO,CAAE,GAAI;AAClE,WAAO;AAAA,EACR;AAGA,QAAM,IAAI,MAAO,OAAO,CAAE,IAAI,KAAQ,OAAO,IAAI,MAAQ,OAAQ;AAGjE,SAAO,CAAE,GAAG,OAAO,IAAI,KAAK,OAAO,IAAI,GAAI;AAC5C;AAQO,IAAM,iBAAiB,CAAE,cAAsC;AACrE,QAAM,QAAQ,UAAU,YAAY,EAAE,KAAK;AAG3C,MAAK,CAAE,MAAM,WAAY,MAAO,KAAK,MAAM,WAAY,OAAQ,GAAI;AAClE,WAAO;AAAA,EACR;AAEA,QAAM,SAAS,QAAS,KAAM;AAG9B,MAAK,CAAE,QAAS;AACf,WAAO;AAAA,EACR;AAGA,SAAO,OAAO,UAAU;AACzB;AAWO,IAAM,sBAAsB,CAClC,OACA,SACA,eACY;AACZ,MAAK,CAAE,SAAS,OAAO,UAAU,UAAW;AAC3C,WAAO;AAAA,EACR;AAGA,MAAK,oBAAoB,KAAM,KAAM,GAAI;AACxC,WAAO;AAAA,EACR;AAEA,QAAM,UAAU,MAAM,KAAK,EAAE,YAAY;AAGzC,MAAK,kBAAkB,KAAM,OAAQ,GAAI;AACxC,UAAM,IAAI,QAAS,CAAE;AACrB,UAAM,IAAI,QAAS,CAAE;AACrB,UAAM,IAAI,QAAS,CAAE;AACrB,WAAO,IAAK,CAAE,GAAI,CAAE,GAAI,CAAE,GAAI,CAAE,GAAI,CAAE,GAAI,CAAE;AAAA,EAC7C;AAGA,MAAK,QAAQ,WAAY,IAAK,KAAK,QAAQ,WAAY,MAAO,GAAI;AACjE,QAAK,YAAa;AACjB,YAAM,WAAW,WAAY,OAAO,OAAQ;AAC5C,UAAK,UAAW;AAEf,eAAO,oBAAqB,UAAU,SAAS,UAAW;AAAA,MAC3D;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAGA,MAAK,QAAQ,WAAY,MAAO,KAAK,QAAQ,WAAY,MAAO,GAAI;AAEnE,QAAK,QAAQ,WAAY,OAAQ,GAAI;AACpC,aAAO;AAAA,IACR;AACA,UAAM,SAAS,QAAS,OAAQ;AAChC,QAAK,QAAS;AACb,aAAO,OAAO,UAAU;AAAA,IACzB;AACA,WAAO;AAAA,EACR;AAGA,SAAO;AACR;AAWO,IAAM,kBAAkB,CAAE,KAAa,UAA2B;AACxE,mBAAkB,GAAI;AAEtB,QAAM,IAAI,SAAU,IAAI,MAAO,GAAG,CAAE,GAAG,EAAG;AAC1C,QAAM,IAAI,SAAU,IAAI,MAAO,GAAG,CAAE,GAAG,EAAG;AAC1C,QAAM,IAAI,SAAU,IAAI,MAAO,GAAG,CAAE,GAAG,EAAG;AAG1C,QAAM,OAAO,KAAK,MAAO,KAAM,MAAM,KAAM,KAAM;AACjD,QAAM,OAAO,KAAK,MAAO,KAAM,MAAM,KAAM,KAAM;AACjD,QAAM,OAAO,KAAK,MAAO,KAAM,MAAM,KAAM,KAAM;AAEjD,SAAO,IAAK,KAAK,SAAU,EAAG,EAAE,SAAU,GAAG,GAAI,CAAE,GAAI,KACrD,SAAU,EAAG,EACb,SAAU,GAAG,GAAI,CAAE,GAAI,KAAK,SAAU,EAAG,EAAE,SAAU,GAAG,GAAI,CAAE;AACjE;;;AC3NA,IAAM,uBAAuB;AActB,IAAM,qBAAqB,CACjC,OACA,YACmB;AACnB,MAAK,CAAE,OAAQ;AACd,WAAO;AAAA,EACR;AAIA,MAAK,MAAM,WAAY,MAAO,KAAK,MAAM,SAAU,GAAI,GAAI;AAC1D,UAAM,SAAS,mBAAoB,KAAM;AAEzC,QAAK,QAAS;AACb,YAAM,WAAW,oBAAqB,OAAO,SAAS,OAAQ;AAE9D,aAAO,YAAY,OAAO;AAAA,IAC3B;AAAA,EACD;AAGA,MAAK,MAAM,WAAY,IAAK,GAAI;AAC/B,WAAO,oBAAqB,OAAO,OAAQ;AAAA,EAC5C;AAGA,SAAO;AACR;AASA,SAAS,mBAAoB,MAAoE;AAEhG,QAAM,QAAQ,KAAK,MAAO,GAAG,EAAG,EAAE,KAAK;AAEvC,MAAK,CAAE,MAAM,WAAY,IAAK,GAAI;AACjC,WAAO;AAAA,EACR;AAGA,QAAM,aAAa,MAAM,QAAS,GAAI;AAEtC,MAAK,eAAe,IAAK;AAExB,UAAMC,WAAU,MAAM,KAAK;AAE3B,QAAK,CAAE,qBAAqB,KAAMA,QAAQ,GAAI;AAC7C,aAAO;AAAA,IACR;AAEA,WAAO,EAAE,SAAAA,UAAS,UAAU,KAAK;AAAA,EAClC;AAGA,QAAM,UAAU,MAAM,MAAO,GAAG,UAAW,EAAE,KAAK;AAGlD,MAAK,CAAE,qBAAqB,KAAM,OAAQ,GAAI;AAC7C,WAAO;AAAA,EACR;AAEA,QAAM,WAAW,MAAM,MAAO,aAAa,CAAE,EAAE,KAAK;AAEpD,SAAO,EAAE,SAAS,UAAU,YAAY,KAAK;AAC9C;AASA,SAAS,oBAAqB,SAAiB,SAA8C;AAC5F,MAAK,OAAO,WAAW,eAAe,OAAO,aAAa,aAAc;AACvE,WAAO;AAAA,EACR;AAEA,MAAI;AACH,UAAM,gBAAgB,WAAW,SAAS;AAC1C,UAAM,gBAAgB,iBAAkB,aAAc,EAAE,iBAAkB,OAAQ,EAAE,KAAK;AAEzF,WAAO,iBAAiB;AAAA,EACzB,QAAQ;AAEP,WAAO;AAAA,EACR;AACD;","names":["formatNumber","varName"]}