@splunk/visualizations 28.9.0 → 28.9.1

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 (46) hide show
  1. package/Area.js +2 -2
  2. package/Bar.js +2 -2
  3. package/Bubble.js +2 -2
  4. package/CHANGELOG.external.md +28 -16
  5. package/ChoroplethSvg.js +2 -2
  6. package/Column.js +2 -2
  7. package/Ellipse.js +2 -2
  8. package/Events.js +2 -2
  9. package/FillerGauge.js +2 -2
  10. package/Image.js +2 -2
  11. package/Line.js +2 -2
  12. package/LinkGraph.js +2 -2
  13. package/Map/PureMap/ChoroplethLayer.d.ts.map +1 -1
  14. package/Map/PureMap/PureMap.d.ts.map +1 -1
  15. package/Map/PureMap/mapWorker.d.ts +2 -0
  16. package/Map/PureMap/mapWorker.d.ts.map +1 -0
  17. package/Map.js +79 -26
  18. package/Map.js.map +3 -3
  19. package/Markdown.js +2 -2
  20. package/MarkerGauge.js +2 -2
  21. package/NetworkGraph.js +2 -2
  22. package/ParallelCoordinates.js +2 -2
  23. package/Pie.js +2 -2
  24. package/ProcessTree.js +2 -2
  25. package/Punchcard.js +2 -2
  26. package/Rectangle.js +2 -2
  27. package/RichText.js +2 -2
  28. package/Sankey.js +2 -2
  29. package/Scatter.js +2 -2
  30. package/SingleValue.js +2 -2
  31. package/SingleValueIcon.js +2 -2
  32. package/SingleValueRadial.js +2 -2
  33. package/Table.js +2 -2
  34. package/Timeline.js +2 -2
  35. package/Treemap.js +2 -2
  36. package/common/DocExampleWithVizSandbox.d.ts +2 -0
  37. package/common/DocExampleWithVizSandbox.d.ts.map +1 -1
  38. package/common/DocExampleWithVizSandbox.js +51 -3
  39. package/common/DocExampleWithVizSandbox.js.map +2 -2
  40. package/common/OverviewDoc.js +51 -3
  41. package/common/OverviewDoc.js.map +2 -2
  42. package/common/utils/mapUtils.js +3 -3
  43. package/common/utils/mapUtils.js.map +2 -2
  44. package/common/withDashboardViz.js +2 -2
  45. package/docs-llm/map/examples-react.md +39 -39
  46. package/package.json +23 -20
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/common/OverviewDoc.tsx", "esm-externals:react", "esm-externals:prop-types", "esm-externals:styled-components", "esm-externals:@splunk/react-ui/Paragraph", "esm-externals:@splunk/react-ui/Heading", "esm-externals:@splunk/react-ui/List", "esm-externals:@splunk/react-ui/Chip", "esm-externals:@splunk/react-ui/Prose", "esm-externals:@splunk/react-icons/enterprise/ChartLine", "esm-externals:@splunk/react-icons/enterprise/ChartBar", "esm-externals:@splunk/react-icons/enterprise/ChartScatter", "esm-externals:@splunk/react-icons/enterprise/ChoroplethMap", "esm-externals:@splunk/react-icons/enterprise/SplitBy", "esm-externals:@splunk/react-docs/DocExample", "esm-externals:@splunk/react-ui/Button", "esm-externals:@splunk/react-ui/Code", "esm-externals:@splunk/react-ui/TransitionOpen", "esm-externals:@splunk/react-icons/SquaresLayered", "esm-externals:@splunk/react-icons/Checkmark", "esm-externals:@splunk/react-icons/EyeSlashed", "esm-externals:@splunk/react-icons/WindowChevronsSlash", "esm-externals:@splunk/ui-utils/i18n", "esm-externals:@splunk/react-docs/UtilPage", "../src/common/docUtils.tsx", "../src/common/DocExampleWithVizSandbox.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport P from '@splunk/react-ui/Paragraph';\nimport Heading from '@splunk/react-ui/Heading';\nimport List from '@splunk/react-ui/List';\nimport Chip from '@splunk/react-ui/Chip';\nimport Prose from '@splunk/react-ui/Prose';\nimport ChartLine from '@splunk/react-icons/enterprise/ChartLine';\nimport ChartBar from '@splunk/react-icons/enterprise/ChartBar';\nimport ChartScatter from '@splunk/react-icons/enterprise/ChartScatter';\nimport ChoroplethMap from '@splunk/react-icons/enterprise/ChoroplethMap';\nimport SplitBy from '@splunk/react-icons/enterprise/SplitBy';\nimport { Overview, Variation } from './interfaces/Overview';\nimport { VizCategory } from './interfaces/VizCategory';\nimport DocExampleWithVizSandbox from './DocExampleWithVizSandbox';\n\ninterface VariationCode {\n code: string;\n example: () => React.ReactElement;\n}\n\ninterface OverviewProps {\n overview: Overview;\n variationCode?: Record<string, VariationCode>;\n}\n\nconst chipIconStyles = {\n color: 'white',\n};\n\nconst chipType = {\n [VizCategory.TRENDS]: {\n backgroundColor: '#66AAF9',\n icon: <ChartLine style={chipIconStyles} />,\n },\n [VizCategory.COMPARISONS]: {\n backgroundColor: '#45D4BA',\n icon: <ChartBar style={chipIconStyles} />,\n },\n [VizCategory.CORRELATION]: {\n backgroundColor: '#FB865C',\n icon: <ChartScatter style={chipIconStyles} />,\n },\n [VizCategory.SPATIAL]: {\n backgroundColor: '#E85B79',\n icon: <ChoroplethMap style={chipIconStyles} />,\n },\n [VizCategory.FLOW]: {\n backgroundColor: '#9980FF',\n icon: <SplitBy style={chipIconStyles} />,\n },\n};\n\nconst StyledChip = styled(Chip)`\n [data-test='label'] {\n color: white;\n }\n margin-left: 10px;\n`;\n\nconst StyledWrapper = styled.div`\n display: flex;\n margin-bottom: 10px;\n align-items: center;\n`;\n\nconst Variations = ({ variations, variationCode, type }): React.ReactElement => (\n <>\n {variations.map((v: Variation): React.ReactElement => {\n const variationObj = variationCode[v.key];\n return (\n <DocExampleWithVizSandbox\n hideSandbox={v.hideSandbox ?? false}\n type={type}\n key={v.key}\n code={variationObj.code}\n example={variationObj.example}\n {...v}\n />\n );\n })}\n </>\n);\n\nVariations.propTypes = {\n variations: T.array,\n variationCode: T.object,\n type: T.string,\n};\n\nconst Tip = ({ tip }): React.ReactElement => <List.Item>{tip}</List.Item>;\n\nTip.propTypes = {\n tip: T.string,\n};\n\nconst Tips = ({ tips }): React.ReactElement => (\n <>\n <Heading level={3}>Tips</Heading>\n <List>\n {tips.map(\n (tip: string): React.ReactElement => (\n <Tip key={tip} tip={tip} />\n )\n )}\n </List>\n </>\n);\n\nTips.propTypes = {\n tips: T.array,\n};\n\nconst OverviewDoc = (props: OverviewProps): React.ReactElement => {\n const { typeOfViz, type, overview, note, tips, variations } = props.overview;\n const { variationCode } = props;\n const vizTypeDisplayNameMap = {\n [VizCategory.TRENDS]: 'Trend',\n [VizCategory.COMPARISONS]: 'Comparison',\n };\n const vizType = vizTypeDisplayNameMap[typeOfViz] || typeOfViz;\n return (\n <>\n {vizType && (\n <StyledWrapper>\n Chart Type\n <StyledChip\n data-test=\"viz-type-chip\"\n backgroundColor={chipType[typeOfViz].backgroundColor}\n icon={chipType[typeOfViz].icon}\n >\n {vizType}\n </StyledChip>\n </StyledWrapper>\n )}\n <Prose>\n <P data-test=\"overview-description\">{overview}</P>\n {note && <P data-test=\"overview-note\">{note}</P>}\n <Tips data-test=\"tips\" tips={tips} />\n </Prose>\n {variationCode && (\n <Variations variations={variations} type={type} variationCode={variationCode} />\n )}\n </>\n );\n};\n\nOverviewDoc.propTypes = {\n overview: T.object,\n variationCode: T.object,\n};\n\nexport default OverviewDoc;\n", "\nimport * as defaultImport from \"react\";\nexport * from \"react\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"prop-types\";\nexport * from \"prop-types\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"styled-components\";\nexport * from \"styled-components\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Paragraph\";\nexport * from \"@splunk/react-ui/Paragraph\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Heading\";\nexport * from \"@splunk/react-ui/Heading\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/List\";\nexport * from \"@splunk/react-ui/List\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Chip\";\nexport * from \"@splunk/react-ui/Chip\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Prose\";\nexport * from \"@splunk/react-ui/Prose\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChartLine\";\nexport * from \"@splunk/react-icons/enterprise/ChartLine\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChartBar\";\nexport * from \"@splunk/react-icons/enterprise/ChartBar\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChartScatter\";\nexport * from \"@splunk/react-icons/enterprise/ChartScatter\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChoroplethMap\";\nexport * from \"@splunk/react-icons/enterprise/ChoroplethMap\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/SplitBy\";\nexport * from \"@splunk/react-icons/enterprise/SplitBy\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-docs/DocExample\";\nexport * from \"@splunk/react-docs/DocExample\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Button\";\nexport * from \"@splunk/react-ui/Button\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Code\";\nexport * from \"@splunk/react-ui/Code\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/TransitionOpen\";\nexport * from \"@splunk/react-ui/TransitionOpen\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/SquaresLayered\";\nexport * from \"@splunk/react-icons/SquaresLayered\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/Checkmark\";\nexport * from \"@splunk/react-icons/Checkmark\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/EyeSlashed\";\nexport * from \"@splunk/react-icons/EyeSlashed\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/WindowChevronsSlash\";\nexport * from \"@splunk/react-icons/WindowChevronsSlash\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/i18n\";\nexport * from \"@splunk/ui-utils/i18n\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-docs/UtilPage\";\nexport * from \"@splunk/react-docs/UtilPage\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "import * as React from 'react';\nimport UtilPage from '@splunk/react-docs/UtilPage';\n\n// https://github.com/jsdoc2md/jsdoc-api#synopsis\ninterface JsDoc {\n access?: string;\n classdesc?: string;\n comment: string;\n kind: string;\n longname: string;\n meta: Record<string, unknown>;\n member: string;\n name: string;\n scope: string;\n}\n\nconst sharedSelectors = new Set([\n 'average',\n 'count',\n 'getField',\n 'getType',\n 'min',\n 'max',\n 'percentile',\n 'sum',\n]);\n\nconst formatSidebarItemName = (name: string, className: string): string => {\n return sharedSelectors.has(name) ? `${className}#${name}` : name;\n};\n\nconst removePrependedClassName = (longname = ''): string => longname.slice(longname.indexOf('#') + 1);\n\nconst formatDSLSelectorDocs = (docs: JsDoc[]): JsDoc[] =>\n docs.map(doc => ({\n ...doc,\n longname: removePrependedClassName(doc.longname),\n }));\n\nexport const getFormatterClassdesc = (\n formatterDocs: JsDoc[],\n name: string\n): { name: string; markdown: string } => ({\n name,\n markdown: `# ${name}\\n ${formatterDocs.find(doc => doc.name === name && doc.kind === 'class').classdesc}`,\n});\n\nexport const extractDocItems = (\n docs: JsDoc[],\n className: string\n): { name: string; component: (...args: any[]) => any }[] => {\n const classHeaderDoc = docs[0];\n const fileDoc = docs.at(-1);\n const filteredDocs = formatDSLSelectorDocs(docs).filter(\n ({ access, comment }) => access === 'public' && comment\n );\n\n return filteredDocs\n .map(doc => ({\n name: formatSidebarItemName(doc.name, className),\n component: function UtilDoc() {\n // named function so linter doesnt raise react/display-name error\n return <UtilPage title={`${className}#${doc.name}`} docs={[classHeaderDoc, doc, fileDoc]} />;\n },\n }))\n .sort((a, b) => a.name.localeCompare(b.name));\n};\n\nexport const formatCodeStringToObject = (codeString: string, regexMatch: RegExp): any => {\n const match = regexMatch.exec(codeString);\n if (!match) return null;\n\n const stringToParse = `{${match[1]}}`;\n\n // remove trailing commas\n const removedCommas = stringToParse.replace(/,(?!\\s*?[-{[\"'\\w])/g, '');\n\n // convert double quotes (which only occur inside strings) to back quotes\n const backQuotes = removedCommas.replaceAll('\"', '`');\n // replace single quotes with double quotes\n const doubleQuotes = backQuotes.replaceAll(\"'\", '\"');\n // replace back quotes with single quotes\n const singleQuotes = doubleQuotes.replaceAll('`', \"'\");\n\n // add quotes around keys\n const quotesAroundKeys = singleQuotes.replace(/\\b(\\w+)\\s*:(?=\\s)/g, '\"$1\":');\n\n let retval = null;\n try {\n retval = JSON.parse(quotesAroundKeys);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(e);\n }\n return retval;\n};\n\nexport const extractDataFromReactCode = (codeString: string): any => {\n const primaryRegex = /dataSources={{([\\s\\S]*?primary:[\\s\\S]*?)}}/;\n const { primary } = formatCodeStringToObject(codeString, primaryRegex) ?? {};\n\n const optionsRegex = /options={{([\\s\\S]*?)}}/;\n const options = formatCodeStringToObject(codeString, optionsRegex);\n\n const contextRegex = /context={{([\\s\\S]*?)}}/;\n const context = formatCodeStringToObject(codeString, contextRegex);\n\n return { primary, options, context };\n};\n\n// Takes a stringified react viz example and a viz type\n// Returns a dashboard definition object.\n// e.g. codeString: '<Area dataSources={{}} options={{}} />'\n// type: 'splunk.area'\nexport const convertToDashboardJSON = (codeString: string, type: string): any => {\n const { options, primary, context } = extractDataFromReactCode(codeString);\n\n return {\n visualizations: {\n test_viz: {\n type,\n ...(options ? { options } : {}),\n ...(primary ? { dataSources: { primary: 'primary' } } : {}),\n ...(context ? { context } : {}),\n },\n },\n ...(primary\n ? {\n dataSources: {\n primary: { type: 'ds.test', options: primary },\n },\n }\n : {}),\n defaults: {\n dataSources: {\n global: {\n options: {\n queryParameters: {\n latest: '$global_time.latest$',\n earliest: '$global_time.earliest$',\n },\n },\n },\n },\n },\n inputs: {\n input_global_trp: {\n type: 'input.timerange',\n options: {\n token: 'global_time',\n defaultValue: '-24h@h,now',\n },\n title: 'Global Time Range',\n },\n },\n layout: {\n type: 'absolute',\n options: {},\n structure: [\n {\n item: 'test_viz',\n type: 'block',\n position: {\n x: 0,\n y: 0,\n w: 800,\n h: 500,\n },\n },\n ],\n globalInputs: ['input_global_trp'],\n },\n };\n};\n", "import * as React from 'react';\nimport DocExample from '@splunk/react-docs/DocExample';\nimport Button from '@splunk/react-ui/Button';\nimport Code from '@splunk/react-ui/Code';\nimport TransitionOpen from '@splunk/react-ui/TransitionOpen';\nimport SquaresLayered from '@splunk/react-icons/SquaresLayered';\nimport Checkmark from '@splunk/react-icons/Checkmark';\nimport EyeSlashed from '@splunk/react-icons/EyeSlashed';\nimport WindowChevronsSlash from '@splunk/react-icons/WindowChevronsSlash';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport * as T from 'prop-types';\nimport { convertToDashboardJSON } from './docUtils';\n\ninterface DocExampleWithVizSandboxProps {\n type: string;\n title: string;\n code: string;\n example: () => React.ReactElement;\n hideSandbox?: boolean;\n description?: string;\n}\n\nconst DocExampleWithVizSandbox = (props: DocExampleWithVizSandboxProps): React.ReactElement => {\n const { type, title, code, example, hideSandbox = false, description } = props;\n const [isCopied, setIsCopied] = React.useState(false);\n const [showCode, setShowCode] = React.useState(false);\n const isMounted = React.useRef(true);\n\n const toggleShowCode = React.useCallback(() => {\n setShowCode(state => !state);\n }, []);\n\n React.useEffect((): (() => void) => {\n return () => {\n isMounted.current = false;\n setIsCopied(false);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n if (hideSandbox) return <DocExample title={title} code={code} example={example} />;\n\n const objDefn = convertToDashboardJSON(code, type);\n // set spacing level to 4\n const prettyJson = JSON.stringify(objDefn, null, 4);\n\n const copyToClipBoard = () => {\n if ('clipboard' in navigator) {\n navigator.clipboard.writeText(prettyJson);\n setIsCopied(true);\n }\n setTimeout(() => {\n if (isMounted.current) {\n setIsCopied(false);\n }\n }, 5000);\n };\n\n const renderAdditionalActions = () => [\n <Button\n key=\"show-dashboard-definition\"\n appearance=\"secondary\"\n onClick={toggleShowCode}\n icon={showCode ? <EyeSlashed /> : <WindowChevronsSlash />}\n label={showCode ? _('Hide dashboard definition') : _('Show dashboard definition')}\n />,\n ];\n\n return (\n <DocExample\n renderAdditionalActions={renderAdditionalActions}\n title={title}\n code={code}\n example={example}\n description={description}\n >\n <TransitionOpen\n animation=\"slideFromTop\"\n open={showCode}\n retainFocus={false}\n takeFocus={false}\n renderChildrenWhenCollapsed={false}\n animateOnMount={false}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n <Code value={prettyJson} language=\"json\" />\n <Button\n onClick={copyToClipBoard}\n icon={isCopied ? <Checkmark /> : <SquaresLayered />}\n label={isCopied ? _('Copied') : _('Copy to clipboard')}\n style={{ height: '30px', maxWidth: '164px' }}\n />\n </div>\n </TransitionOpen>\n </DocExample>\n );\n};\n\nDocExampleWithVizSandbox.propTypes = {\n type: T.string,\n title: T.string,\n code: T.string,\n example: T.func,\n hideSandbox: T.bool,\n};\n\nexport default DocExampleWithVizSandbox;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import * as React from 'react';\nimport * as T from 'prop-types';\nimport styled from 'styled-components';\nimport P from '@splunk/react-ui/Paragraph';\nimport Heading from '@splunk/react-ui/Heading';\nimport List from '@splunk/react-ui/List';\nimport Chip from '@splunk/react-ui/Chip';\nimport Prose from '@splunk/react-ui/Prose';\nimport ChartLine from '@splunk/react-icons/enterprise/ChartLine';\nimport ChartBar from '@splunk/react-icons/enterprise/ChartBar';\nimport ChartScatter from '@splunk/react-icons/enterprise/ChartScatter';\nimport ChoroplethMap from '@splunk/react-icons/enterprise/ChoroplethMap';\nimport SplitBy from '@splunk/react-icons/enterprise/SplitBy';\nimport { Overview, Variation } from './interfaces/Overview';\nimport { VizCategory } from './interfaces/VizCategory';\nimport DocExampleWithVizSandbox from './DocExampleWithVizSandbox';\n\ninterface VariationCode {\n code: string;\n example: () => React.ReactElement;\n}\n\ninterface OverviewProps {\n overview: Overview;\n variationCode?: Record<string, VariationCode>;\n}\n\nconst chipIconStyles = {\n color: 'white',\n};\n\nconst chipType = {\n [VizCategory.TRENDS]: {\n backgroundColor: '#66AAF9',\n icon: <ChartLine style={chipIconStyles} />,\n },\n [VizCategory.COMPARISONS]: {\n backgroundColor: '#45D4BA',\n icon: <ChartBar style={chipIconStyles} />,\n },\n [VizCategory.CORRELATION]: {\n backgroundColor: '#FB865C',\n icon: <ChartScatter style={chipIconStyles} />,\n },\n [VizCategory.SPATIAL]: {\n backgroundColor: '#E85B79',\n icon: <ChoroplethMap style={chipIconStyles} />,\n },\n [VizCategory.FLOW]: {\n backgroundColor: '#9980FF',\n icon: <SplitBy style={chipIconStyles} />,\n },\n};\n\nconst StyledChip = styled(Chip)`\n [data-test='label'] {\n color: white;\n }\n margin-left: 10px;\n`;\n\nconst StyledWrapper = styled.div`\n display: flex;\n margin-bottom: 10px;\n align-items: center;\n`;\n\nconst Variations = ({ variations, variationCode, type }): React.ReactElement => (\n <>\n {variations.map((v: Variation): React.ReactElement => {\n const variationObj = variationCode[v.key];\n return (\n <DocExampleWithVizSandbox\n hideSandbox={v.hideSandbox ?? false}\n type={type}\n key={v.key}\n code={variationObj.code}\n example={variationObj.example}\n {...v}\n />\n );\n })}\n </>\n);\n\nVariations.propTypes = {\n variations: T.array,\n variationCode: T.object,\n type: T.string,\n};\n\nconst Tip = ({ tip }): React.ReactElement => <List.Item>{tip}</List.Item>;\n\nTip.propTypes = {\n tip: T.string,\n};\n\nconst Tips = ({ tips }): React.ReactElement => (\n <>\n <Heading level={3}>Tips</Heading>\n <List>\n {tips.map(\n (tip: string): React.ReactElement => (\n <Tip key={tip} tip={tip} />\n )\n )}\n </List>\n </>\n);\n\nTips.propTypes = {\n tips: T.array,\n};\n\nconst OverviewDoc = (props: OverviewProps): React.ReactElement => {\n const { typeOfViz, type, overview, note, tips, variations } = props.overview;\n const { variationCode } = props;\n const vizTypeDisplayNameMap = {\n [VizCategory.TRENDS]: 'Trend',\n [VizCategory.COMPARISONS]: 'Comparison',\n };\n const vizType = vizTypeDisplayNameMap[typeOfViz] || typeOfViz;\n return (\n <>\n {vizType && (\n <StyledWrapper>\n Chart Type\n <StyledChip\n data-test=\"viz-type-chip\"\n backgroundColor={chipType[typeOfViz].backgroundColor}\n icon={chipType[typeOfViz].icon}\n >\n {vizType}\n </StyledChip>\n </StyledWrapper>\n )}\n <Prose>\n <P data-test=\"overview-description\">{overview}</P>\n {note && <P data-test=\"overview-note\">{note}</P>}\n <Tips data-test=\"tips\" tips={tips} />\n </Prose>\n {variationCode && (\n <Variations variations={variations} type={type} variationCode={variationCode} />\n )}\n </>\n );\n};\n\nOverviewDoc.propTypes = {\n overview: T.object,\n variationCode: T.object,\n};\n\nexport default OverviewDoc;\n", "\nimport * as defaultImport from \"react\";\nexport * from \"react\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"prop-types\";\nexport * from \"prop-types\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"styled-components\";\nexport * from \"styled-components\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Paragraph\";\nexport * from \"@splunk/react-ui/Paragraph\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Heading\";\nexport * from \"@splunk/react-ui/Heading\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/List\";\nexport * from \"@splunk/react-ui/List\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Chip\";\nexport * from \"@splunk/react-ui/Chip\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Prose\";\nexport * from \"@splunk/react-ui/Prose\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChartLine\";\nexport * from \"@splunk/react-icons/enterprise/ChartLine\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChartBar\";\nexport * from \"@splunk/react-icons/enterprise/ChartBar\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChartScatter\";\nexport * from \"@splunk/react-icons/enterprise/ChartScatter\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/ChoroplethMap\";\nexport * from \"@splunk/react-icons/enterprise/ChoroplethMap\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/enterprise/SplitBy\";\nexport * from \"@splunk/react-icons/enterprise/SplitBy\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-docs/DocExample\";\nexport * from \"@splunk/react-docs/DocExample\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Button\";\nexport * from \"@splunk/react-ui/Button\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/Code\";\nexport * from \"@splunk/react-ui/Code\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-ui/TransitionOpen\";\nexport * from \"@splunk/react-ui/TransitionOpen\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/SquaresLayered\";\nexport * from \"@splunk/react-icons/SquaresLayered\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/Checkmark\";\nexport * from \"@splunk/react-icons/Checkmark\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/EyeSlashed\";\nexport * from \"@splunk/react-icons/EyeSlashed\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-icons/WindowChevronsSlash\";\nexport * from \"@splunk/react-icons/WindowChevronsSlash\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/i18n\";\nexport * from \"@splunk/ui-utils/i18n\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/react-docs/UtilPage\";\nexport * from \"@splunk/react-docs/UtilPage\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "import * as React from 'react';\nimport UtilPage from '@splunk/react-docs/UtilPage';\n\n// https://github.com/jsdoc2md/jsdoc-api#synopsis\ninterface JsDoc {\n access?: string;\n classdesc?: string;\n comment: string;\n kind: string;\n longname: string;\n meta: Record<string, unknown>;\n member: string;\n name: string;\n scope: string;\n}\n\nconst sharedSelectors = new Set([\n 'average',\n 'count',\n 'getField',\n 'getType',\n 'min',\n 'max',\n 'percentile',\n 'sum',\n]);\n\nconst formatSidebarItemName = (name: string, className: string): string => {\n return sharedSelectors.has(name) ? `${className}#${name}` : name;\n};\n\nconst removePrependedClassName = (longname = ''): string => longname.slice(longname.indexOf('#') + 1);\n\nconst formatDSLSelectorDocs = (docs: JsDoc[]): JsDoc[] =>\n docs.map(doc => ({\n ...doc,\n longname: removePrependedClassName(doc.longname),\n }));\n\nexport const getFormatterClassdesc = (\n formatterDocs: JsDoc[],\n name: string\n): { name: string; markdown: string } => ({\n name,\n markdown: `# ${name}\\n ${formatterDocs.find(doc => doc.name === name && doc.kind === 'class').classdesc}`,\n});\n\nexport const extractDocItems = (\n docs: JsDoc[],\n className: string\n): { name: string; component: (...args: any[]) => any }[] => {\n const classHeaderDoc = docs[0];\n const fileDoc = docs.at(-1);\n const filteredDocs = formatDSLSelectorDocs(docs).filter(\n ({ access, comment }) => access === 'public' && comment\n );\n\n return filteredDocs\n .map(doc => ({\n name: formatSidebarItemName(doc.name, className),\n component: function UtilDoc() {\n // named function so linter doesnt raise react/display-name error\n return <UtilPage title={`${className}#${doc.name}`} docs={[classHeaderDoc, doc, fileDoc]} />;\n },\n }))\n .sort((a, b) => a.name.localeCompare(b.name));\n};\n\nexport const formatCodeStringToObject = (codeString: string, regexMatch: RegExp): any => {\n const match = regexMatch.exec(codeString);\n if (!match) return null;\n\n const stringToParse = `{${match[1]}}`;\n\n // remove trailing commas\n const removedCommas = stringToParse.replace(/,(?!\\s*?[-{[\"'\\w])/g, '');\n\n // convert double quotes (which only occur inside strings) to back quotes\n const backQuotes = removedCommas.replaceAll('\"', '`');\n // replace single quotes with double quotes\n const doubleQuotes = backQuotes.replaceAll(\"'\", '\"');\n // replace back quotes with single quotes\n const singleQuotes = doubleQuotes.replaceAll('`', \"'\");\n\n // add quotes around keys\n const quotesAroundKeys = singleQuotes.replace(/\\b(\\w+)\\s*:(?=\\s)/g, '\"$1\":');\n\n let retval = null;\n try {\n retval = JSON.parse(quotesAroundKeys);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(e);\n }\n return retval;\n};\n\nexport const extractDataFromReactCode = (codeString: string): any => {\n const primaryRegex = /dataSources={{([\\s\\S]*?primary:[\\s\\S]*?)}}/;\n const { primary } = formatCodeStringToObject(codeString, primaryRegex) ?? {};\n\n const optionsRegex = /options={{([\\s\\S]*?)}}/;\n const options = formatCodeStringToObject(codeString, optionsRegex);\n\n const contextRegex = /context={{([\\s\\S]*?)}}/;\n const context = formatCodeStringToObject(codeString, contextRegex);\n\n return { primary, options, context };\n};\n\n// Takes a stringified react viz example and a viz type\n// Returns a dashboard definition object.\n// e.g. codeString: '<Area dataSources={{}} options={{}} />'\n// type: 'splunk.area'\nexport const convertToDashboardJSON = (codeString: string, type: string): any => {\n const { options, primary, context } = extractDataFromReactCode(codeString);\n\n return {\n visualizations: {\n test_viz: {\n type,\n ...(options ? { options } : {}),\n ...(primary ? { dataSources: { primary: 'primary' } } : {}),\n ...(context ? { context } : {}),\n },\n },\n ...(primary\n ? {\n dataSources: {\n primary: { type: 'ds.test', options: primary },\n },\n }\n : {}),\n defaults: {\n dataSources: {\n global: {\n options: {\n queryParameters: {\n latest: '$global_time.latest$',\n earliest: '$global_time.earliest$',\n },\n },\n },\n },\n },\n inputs: {\n input_global_trp: {\n type: 'input.timerange',\n options: {\n token: 'global_time',\n defaultValue: '-24h@h,now',\n },\n title: 'Global Time Range',\n },\n },\n layout: {\n type: 'absolute',\n options: {},\n structure: [\n {\n item: 'test_viz',\n type: 'block',\n position: {\n x: 0,\n y: 0,\n w: 800,\n h: 500,\n },\n },\n ],\n globalInputs: ['input_global_trp'],\n },\n };\n};\n", "import * as React from 'react';\nimport DocExample from '@splunk/react-docs/DocExample';\nimport Button from '@splunk/react-ui/Button';\nimport Code from '@splunk/react-ui/Code';\nimport TransitionOpen from '@splunk/react-ui/TransitionOpen';\nimport SquaresLayered from '@splunk/react-icons/SquaresLayered';\nimport Checkmark from '@splunk/react-icons/Checkmark';\nimport EyeSlashed from '@splunk/react-icons/EyeSlashed';\nimport WindowChevronsSlash from '@splunk/react-icons/WindowChevronsSlash';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport * as T from 'prop-types';\nimport { convertToDashboardJSON } from './docUtils';\n\ninterface DocExampleWithVizSandboxProps {\n type: string;\n title: string;\n code: string;\n example: () => React.ReactElement;\n hideSandbox?: boolean;\n description?: string;\n showMapAttribution?: boolean;\n}\n\nconst MAP_DOCS_EXAMPLE_WRAPPER_STYLE: React.CSSProperties = {\n position: 'relative',\n display: 'inline-block',\n width: 'fit-content',\n maxWidth: '100%',\n verticalAlign: 'top',\n};\n\nconst MAP_DOCS_ATTRIBUTION_STYLE: React.CSSProperties = {\n position: 'absolute',\n right: '16px',\n bottom: '16px',\n zIndex: 4,\n padding: '4px 8px',\n borderRadius: '4px',\n background: 'rgba(255, 255, 255, 0.92)',\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.2)',\n fontSize: '11px',\n lineHeight: '14px',\n pointerEvents: 'auto',\n};\n\nconst MAP_DOCS_ATTRIBUTION_LINK_STYLE: React.CSSProperties = {\n color: '#136CBE',\n textDecoration: 'none',\n};\n\nconst shouldRenderMapDocsAttribution = (type: string, code: string): boolean =>\n type === 'splunk.map' &&\n (code.includes('basemaps.cartocdn.com') ||\n code.includes('MapDocsExample') ||\n code.includes('docsTileConfig') ||\n code.includes('testTileConfig')) &&\n !code.includes('showBaseLayer: false');\n\nconst MapDocsAttribution = (): React.ReactElement => (\n <div data-test=\"map-docs-attribution\" style={MAP_DOCS_ATTRIBUTION_STYLE}>\n <a\n href=\"https://www.openstreetmap.org/copyright\"\n rel=\"noopener noreferrer\"\n style={MAP_DOCS_ATTRIBUTION_LINK_STYLE}\n target=\"_blank\"\n >\n \u00A9 OpenStreetMap contributors\n </a>{' '}\n <a\n href=\"https://carto.com/attributions/\"\n rel=\"noopener noreferrer\"\n style={MAP_DOCS_ATTRIBUTION_LINK_STYLE}\n target=\"_blank\"\n >\n \u00A9 CARTO\n </a>\n </div>\n);\n\nconst DocExampleWithVizSandbox = (props: DocExampleWithVizSandboxProps): React.ReactElement => {\n const { type, title, code, example, hideSandbox = false, description, showMapAttribution } = props;\n const [isCopied, setIsCopied] = React.useState(false);\n const [showCode, setShowCode] = React.useState(false);\n const isMounted = React.useRef(true);\n const ExampleComponent = example;\n const showMapDocsAttribution =\n !code.includes('showBaseLayer: false') &&\n (showMapAttribution ?? shouldRenderMapDocsAttribution(type, code));\n\n const toggleShowCode = React.useCallback(() => {\n setShowCode(state => !state);\n }, []);\n\n React.useEffect((): (() => void) => {\n return () => {\n isMounted.current = false;\n setIsCopied(false);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n if (hideSandbox) return <DocExample title={title} code={code} example={example} />;\n\n const objDefn = convertToDashboardJSON(code, type);\n // set spacing level to 4\n const prettyJson = JSON.stringify(objDefn, null, 4);\n\n const copyToClipBoard = () => {\n if ('clipboard' in navigator) {\n navigator.clipboard.writeText(prettyJson);\n setIsCopied(true);\n }\n setTimeout(() => {\n if (isMounted.current) {\n setIsCopied(false);\n }\n }, 5000);\n };\n\n const renderAdditionalActions = () => [\n <Button\n key=\"show-dashboard-definition\"\n appearance=\"secondary\"\n onClick={toggleShowCode}\n icon={showCode ? <EyeSlashed /> : <WindowChevronsSlash />}\n label={showCode ? _('Hide dashboard definition') : _('Show dashboard definition')}\n />,\n ];\n\n const renderExample = () => (\n <div style={MAP_DOCS_EXAMPLE_WRAPPER_STYLE}>\n <ExampleComponent />\n {showMapDocsAttribution && <MapDocsAttribution />}\n </div>\n );\n\n return (\n <DocExample\n renderAdditionalActions={renderAdditionalActions}\n title={title}\n code={code}\n example={showMapDocsAttribution ? renderExample : example}\n description={description}\n >\n <TransitionOpen\n animation=\"slideFromTop\"\n open={showCode}\n retainFocus={false}\n takeFocus={false}\n renderChildrenWhenCollapsed={false}\n animateOnMount={false}\n >\n <div style={{ display: 'flex', justifyContent: 'space-between' }}>\n <Code value={prettyJson} language=\"json\" />\n <Button\n onClick={copyToClipBoard}\n icon={isCopied ? <Checkmark /> : <SquaresLayered />}\n label={isCopied ? _('Copied') : _('Copy to clipboard')}\n style={{ height: '30px', maxWidth: '164px' }}\n />\n </div>\n </TransitionOpen>\n </DocExample>\n );\n};\n\nDocExampleWithVizSandbox.propTypes = {\n type: T.string,\n title: T.string,\n code: T.string,\n example: T.func,\n hideSandbox: T.bool,\n showMapAttribution: T.bool,\n};\n\nexport default DocExampleWithVizSandbox;\n"],
5
+ "mappings": "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",
6
6
  "names": ["defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport"]
7
7
  }
@@ -396,13 +396,13 @@ var matchBubbleSize = (dataRange, data) => {
396
396
  return size;
397
397
  };
398
398
 
399
- // esm-externals:maplibre-gl
399
+ // esm-externals:maplibre-gl/dist/maplibre-gl.mjs
400
400
  var maplibre_gl_exports = {};
401
401
  __export(maplibre_gl_exports, {
402
402
  default: () => maplibre_gl_default
403
403
  });
404
- var defaultImport21 = __toESM(require("maplibre-gl"));
405
- __reExport(maplibre_gl_exports, require("maplibre-gl"));
404
+ var defaultImport21 = __toESM(require("maplibre-gl/dist/maplibre-gl.mjs"), 1);
405
+ __reExport(maplibre_gl_exports, require("maplibre-gl/dist/maplibre-gl.mjs"));
406
406
  var maplibre_gl_default = "default" in defaultImport21 ? defaultImport21.default : defaultImport21;
407
407
 
408
408
  // src/Map/PureMap/MapContext.tsx
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/common/utils/mapUtils.ts", "esm-externals:@splunk/visualization-encoding/utils/types", "esm-externals:@splunk/visualization-encoding/utils/dsl", "esm-externals:@splunk/visualizations-shared/hocUtils", "esm-externals:@splunk/visualizations-shared/JSONSchemaUtils", "esm-externals:react", "esm-externals:styled-components", "esm-externals:lodash", "esm-externals:@splunk/visualizations-shared/iconUtils", "esm-externals:@splunk/visualizations-shared/colorUtils", "esm-externals:@splunk/visualizations-shared/RemoteIcon", "esm-externals:@splunk/visualization-context/FeatureFlagContext", "esm-externals:@splunk/ui-utils/i18n", "esm-externals:@splunk/ui-utils/format", "../../src/Map/PureMap/keyboardConstants.ts", "esm-externals:@splunk/react-ui/Popover", "esm-externals:@splunk/themes", "esm-externals:@splunk/ui-utils/id", "../../src/common/utils/shadowDomUtils.ts", "../../src/Map/PureMap/Tooltip.tsx", "esm-externals:d3-scale", "esm-externals:chroma-js", "esm-externals:@splunk/visualization-color-palettes", "esm-externals:@splunk/visualization-schemas", "../../src/Map/PureMap/MapUtils.ts", "esm-externals:maplibre-gl", "../../src/Map/PureMap/MapContext.tsx", "../../src/Map/PureMap/MarkerWrapper.tsx", "../../src/Map/PureMap/BubbleLayer.tsx"],
4
- "sourcesContent": ["import { isNumber } from '@splunk/visualization-encoding/utils/types';\nimport { getFieldsFromDSL } from '@splunk/visualization-encoding/utils/dsl';\nimport { deepMergeWithArrayPrimitiveOverrides } from '@splunk/visualizations-shared/hocUtils';\nimport { pickFieldFromJSONSchema } from '@splunk/visualizations-shared/JSONSchemaUtils';\nimport { GEO_LAT_AND_LONG_FIELD } from '../../Map/PureMap/BubbleLayer';\n\nexport const columnsNullToZeros = (config, dataSources, options) => {\n const { primary } = dataSources;\n const { columns, fields } = primary.data;\n let newColumns = columns;\n const mergedOptions = deepMergeWithArrayPrimitiveOverrides(\n {},\n options,\n pickFieldFromJSONSchema(config.optionsSchema, 'default')\n );\n if (mergedOptions.layers?.[0]?.type === 'bubble') {\n const latitudeField = getFieldsFromDSL(mergedOptions.layers[0].latitude, dataSources)[0] || '';\n const longitudeField = getFieldsFromDSL(mergedOptions.layers[0].longitude, dataSources)[0] || '';\n const stringsFields = getFieldsFromDSL(\"> primary | frameBySeriesTypes('string')\", dataSources);\n const excludedFields = new Set([\n latitudeField,\n longitudeField,\n 'geobin',\n 'name',\n ...stringsFields,\n ...GEO_LAT_AND_LONG_FIELD,\n ]);\n const indicesToEvaluate = new Set(\n fields.reduce((arr, e, i) => {\n const field = typeof e === 'string' ? e : e.name.toString();\n if (!excludedFields.has(field)) {\n arr.push(i);\n }\n return arr;\n }, [])\n );\n\n newColumns = columns.map((column, i) => {\n if (indicesToEvaluate.has(i)) {\n // sanitize value and convert string to numeric numbers\n return column.map(value => (!value || !isNumber(value) ? 0 : +value));\n }\n return column;\n });\n }\n\n const modifiedDatasources = {\n ...dataSources,\n primary: {\n ...primary,\n data: {\n ...primary.data,\n columns: newColumns,\n },\n },\n };\n\n return modifiedDatasources;\n};\n", "\nimport * as defaultImport from \"@splunk/visualization-encoding/utils/types\";\nexport * from \"@splunk/visualization-encoding/utils/types\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-encoding/utils/dsl\";\nexport * from \"@splunk/visualization-encoding/utils/dsl\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/hocUtils\";\nexport * from \"@splunk/visualizations-shared/hocUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/JSONSchemaUtils\";\nexport * from \"@splunk/visualizations-shared/JSONSchemaUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"react\";\nexport * from \"react\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"styled-components\";\nexport * from \"styled-components\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"lodash\";\nexport * from \"lodash\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/iconUtils\";\nexport * from \"@splunk/visualizations-shared/iconUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/colorUtils\";\nexport * from \"@splunk/visualizations-shared/colorUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/RemoteIcon\";\nexport * from \"@splunk/visualizations-shared/RemoteIcon\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-context/FeatureFlagContext\";\nexport * from \"@splunk/visualization-context/FeatureFlagContext\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/i18n\";\nexport * from \"@splunk/ui-utils/i18n\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/format\";\nexport * from \"@splunk/ui-utils/format\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "export const KEYBOARD_KEYS = {\n ARROW_RIGHT: 'ArrowRight',\n ARROW_LEFT: 'ArrowLeft',\n ARROW_UP: 'ArrowUp',\n ARROW_DOWN: 'ArrowDown',\n HOME: 'Home',\n END: 'End',\n ENTER: 'Enter',\n SPACE: ' ',\n} as const;\n", "\nimport * as defaultImport from \"@splunk/react-ui/Popover\";\nexport * from \"@splunk/react-ui/Popover\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/themes\";\nexport * from \"@splunk/themes\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/id\";\nexport * from \"@splunk/ui-utils/id\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "export const getFloatingLayerStyleTarget = (anchor?: HTMLElement | null): HTMLElement | undefined => {\n if (!anchor || typeof anchor.getRootNode !== 'function') {\n return undefined;\n }\n\n const rootNode = anchor.getRootNode();\n\n if (typeof ShadowRoot !== 'undefined' && rootNode instanceof ShadowRoot) {\n return anchor.ownerDocument.head;\n }\n\n return undefined;\n};\n", "import * as React from 'react';\nimport styled, { StyleSheetManager } from 'styled-components';\nimport Popover from '@splunk/react-ui/Popover';\nimport { isRemoteIcon, isDataURI } from '@splunk/visualizations-shared/iconUtils';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport FeatureFlagContext from '@splunk/visualization-context/FeatureFlagContext';\nimport RemoteIcon from '@splunk/visualizations-shared/RemoteIcon';\nimport { variables } from '@splunk/themes';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport { getFloatingLayerStyleTarget } from '../../common/utils/shadowDomUtils';\n\ntype FeatureFlagContextValue = Record<string, boolean | undefined> | null;\n\nconst StyledPopover = styled(Popover)`\n min-width: 250px;\n max-width: 332px;\n max-width: fit-content;\n font-size: 12px;\n`;\n\nconst StyledTable = styled.table`\n margin: 2px 6px 2px 6px;\n width: calc(100% - 12px);\n`;\n\nconst StyledTitleColumn = styled.td`\n opacity: 0.85;\n word-break: break-all;\n vertical-align: top;\n`;\n\nconst StyledValueColumn = styled.td`\n text-align: right;\n word-break: break-all;\n vertical-align: top;\n`;\n\nconst StyledColorBlock = styled.div`\n background-color: ${props => props.color};\n display: inline-block;\n margin-right: 4px;\n border-radius: 2px;\n width: 6px;\n height: 11px;\n transform: translateY(1px);\n`;\n\nconst StyledIconWrapper = styled.span`\n margin-left: 4px;\n display: inline-block;\n vertical-align: middle;\n`;\n\nconst StyledTooltipHeader = styled.thead`\n th {\n height: 16px;\n color: ${variables.contentColorActive};\n padding: 0;\n }\n\n span {\n display: block;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n width: 100%;\n }\n`;\n\nexport const convertDegToDMS = (decimalDegree: number, type: 'latitude' | 'longitude'): string => {\n const truncate = n => (n > 0 ? Math.floor(n) : Math.ceil(n));\n const absoluteDegree = Math.abs(decimalDegree);\n let degrees = truncate(absoluteDegree);\n let minutes = truncate((absoluteDegree - degrees) * 60);\n let seconds = Math.round((absoluteDegree - degrees - minutes / 60) * 3600);\n if (seconds === 60) {\n minutes += 1;\n seconds = 0;\n }\n if (minutes === 60) {\n degrees += 1;\n minutes = 0;\n }\n let direction: string;\n if (type === 'longitude') {\n direction = decimalDegree < 0 ? 'W' : 'E';\n } else if (type === 'latitude') {\n direction = decimalDegree < 0 ? 'S' : 'N';\n }\n return `${degrees}\u00B0 ${minutes}' ${seconds}\" ${direction}`;\n};\n\nexport interface TooltipProps {\n id?: string;\n open?: boolean;\n anchor?: HTMLElement;\n latitude?: number;\n longitude?: number;\n areaId?: string;\n areaValue?: number;\n additionalFields?: Array<{ name: string; value: number | string; color?: string; icon?: string }>;\n showCoordinates?: boolean;\n tooltipHeader?: string;\n stylesManagedExternally?: boolean;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n}\n// only want latitude/longitude for marker and bubble\n// omit for choropleth, and put areaid, areavalue instead\nconst Tooltip = ({\n id,\n open,\n anchor,\n latitude,\n longitude,\n areaId,\n areaValue,\n additionalFields = [],\n showCoordinates = true,\n tooltipHeader = null,\n stylesManagedExternally = false,\n onMouseEnter,\n onMouseLeave,\n}: TooltipProps): JSX.Element => {\n const featureFlagContext = React.useContext<FeatureFlagContextValue>(FeatureFlagContext);\n const isTooltipIconFlagEnabled = Boolean(featureFlagContext?.visualizations_enableTooltipIcon);\n const styleTarget = stylesManagedExternally ? undefined : getFloatingLayerStyleTarget(anchor);\n\n const popover = (\n <StyledPopover\n id={id}\n role=\"tooltip\"\n open={open}\n animation={false}\n anchor={anchor}\n data-test=\"map-marker-tooltip\"\n defaultPlacement=\"above\"\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n <StyledTable>\n {tooltipHeader && (\n <StyledTooltipHeader data-test=\"tooltip-header\">\n <tr>\n <th colSpan={2}>\n <span data-test=\"tooltip-header-value\">{tooltipHeader}</span>\n </th>\n </tr>\n </StyledTooltipHeader>\n )}\n <tbody>\n {Boolean(areaId && areaValue) && (\n <tr>\n <StyledTitleColumn data-test=\"area-id\">{areaId}</StyledTitleColumn>\n <StyledValueColumn data-test=\"area-value\">{areaValue}</StyledValueColumn>\n </tr>\n )}\n {Boolean(showCoordinates && latitude) && (\n <tr>\n <StyledTitleColumn>{_('Latitude')}</StyledTitleColumn>\n <StyledValueColumn data-test=\"latitude\">\n {convertDegToDMS(latitude, 'latitude')}\n </StyledValueColumn>\n </tr>\n )}\n {Boolean(showCoordinates && longitude) && (\n <tr>\n <StyledTitleColumn>{_('Longitude')}</StyledTitleColumn>\n <StyledValueColumn data-test=\"longitude\">\n {convertDegToDMS(longitude, 'longitude')}\n </StyledValueColumn>\n </tr>\n )}\n {additionalFields\n .filter(({ value }) => value && String(value) !== '0')\n .map(({ name, value, color, icon }) => (\n <tr key={createDOMID()}>\n <StyledTitleColumn data-test=\"field-title\">\n {color ? (\n <StyledColorBlock data-test=\"field-color\" color={color} />\n ) : null}\n <span>\n {name}\n {isTooltipIconFlagEnabled &&\n icon &&\n (isRemoteIcon(icon) || isDataURI(icon)) ? (\n <StyledIconWrapper data-test=\"field-icon\">\n <RemoteIcon iconURL={icon} width={16} height={16} />\n </StyledIconWrapper>\n ) : null}\n </span>\n </StyledTitleColumn>\n <StyledValueColumn data-test=\"field-value\">{value}</StyledValueColumn>\n </tr>\n ))}\n </tbody>\n </StyledTable>\n </StyledPopover>\n );\n\n return styleTarget ? <StyleSheetManager target={styleTarget}>{popover}</StyleSheetManager> : popover;\n};\n\nexport default Tooltip;\n", "\nimport * as defaultImport from \"d3-scale\";\nexport * from \"d3-scale\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"chroma-js\";\nexport * from \"chroma-js\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-color-palettes\";\nexport * from \"@splunk/visualization-color-palettes\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-schemas\";\nexport * from \"@splunk/visualization-schemas\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "import { forEach, sum, isNumber, min as lodashMin, max as lodashMax, get, isEqual, isObject } from 'lodash';\nimport { LngLatBoundsLike } from 'maplibre-gl';\nimport { scalePow } from 'd3-scale';\nimport chroma from 'chroma-js';\nimport type { MapContextInterface, BaseTileConfig } from '@splunk/visualization-context/MapContext';\nimport { isColor } from '@splunk/visualizations-shared/colorUtils';\nimport { VIZ_CATEGORICAL } from '@splunk/visualization-color-palettes';\nimport { isNumber as isNumberUtil } from '@splunk/visualization-encoding/utils/types';\nimport type { GeoJsonDataType } from '@splunk/visualizations-shared/mapUtils';\nimport { LAYER_TYPE } from '@splunk/visualization-schemas';\n\nexport const MAX_LATITUDE = 90;\nexport const MIN_LATITUDE = -90;\nexport const MAX_LONGITUDE = 180;\nexport const MIN_LONGITUDE = -180;\nexport const DEFAULT_RESULT_LIMIT = 1000;\nexport const DEFAULT_CLUSTER_COLOR = '#909090';\nexport const DEFAULT_SERIES_COLORS = VIZ_CATEGORICAL;\n// MapLibre requires a map style specification number which is always 8\nexport const MAP_STYLE_VERSION_NUMBER = 8;\n// currently using one [min, max] value set for bubbles across all zoom levels\nexport const MIN_BUBBLE_RADIUS = 7.11; // 10px\nexport const MAX_BUBBLE_RADIUS = 45.26; // 85px\nexport const DEFAULT_OPACITY = 0.8;\nconst LONGITUDE = 'longitude';\nconst LATITUDE = 'latitude';\nexport type MaybeBaseTileConfig = BaseTileConfig | Record<string, never>;\ninterface GenericLayerType {\n type: string;\n latitude: number[];\n longitude: number[];\n dataColors?: string[] | '';\n seriesColors: string[];\n additionalTooltipFields?: string[];\n tooltipHeaderField?: string[];\n resultLimit: number;\n metadata?: Array<{ [key: string]: number | string }>;\n}\n\nexport interface MarkerLayerType extends GenericLayerType {\n type: LAYER_TYPE.Marker;\n}\n\nexport interface BubbleLayerType extends GenericLayerType {\n type: LAYER_TYPE.Bubble;\n bubbleSize?: number[][] | number[];\n bubbleSizeFields: string[];\n dataValuesField?: string;\n tooltipHeaderFieldName?: string;\n geobin?: string[];\n icon?: string[];\n tooltipFieldIcons?: string;\n}\n\ninterface BubbleLayerDatumType {\n zoom?: number | null;\n values: number[];\n sanitizedValues: number[];\n coordinates: number[];\n}\n\nexport interface BubbleLayerDataType {\n data: BubbleLayerDatumType[];\n dataRange: number[];\n isPie: boolean;\n resultLimit: number;\n bubbleSizeFields: string[];\n}\n\nexport interface ChoroplethLayerType {\n type: LAYER_TYPE.Choropleth;\n areaIds: string[];\n areaValues: number[];\n dataColors: string[];\n additionalTooltipFields?: string[];\n tooltipHeaderField?: string[];\n geom?: GeoJsonDataType[] | null;\n resultLimit?: number;\n metadata?: Array<{ [key: string]: number | string | GeoJsonDataType }>;\n source?: string;\n width?: string | number;\n height?: string | number;\n choroplethEmptyAreaColor?: string;\n choroplethStrokeColor?: string;\n choroplethOpacity?: number;\n}\n\nexport interface MapLayerClickPayloadType {\n name?: string;\n value?: string | number;\n /* cell values of all cells of clicked row with the field and value - in shape row.<field>.value */\n [key: string]: string | number;\n}\n\nexport type ClusterLayerType = BubbleLayerType | MarkerLayerType;\nexport type LayerType = ClusterLayerType | ChoroplethLayerType;\n/**\n * Construct a tile preset {key: config} by combining the default + custom tile configs\n * Also returns the default tile config for each theme - light/dark\n * @param {MapContextInterface} args\n * @param {BaseTileConfig[]} args.defaultTileConfig\n * @param {BaseTileConfig[]} args.customTileConfig\n * @returns {Object} tile preset\n */\nexport const getTilePreset = ({\n defaultTileConfig = [],\n customTileConfig = [],\n}: MapContextInterface): {\n tilePreset: Record<string, BaseTileConfig>;\n defaultTileLight: MaybeBaseTileConfig;\n defaultTileDark: MaybeBaseTileConfig;\n} => {\n const tilePreset: Record<string, BaseTileConfig> = {};\n let defaultTileLight: MaybeBaseTileConfig = {};\n let defaultTileDark: MaybeBaseTileConfig = {};\n const tileConfigs = [...defaultTileConfig, ...customTileConfig];\n forEach(tileConfigs, tileConfig => {\n const key = tileConfig?.key;\n if (!key) {\n return;\n }\n const updatedConfig: BaseTileConfig = {\n ...tileConfig,\n version: MAP_STYLE_VERSION_NUMBER,\n };\n tilePreset[key] = updatedConfig;\n });\n\n if (defaultTileConfig.length > 0) {\n defaultTileLight =\n defaultTileConfig.find(config => config.theme === 'light') ??\n defaultTileConfig.find(config => config.theme === undefined) ??\n {};\n defaultTileDark =\n defaultTileConfig.find(config => config.theme === 'dark') ??\n defaultTileConfig.find(config => config.theme === undefined) ??\n {};\n }\n\n return { tilePreset, defaultTileLight, defaultTileDark };\n};\n\n/**\n * Check if baseLayerTileServer is in tilePreset and config matches current theme, if yes, return.\n * If no, construct a mapStyle with baseLayerTilerServer and baseLayerTileServerType\n * Else return default tile config based on current theme\n * @param {Object} args\n * @param {BaseTileConfig[]} args.tilePreset\n * @param {String} args.baseLayerTilerServer\n * @param {String} args.baseLayerTileServerType\n * @param {String} args.colorScheme\n * @param {BaseTileConfig} args.defaultTileDark\n * @param {BaseTileConfig} args.defaultTileLight\n * @returns {BaseTileConfig} mapStyle\n */\nexport const getMapStyle = ({\n showBaseLayer,\n baseLayerTileServer = '',\n baseLayerTileServerType = '',\n tilePreset = {},\n colorScheme = 'light',\n defaultTileLight = {},\n defaultTileDark = {},\n}: {\n showBaseLayer: boolean;\n baseLayerTileServer?: string;\n baseLayerTileServerType?: string;\n tilePreset?: Record<string, BaseTileConfig>;\n colorScheme?: string;\n defaultTileLight?: MaybeBaseTileConfig;\n defaultTileDark?: MaybeBaseTileConfig;\n}): MaybeBaseTileConfig => {\n if (!showBaseLayer) {\n return {\n name: 'empty-base-layer',\n key: 'empty-base-layer',\n version: MAP_STYLE_VERSION_NUMBER,\n sources: {\n 'base-tiles': {\n type: 'raster',\n tiles: [\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',\n ],\n tileSize: 256,\n },\n },\n layers: [\n {\n id: 'base-layer',\n type: 'raster',\n source: 'base-tiles',\n minzoom: 0,\n maxzoom: 22,\n },\n ],\n };\n }\n\n if (\n baseLayerTileServer &&\n tilePreset[baseLayerTileServer] &&\n (!tilePreset[baseLayerTileServer].theme || tilePreset[baseLayerTileServer].theme === colorScheme)\n ) {\n return tilePreset[baseLayerTileServer];\n }\n\n if (baseLayerTileServer && baseLayerTileServerType) {\n let tiles: string[] = [];\n /**\n * Tile Server URLs (eg: http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png) can specify the variable {s} which refers to a subdomain\n * Subdomains are used to help with browser parallel requests per domain limitation. These subdomains are typically single letters 'a', 'b' and 'c'\n * Refer to https://leafletjs.com/SlavaUkraini/reference.html#tilelayer and https://wiki.openstreetmap.org/wiki/Tile_servers\n */\n if (/^(https?):\\/\\/{[sS]}\\./.exec(baseLayerTileServer)) {\n /**\n * sXML (Leaflet) allows users to define their own tile server URLs + list of available subdomains\n * In order to preserve this behavior during conversion to splunk.map,\n * if the variable {s} or {S} is detected, replace it with 'a', 'b' and 'c' - default values for subdomains\n */\n tiles = [\n baseLayerTileServer.replace(/{[sS]}/, 'a'),\n baseLayerTileServer.replace(/{[sS]}/, 'b'),\n baseLayerTileServer.replace(/{[sS]}/, 'c'),\n ];\n } else {\n tiles = [baseLayerTileServer];\n }\n const mapStyle: BaseTileConfig = {\n name: baseLayerTileServer,\n key: baseLayerTileServer,\n version: MAP_STYLE_VERSION_NUMBER,\n sources: {\n 'base-tiles': {\n type: baseLayerTileServerType,\n tiles,\n tileSize: 256,\n },\n },\n layers: [\n {\n id: 'base-layer',\n type: 'raster',\n source: 'base-tiles',\n minzoom: 0,\n maxzoom: 24, // https://maplibre.org/maplibre-gl-js-docs/api/map/\n },\n ],\n };\n return mapStyle;\n }\n\n // if tile server is not present in the preset AND we can't construct a mapStyle, fall back on defaults\n return colorScheme === 'light' ? defaultTileLight : defaultTileDark;\n};\n\nexport interface ZoomConstraints {\n minZoom: number;\n maxZoom: number;\n}\n\nexport const getZoomConstraintsFromTileConfig = (\n tileConfig: BaseTileConfig,\n baseLayerTileServer?: string\n): ZoomConstraints => {\n const { sources, layers } = tileConfig;\n let matchedBaseLayerTileServer = false;\n // check sources for minzoom maxzoom first\n const sourceKeys = Object.keys(sources);\n for (const key of sourceKeys) {\n const source = sources[key] as { [key: string]: unknown };\n const { minzoom, maxzoom } = source;\n const tiles = Array.isArray(source?.tiles) ? (source.tiles as string[]) : [];\n if (baseLayerTileServer && tiles.includes(baseLayerTileServer)) {\n matchedBaseLayerTileServer = true;\n }\n if (\n ((baseLayerTileServer && matchedBaseLayerTileServer) || !baseLayerTileServer) &&\n isNumber(minzoom) &&\n isNumber(maxzoom)\n ) {\n return {\n minZoom: minzoom,\n maxZoom: maxzoom,\n };\n }\n }\n // then check layers\n for (const layer of layers) {\n const { minzoom, maxzoom } = layer;\n if (\n ((baseLayerTileServer && matchedBaseLayerTileServer) || !baseLayerTileServer) &&\n isNumber(minzoom) &&\n isNumber(maxzoom)\n ) {\n return {\n minZoom: minzoom,\n maxZoom: maxzoom,\n };\n }\n }\n // Maplibre default - would reset previous min/maxZoom https://maplibre.org/maplibre-gl-js-docs/api/map/\n return {\n minZoom: 0,\n maxZoom: 24,\n };\n};\n\nexport const isBaseTileConfig = (config: MaybeBaseTileConfig): config is BaseTileConfig =>\n Boolean(config && 'name' in config && 'key' in config && 'sources' in config && 'layers' in config);\n\nexport const getZoomLevelFromGeobin = (geobinStr?: string | null): number | null => {\n if (!geobinStr) {\n return null;\n }\n // geostats cmds return geobin with zoom level 0-18, 0-99 in the geobinPattern covers the range\n const geobinPattern = /bin_id_zl_(\\d{1,2})_y_/g;\n const match = geobinPattern.exec(geobinStr);\n return (match?.length && Number.parseInt(match[1], 10)) ?? null;\n};\n\n// Bubble colors - static\nexport const getStaticColors = (colorCount: number, colorArray: string[]): string[] => {\n if (colorCount < 0 || !colorCount) {\n return [DEFAULT_CLUSTER_COLOR];\n }\n if (!colorArray?.length) {\n return [...new Array(colorCount).keys()].map(i => DEFAULT_SERIES_COLORS[i]);\n }\n // loop through colorArray to pick the first $colorCount colors\n // start from begining again if colorCount > colorArray.length\n return [...new Array(colorCount).keys()].map(i =>\n isColor(colorArray[i % colorArray.length]) ? colorArray[i % colorArray.length] : DEFAULT_CLUSTER_COLOR\n );\n};\n\n// Bubble size\nexport const matchBubbleSize = (dataRange: number[], data: number): any => {\n const size = scalePow().exponent(0.2).domain(dataRange).range([MIN_BUBBLE_RADIUS, MAX_BUBBLE_RADIUS])(\n data\n );\n\n if (size > MAX_BUBBLE_RADIUS) {\n return MAX_BUBBLE_RADIUS;\n }\n if (size < MIN_BUBBLE_RADIUS) {\n return MIN_BUBBLE_RADIUS;\n }\n return size;\n};\n\nexport const transposeArray = (array: number[][]): number[][] => {\n if (!array?.length || !array[0]?.length) {\n return [];\n }\n return array[0].map((_, i) => array.map(row => row[i]));\n};\n\n// sanitize values: update all null, undefined, or negative values to 0\nexport const sanitizeValues = (values: number[] | number[][]) => {\n // null / undefined\n if (!values) {\n return 0;\n }\n // number\n if (!Array.isArray(values)) {\n return Math.max(values, 0);\n }\n // array\n return values.map(arr => sanitizeValues(arr));\n};\n\n// eslint-disable-next-line consistent-return\nexport const sortByValuesField = (bubbleLayer: BubbleLayerType) => {\n const { bubbleSizeFields, dataValuesField } = bubbleLayer;\n\n // Find the index of dataValuesField in fields\n const index = bubbleSizeFields.indexOf(dataValuesField);\n if (index === -1) return bubbleLayer; // If not found, return as is\n\n // Move dataValuesField and corresponding sizes to the first position\n bubbleLayer.bubbleSizeFields.unshift(bubbleLayer.bubbleSizeFields.splice(index, 1)[0]);\n bubbleLayer.bubbleSize.unshift(bubbleLayer.bubbleSize.splice(index, 1)[0] as number & number[]);\n};\n\nexport const bakeBubbleData = (layer: BubbleLayerType): BubbleLayerDataType => {\n if (!layer?.bubbleSize?.length || !layer?.latitude?.length || !layer?.longitude?.length) {\n return null;\n }\n const hasGeobinData = Array.isArray(layer.geobin) && layer.geobin.length > 0;\n // if bubbleSize is passed as an array of single number array (data series)\n // e.g. [value0, value1, ...]\n // format each value as an array to unify data operations for data series and frames\n const sanitizedBubbleSize = sanitizeValues(layer.bubbleSize);\n let transposedBubbleSize: number[][];\n let transposedSanitizedBubbleSize: number[][];\n let isPie = false;\n // format array if bubbleSize is passed as an array of array (data frame)\n if (Array.isArray(layer.bubbleSize[0])) {\n // one-time array transpose,\n // e.g. from [column0data, column0data] (multi series)\n // to [[column0datum0, column1datum0], [column0datum1, column1data1], ...]\n // or e.g. from [column0data] (single series)\n // to [[column0data]]\n // for easy access of values at each geo location,\n // and min max pie size computation\n transposedBubbleSize = transposeArray(layer.bubbleSize as number[][]);\n transposedSanitizedBubbleSize = transposeArray(sanitizedBubbleSize);\n // if multiple series in the dataframe, set isPie to true\n if (layer.bubbleSize.length > 1) {\n isPie = true;\n // when dynamic coloring is enabled,\n // set the configured dataValues field as the first field\n // to apply dynamic colors only to the first pie slice.\n if (layer.dataValuesField && !!layer.dataColors) {\n sortByValuesField(layer); // here\n }\n }\n } else {\n transposedBubbleSize = layer.bubbleSize.map(n => [n]);\n transposedSanitizedBubbleSize = sanitizedBubbleSize.map(n => [n]);\n }\n if (!transposedBubbleSize?.length) {\n return null;\n }\n const data = layer.latitude\n .map((lat, i) => ({\n zoom: hasGeobinData ? getZoomLevelFromGeobin(layer.geobin[i]) : null,\n values: transposedBubbleSize[i],\n sanitizedValues: transposedSanitizedBubbleSize[i],\n coordinates: [layer.longitude[i], lat],\n metadata: layer.metadata ? layer.metadata[i] : {},\n }))\n .filter(d => Boolean(d.values));\n\n // compute the min/max value to encode min/max pie or bubble size\n let min = sum(transposedSanitizedBubbleSize[0]);\n let max = min;\n transposedSanitizedBubbleSize.forEach(row => {\n const bubbleSize = sum(row);\n max = Math.max(bubbleSize, max);\n min = Math.min(bubbleSize, min);\n });\n return {\n data,\n dataRange: [min, max],\n isPie,\n resultLimit: layer.resultLimit,\n bubbleSizeFields: layer.bubbleSizeFields,\n };\n};\n\nexport const isValidLatLon = (latlon: Array<number | string>): boolean => {\n if (!latlon || !Array.isArray(latlon) || latlon.length !== 2) {\n return false;\n }\n const [lat, lon] = latlon;\n if (!isNumberUtil(lat) || !(Number(lat) >= MIN_LATITUDE && Number(lat) <= MAX_LATITUDE)) {\n return false;\n }\n if (!isNumberUtil(lon) || !(Number(lon) >= MIN_LONGITUDE && Number(lon) <= MAX_LONGITUDE)) {\n return false;\n }\n return true;\n};\n\nexport const getChoroplethValues = (field: string, choroplethLayer: ChoroplethLayerType): number[] => {\n if (!Array.isArray(choroplethLayer.geom) || choroplethLayer.geom.length === 0) {\n return [];\n }\n const limit = choroplethLayer.resultLimit ?? DEFAULT_RESULT_LIMIT;\n const slicedGeomList = choroplethLayer.geom.slice(0, limit);\n const flatCoordinates = slicedGeomList.flatMap(geomObject => {\n if (!geomObject) {\n return [];\n }\n if (geomObject.type === 'MultiPolygon') {\n return geomObject.coordinates.flat(2);\n }\n if (geomObject.type === 'Polygon') {\n return geomObject.coordinates.flat();\n }\n return [];\n });\n return flatCoordinates.map(coord => coord[field === LONGITUDE ? 0 : 1]);\n};\n\n/**\n * Returns a list of all lat or lon coordinates used in a specified layer\n * @param {LayerType[]} layer\n * @param {string} field\n * @returns {number[]} list of lat coordinates or lon coordinates\n */\nconst getLatOrLonCoordinates = (layer: LayerType, field: string): number[] => {\n const getClusterValues = (clusterLayer: ClusterLayerType): number[] =>\n get(clusterLayer, field, []).slice(\n 0,\n clusterLayer.type === LAYER_TYPE.Marker && clusterLayer.resultLimit\n ? clusterLayer.resultLimit\n : DEFAULT_RESULT_LIMIT\n );\n return layer.type === LAYER_TYPE.Choropleth ? getChoroplethValues(field, layer) : getClusterValues(layer);\n};\n\n/**\n * Returns the min and max LongLat pairs to determine the layer boundaries to fit all markers/bubbles\n * @param {LayerType[]} layers\n * @returns {LngLatBoundsLike}\n */\nexport const getGlobalLayerBoundaries = (layers: LayerType[]): LngLatBoundsLike => {\n const isLayerValid = (field: string): boolean =>\n layers.every(layer => layer[field] || (layer as ChoroplethLayerType).geom);\n const getDefaultMax = (field: string) => (field === LONGITUDE ? MAX_LONGITUDE : MAX_LATITUDE);\n const getDefaultMin = (field: string) => (field === LONGITUDE ? MIN_LONGITUDE : MIN_LATITUDE);\n\n if (!layers || !Array.isArray(layers) || !layers.length) {\n return null;\n }\n\n const getMin = (field: string): number => {\n if (!isLayerValid(field)) {\n return getDefaultMin(field);\n }\n return layers.reduce((prevVal, layer) => {\n const coordinatesNumArr = getLatOrLonCoordinates(layer, field).map(x => +x);\n return lodashMin([prevVal, ...coordinatesNumArr]);\n }, getDefaultMax(field));\n };\n\n const getMax = (field: string): number => {\n if (!isLayerValid(field)) {\n return getDefaultMax(field);\n }\n return layers.reduce((prevVal, layer) => {\n const coordinatesNumArr = getLatOrLonCoordinates(layer, field).map(Number);\n return lodashMax([prevVal, ...coordinatesNumArr]);\n }, getDefaultMin(field));\n };\n\n return [\n [getMin(LONGITUDE), getMin(LATITUDE)],\n [getMax(LONGITUDE), getMax(LATITUDE)],\n ];\n};\n\nexport const formatTooltipFieldValue = (value: unknown): string | number => {\n if (value === null || value === undefined) {\n return '';\n }\n if (typeof value === 'string' || typeof value === 'number') {\n return value;\n }\n return JSON.stringify(value);\n};\n\nexport const getScaledOpacities = (colors: string[], cfgOpacity: number): number[] => {\n // extract opacity information from 8 digit hex codes\n const opacities = colors?.map(color => (color?.length === 9 ? (chroma(color).alpha() ?? 1) : 1));\n // opacity cannot be greater than configured opacity\n return opacities?.map(opacity => opacity * cfgOpacity);\n};\n\nexport const compareBaseStyles = (curr, next): boolean => {\n const currBaseLayer = curr?.layers?.find(layer => layer?.id === 'base-layer');\n const nextBaseLayer = next?.layers?.find(layer => layer?.id === 'base-layer');\n const currBaseSource = get(curr?.sources, (currBaseLayer?.source as string) ?? '');\n const nextBaseSource = get(next?.sources, (nextBaseLayer?.source as string) ?? '');\n\n if (!currBaseLayer || !nextBaseLayer || !currBaseSource || !nextBaseSource) {\n return false;\n }\n\n return isEqual(currBaseLayer, nextBaseLayer) && isEqual(currBaseSource, nextBaseSource);\n};\n\nexport const formatMetadata = (\n choroplethLayer: ChoroplethLayerType,\n i: number\n): { [key: string]: string } => {\n if (!choroplethLayer?.areaIds || !choroplethLayer?.areaValues) return {};\n if (i >= choroplethLayer.areaIds.length) return {};\n\n const metadata = choroplethLayer.metadata ? choroplethLayer.metadata[i] : {};\n const name = choroplethLayer.areaIds[i];\n const value = choroplethLayer.areaValues[i];\n const base = { name, value: String(value) };\n\n return Object.keys(metadata).reduce((result, curr) => {\n const key = `row.${curr}.value`;\n const val = isObject(metadata[curr]) ? JSON.stringify(metadata[curr]) : String(metadata[curr]);\n return { ...result, [key]: val };\n }, base);\n};\n", "\nimport * as defaultImport from \"maplibre-gl\";\nexport * from \"maplibre-gl\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "import * as React from 'react';\n\ninterface MapContextValue {\n activeTooltipId: string | null;\n setActiveTooltipId: (id: string | null | ((prev: string | null) => string | null)) => void;\n activeChoroplethId: string | null;\n setActiveChoroplethId: (id: string | null) => void;\n}\n\nconst MapContext = React.createContext<MapContextValue>({\n activeTooltipId: null,\n setActiveTooltipId: () => {},\n activeChoroplethId: null,\n setActiveChoroplethId: () => {},\n});\n\nexport const MapProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [activeTooltipId, setActiveTooltipId] = React.useState<string | null>(null);\n const [activeChoroplethId, setActiveChoroplethId] = React.useState<string | null>(null);\n\n const value = React.useMemo(\n () => ({\n activeTooltipId,\n setActiveTooltipId,\n activeChoroplethId,\n setActiveChoroplethId,\n }),\n [activeTooltipId, activeChoroplethId]\n );\n\n return <MapContext.Provider value={value}>{children}</MapContext.Provider>;\n};\n\nexport const useMapContext = () => React.useContext(MapContext);\n", "import type { Map } from 'maplibre-gl';\nimport { Marker } from 'maplibre-gl';\nimport * as React from 'react';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport Tooltip from './Tooltip';\nimport type { TooltipProps } from './Tooltip';\nimport { useMapContext } from './MapContext';\n\nexport interface MarkerWrapperProps extends React.HTMLAttributes<HTMLDivElement> {\n latitude: number;\n longitude: number;\n areaId?: string;\n areaValue?: number;\n additionalFields?: TooltipProps['additionalFields'];\n tooltipHeader?: TooltipProps['tooltipHeader'];\n map: React.MutableRefObject<Map>;\n showCoordinates?: boolean;\n stylesManagedExternally?: boolean;\n customMarkerId?: string;\n}\n\nconst MarkerWrapper = ({\n longitude,\n latitude,\n areaId,\n areaValue,\n additionalFields = [],\n tooltipHeader = null,\n map,\n children,\n showCoordinates = true,\n stylesManagedExternally = false,\n customMarkerId,\n ...otherProps\n}: MarkerWrapperProps): JSX.Element => {\n const container = React.useRef<HTMLDivElement>();\n const marker = React.useRef<Marker>();\n const [isTooltipOpen, setTooltipOpenStatus] = React.useState(false);\n const [isFocused, setIsFocused] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n const [isPopoverHovered, setIsPopoverHovered] = React.useState(false);\n const tooltipId = React.useMemo(() => createDOMID(), []);\n const pendingMoveEndHandler = React.useRef<(() => void) | null>(null);\n const closeTimeoutRef = React.useRef<NodeJS.Timeout | null>(null);\n const generatedMarkerId = React.useMemo(() => createDOMID(), []);\n const markerId = customMarkerId || generatedMarkerId;\n const { activeTooltipId, setActiveTooltipId } = useMapContext();\n const mapMoveHandlerRef = React.useRef<(() => void) | null>(null);\n\n const openTooltip = React.useCallback(() => {\n setActiveTooltipId(markerId);\n setTooltipOpenStatus(true);\n }, [markerId, setActiveTooltipId]);\n\n const cleanupPendingMoveEnd = React.useCallback(() => {\n if (pendingMoveEndHandler.current && map.current && typeof map.current.off === 'function') {\n map.current.off('moveend', pendingMoveEndHandler.current);\n pendingMoveEndHandler.current = null;\n }\n }, [map]);\n\n const cleanupMapMoveHandler = React.useCallback(() => {\n if (mapMoveHandlerRef.current && map.current && typeof map.current.off === 'function') {\n map.current.off('move', mapMoveHandlerRef.current);\n mapMoveHandlerRef.current = null;\n }\n }, [map]);\n\n // Consolidated close logic: only close if nothing is keeping tooltip open\n const shouldCloseTooltip = React.useCallback(\n (focused: boolean, hovered: boolean, popoverHovered: boolean) => {\n return !focused && !hovered && !popoverHovered;\n },\n []\n );\n\n const cancelCloseTimeout = React.useCallback(() => {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n }, []);\n\n const closeTooltipIfShould = React.useCallback(\n (focused: boolean, hovered: boolean, popoverHovered: boolean) => {\n cancelCloseTimeout();\n\n if (shouldCloseTooltip(focused, hovered, popoverHovered)) {\n // Small delay to allow mouse to reach tooltip\n closeTimeoutRef.current = setTimeout(() => {\n setTooltipOpenStatus(false);\n setActiveTooltipId(currentId => (currentId === markerId ? null : currentId));\n closeTimeoutRef.current = null;\n }, 100);\n }\n },\n [shouldCloseTooltip, markerId, setActiveTooltipId, cancelCloseTimeout]\n );\n\n const handleMouseEnter = React.useCallback(() => {\n cancelCloseTimeout();\n setIsHovered(true);\n openTooltip();\n }, [openTooltip, cancelCloseTimeout]);\n\n const handleMouseLeave = React.useCallback(() => {\n setIsHovered(false);\n closeTooltipIfShould(isFocused, false, isPopoverHovered);\n }, [isFocused, isPopoverHovered, closeTooltipIfShould]);\n\n const handlePopoverMouseEnter = React.useCallback(() => {\n cancelCloseTimeout();\n setIsPopoverHovered(true);\n }, [cancelCloseTimeout]);\n\n const handlePopoverMouseLeave = React.useCallback(() => {\n setIsPopoverHovered(false);\n closeTooltipIfShould(isFocused, isHovered, false);\n }, [isFocused, isHovered, closeTooltipIfShould]);\n\n const handleBlur = React.useCallback(() => {\n setIsFocused(false);\n cleanupPendingMoveEnd();\n closeTooltipIfShould(false, isHovered, isPopoverHovered);\n }, [isHovered, isPopoverHovered, cleanupPendingMoveEnd, closeTooltipIfShould]);\n\n const handleEscapeKey = React.useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape' && activeTooltipId === markerId) {\n cancelCloseTimeout();\n setIsFocused(false);\n setIsHovered(false);\n setIsPopoverHovered(false);\n cleanupPendingMoveEnd();\n setTooltipOpenStatus(false);\n setActiveTooltipId(null);\n }\n },\n [activeTooltipId, markerId, cleanupPendingMoveEnd, setActiveTooltipId, cancelCloseTimeout]\n );\n\n const handleFocus = React.useCallback(() => {\n // Clean up any pending moveend handler from previous focus\n cleanupPendingMoveEnd();\n\n // Pan map to show focused datapoint if it's outside current bounds\n if (\n map.current &&\n longitude !== undefined &&\n latitude !== undefined &&\n typeof map.current.once === 'function'\n ) {\n const bounds = map.current.getBounds();\n if (!bounds.contains([longitude, latitude])) {\n // Set focused state and open tooltip after pan completes\n const moveEndHandler = () => {\n pendingMoveEndHandler.current = null;\n setIsFocused(true);\n openTooltip();\n };\n pendingMoveEndHandler.current = moveEndHandler;\n map.current.once('moveend', moveEndHandler);\n map.current.panTo([longitude, latitude]);\n return;\n }\n }\n // No pan needed, set focused immediately\n setIsFocused(true);\n openTooltip();\n }, [openTooltip, map, longitude, latitude, cleanupPendingMoveEnd]);\n\n const cleanupMarker = React.useCallback(() => {\n if (marker.current) {\n marker.current.remove();\n marker.current = undefined;\n }\n }, []);\n\n React.useEffect(() => {\n try {\n if (marker.current) {\n marker.current.setLngLat([longitude, latitude]);\n } else {\n marker.current = new Marker({ element: container.current });\n marker.current.setLngLat([longitude, latitude]);\n marker.current.addTo(map.current);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(error);\n cleanupMarker();\n }\n }, [latitude, longitude, map]);\n\n // Add Escape key listener when tooltip is open\n React.useEffect(() => {\n if (isTooltipOpen && activeTooltipId === markerId) {\n document.addEventListener('keydown', handleEscapeKey);\n return () => {\n document.removeEventListener('keydown', handleEscapeKey);\n };\n }\n return undefined;\n }, [isTooltipOpen, activeTooltipId, markerId, handleEscapeKey]);\n\n // Close tooltip if another marker becomes active\n React.useEffect(() => {\n if (isTooltipOpen && activeTooltipId !== markerId && activeTooltipId !== null) {\n setTooltipOpenStatus(false);\n }\n }, [activeTooltipId, markerId, isTooltipOpen]);\n\n // Reopen tooltip if this marker has focus/hover/popoverHover when another tooltip closes\n React.useEffect(() => {\n if (!isTooltipOpen && activeTooltipId === null && (isFocused || isHovered || isPopoverHovered)) {\n openTooltip();\n }\n }, [activeTooltipId, isTooltipOpen, isFocused, isHovered, isPopoverHovered, openTooltip]);\n\n // For choropleths: sync local tooltip state with global active state\n // Choropleths set activeTooltipId from MapLibre event handlers, so open tooltip when this marker becomes active\n React.useEffect(() => {\n if (!customMarkerId) return;\n\n if (activeTooltipId === markerId) {\n setTooltipOpenStatus(true);\n } else {\n setTooltipOpenStatus(false);\n }\n }, [customMarkerId, activeTooltipId, markerId]);\n\n // Update marker position during map movement/zoom when tooltip is open\n // Use requestAnimationFrame to throttle updates to once per frame\n const [, forceUpdate] = React.useReducer(x => x + 1, 0);\n\n React.useEffect(() => {\n if (!isTooltipOpen || !map.current || typeof map.current.on !== 'function') {\n return undefined;\n }\n\n let rafId: number | null = null;\n\n const handleMapMove = () => {\n rafId ??= requestAnimationFrame(() => {\n forceUpdate();\n rafId = null;\n });\n };\n\n mapMoveHandlerRef.current = handleMapMove;\n map.current.on('move', handleMapMove);\n\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n }\n cleanupMapMoveHandler();\n };\n }, [isTooltipOpen, map, cleanupMapMoveHandler]);\n\n React.useEffect(\n () => () => {\n cancelCloseTimeout();\n cleanupPendingMoveEnd();\n cleanupMapMoveHandler();\n cleanupMarker();\n },\n [cancelCloseTimeout, cleanupPendingMoveEnd, cleanupMapMoveHandler, cleanupMarker]\n );\n const filteredAdditionalFields = additionalFields.filter(({ value }) => value && String(value) !== '0');\n const showTooltip =\n showCoordinates || filteredAdditionalFields.length || (areaId && !Number.isNaN(areaValue));\n // Only show tooltip if this marker is the active one in the global context\n // keepChildrenVisible allows tooltip to show during state sync for choropleths\n const isTooltipVisible = activeTooltipId === markerId && (isTooltipOpen || customMarkerId !== undefined);\n\n const childrenWithTooltipId = React.useMemo(() => {\n if (!children) return null;\n if (!React.isValidElement(children)) return children;\n return React.cloneElement(children, {\n 'aria-describedby': tooltipId,\n } as any);\n }, [children, tooltipId]);\n\n return (\n <div>\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div // NOSONAR typescript:S6848 - this wrapper only forwards hover/focus events to position a tooltip; it is not an interactive control and adding a role would misrepresent it to assistive tech\n ref={container}\n data-test=\"map-marker\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...otherProps}\n >\n {childrenWithTooltipId}\n </div>\n <div>\n {showTooltip && (\n <Tooltip\n id={tooltipId}\n open={isTooltipVisible}\n anchor={container.current}\n latitude={showCoordinates ? latitude : null}\n longitude={showCoordinates ? longitude : null}\n areaId={areaId}\n areaValue={areaValue}\n additionalFields={additionalFields}\n showCoordinates={showCoordinates}\n tooltipHeader={tooltipHeader}\n stylesManagedExternally={stylesManagedExternally}\n onMouseEnter={handlePopoverMouseEnter}\n onMouseLeave={handlePopoverMouseLeave}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default MarkerWrapper;\n", "import * as React from 'react';\nimport styled from 'styled-components';\nimport type { Map } from 'maplibre-gl';\nimport { sum } from 'lodash';\nimport { isRemoteIcon, isDataURI } from '@splunk/visualizations-shared/iconUtils';\nimport { isColor } from '@splunk/visualizations-shared/colorUtils';\nimport RemoteIcon from '@splunk/visualizations-shared/RemoteIcon';\nimport FeatureFlagContext from '@splunk/visualization-context/FeatureFlagContext';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport { sprintf } from '@splunk/ui-utils/format';\nimport { KEYBOARD_KEYS } from './keyboardConstants';\nimport { convertDegToDMS } from './Tooltip';\nimport {\n bakeBubbleData,\n BubbleLayerType,\n DEFAULT_SERIES_COLORS,\n DEFAULT_RESULT_LIMIT,\n DEFAULT_CLUSTER_COLOR,\n getStaticColors,\n matchBubbleSize,\n} from './MapUtils';\nimport MarkerWrapper from './MarkerWrapper';\nimport type { TooltipProps } from './Tooltip';\nimport { useRovingTabindex } from './useRovingTabindex';\n\ntype FeatureFlagContextValue = Record<string, boolean | undefined> | null;\n\nexport const GEO_BOUND_PREFIX = '_geo_bounds_';\nexport const GEO_LAT_AND_LONG_FIELD = ['_geo_long_field', '_geo_lat_field'];\nexport const ICON_DISPLAY_CUTOFF = 16;\n\nexport interface PieSegmentProps {\n start: number;\n end: number;\n radius: number;\n color: string;\n themeColor: string;\n segmentMetadata?: { name: string; value: number; color: string };\n handleBubbleClick?: (e: React.UIEvent, name: string, count: number) => void;\n ariaLabel?: string;\n 'aria-describedby'?: string;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n elementRef?: React.Ref<Element>;\n hasEventHandlers?: boolean;\n}\n\nexport const PieSegment = React.memo(\n ({\n start,\n end,\n radius,\n color,\n themeColor,\n segmentMetadata,\n handleBubbleClick,\n ariaLabel,\n 'aria-describedby': ariaDescribedBy,\n onKeyDown,\n onFocus,\n onBlur,\n elementRef,\n hasEventHandlers,\n }: PieSegmentProps): JSX.Element => {\n const { name, value } = segmentMetadata ?? {};\n const handleInteraction = React.useCallback(\n (e: React.UIEvent) => {\n if ('key' in e && e.key !== KEYBOARD_KEYS.ENTER && e.key !== KEYBOARD_KEYS.SPACE) {\n return;\n }\n e.preventDefault();\n handleBubbleClick(e, name, value);\n },\n [name, value, handleBubbleClick]\n );\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n // Handle Enter/Space for activation only when interactive\n if (hasEventHandlers && (e.key === KEYBOARD_KEYS.ENTER || e.key === KEYBOARD_KEYS.SPACE)) {\n handleInteraction(e);\n }\n\n // Always call the navigation handler for arrow keys, Home, End\n if (onKeyDown) {\n onKeyDown(e);\n }\n },\n [hasEventHandlers, handleInteraction, onKeyDown]\n );\n\n if (end - start === 1) {\n return (\n <BubbleSegment\n $hasEventHandlers={hasEventHandlers}\n ref={elementRef as React.Ref<SVGCircleElement>}\n as=\"circle\"\n role={hasEventHandlers ? 'button' : 'graphics-symbol'}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n onClick={hasEventHandlers ? handleInteraction : undefined}\n onKeyDown={handleKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n cx={radius}\n cy={radius}\n r={radius}\n fill={color}\n fillOpacity={0.5}\n strokeWidth={1.5}\n stroke={color}\n />\n );\n }\n const a0 = 2 * Math.PI * (start - 0.25);\n const a1 = 2 * Math.PI * (end - 0.25);\n const x0 = Math.cos(a0);\n const y0 = Math.sin(a0);\n const x1 = Math.cos(a1);\n const y1 = Math.sin(a1);\n const arc = end - start > 0.5 ? 1 : 0;\n\n return (\n <BubbleSegment\n $hasEventHandlers={hasEventHandlers}\n ref={elementRef as React.Ref<SVGPathElement>}\n as=\"path\"\n role={hasEventHandlers ? 'button' : 'graphics-symbol'}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n onClick={hasEventHandlers ? handleInteraction : undefined}\n onKeyDown={handleKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n d={`M ${radius} ${radius} L ${radius + radius * x0} ${\n radius + radius * y0\n } A ${radius} ${radius} 0 ${arc} 1 ${radius + radius * x1} ${\n radius + radius * y1\n } L ${radius} ${radius} A 0 0 0 ${arc} 0 ${radius} ${radius}`}\n fill={color}\n fillOpacity={0.8}\n stroke={themeColor}\n strokeWidth={2}\n strokeOpacity={0.3}\n />\n );\n }\n);\n\nPieSegment.displayName = 'MapBubblePieSegment';\n\nexport const BubbleSegment = styled.path<{ $hasEventHandlers: boolean }>`\n transition: 0.2s ease-in-out;\n transition-property: fill, stroke;\n ${({ $hasEventHandlers }) => $hasEventHandlers && 'cursor: pointer;'}\n\n &:focus {\n outline: none;\n }\n`;\n\nexport const BUBBLE_SEGMENT_DIMMED_STYLES = {\n fill: 'rgba(150, 150, 150, 0.3)',\n stroke: 'rgba(200, 200, 200, 0.4)',\n} as const;\n\ninterface BubbleSvgProps {\n values: number[];\n valueRange: number[];\n tooltipHeader?: string;\n latitude: number;\n longitude: number;\n icon?: string;\n isPie: boolean;\n themeColor: string;\n segmentStartIndex: number;\n colors: string[];\n bubbleSize: Required<TooltipProps['additionalFields'][number] & { value: number }>[];\n onClick: (e: React.UIEvent, name: string, count: number) => void;\n 'aria-describedby'?: string;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n setElementRef?: (index: number, element: Element | null) => void;\n hasEventHandlers?: boolean;\n}\n\nconst BubbleSvg = React.memo(\n ({\n values,\n valueRange,\n tooltipHeader,\n latitude,\n longitude,\n icon,\n isPie,\n themeColor,\n segmentStartIndex,\n colors,\n bubbleSize,\n onClick,\n 'aria-describedby': ariaDescribedBy,\n onKeyDown,\n onFocus,\n onBlur,\n setElementRef,\n hasEventHandlers,\n }: BubbleSvgProps) => {\n const featureFlagContext = React.useContext<FeatureFlagContextValue>(FeatureFlagContext);\n const isBubbleMapIconFlagEnabled = Boolean(featureFlagContext?.visualizations_enableBubbleMapIcon);\n\n const total = values.reduce((totalValue, v) => totalValue + v, 0);\n const radius = matchBubbleSize(valueRange, total);\n\n const getAriaLabel = React.useCallback(\n (segmentName?: string, segmentValue?: number) => {\n let segmentLabel = _('Map marker');\n if (tooltipHeader) {\n segmentLabel = tooltipHeader;\n } else if (latitude !== undefined && longitude !== undefined) {\n segmentLabel = sprintf(_('Location: %(lat)s, %(lng)s'), {\n lat: convertDegToDMS(latitude, 'latitude'),\n lng: convertDegToDMS(longitude, 'longitude'),\n });\n }\n\n if (segmentName != null && segmentValue != null) {\n segmentLabel = sprintf(_('%(locationLabel)s, %(segmentName)s: %(segmentValue)s'), {\n locationLabel: segmentLabel,\n segmentName,\n segmentValue: segmentValue.toString(),\n });\n }\n if (hasEventHandlers) {\n segmentLabel = sprintf(_('%(label)s, Click for drilldown'), { label: segmentLabel });\n }\n\n return segmentLabel;\n },\n [tooltipHeader, latitude, longitude, hasEventHandlers]\n );\n\n const offsets: number[] = [];\n let runningTotal = 0;\n values.forEach(count => {\n offsets.push(runningTotal);\n runningTotal += count;\n });\n\n const width = radius * 2;\n const showIcon =\n isBubbleMapIconFlagEnabled &&\n radius >= ICON_DISPLAY_CUTOFF &&\n icon &&\n (isRemoteIcon(icon) || isDataURI(icon));\n\n return (\n <svg width={width} height={width} viewBox={`-3 -3 ${width + 6} ${width + 6}`}>\n {isPie && (\n <circle\n cx={radius}\n cy={radius}\n r={radius}\n fill=\"none\"\n strokeWidth={2}\n stroke={themeColor}\n strokeOpacity={0.3}\n />\n )}\n {values.map((v, i) => {\n const globalIndex = segmentStartIndex + i;\n return (\n <PieSegment\n key={globalIndex}\n start={offsets[i] / total}\n end={(offsets[i] + v) / total}\n radius={radius}\n color={colors[i]}\n themeColor={themeColor}\n segmentMetadata={bubbleSize[i]}\n handleBubbleClick={onClick}\n ariaLabel={getAriaLabel(bubbleSize[i]?.name, bubbleSize[i]?.value)}\n aria-describedby={ariaDescribedBy}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n elementRef={\n setElementRef ? element => setElementRef(globalIndex, element) : undefined\n }\n hasEventHandlers={hasEventHandlers}\n />\n );\n })}\n {showIcon && (\n <foreignObject\n x={radius - (radius * 0.8) / 2}\n y={radius - (radius * 0.8) / 2}\n width={radius * 0.8}\n height={radius * 0.8}\n style={{ pointerEvents: 'none' }}\n data-test=\"bubble-icon-wrapper\"\n >\n <RemoteIcon iconURL={icon} width={radius * 0.8} height={radius * 0.8} />\n </foreignObject>\n )}\n </svg>\n );\n }\n);\n\nexport interface BubbleProps {\n originalValues: number[];\n valueRange: number[];\n colors: string[];\n themeColor: string;\n isPie: boolean;\n latitude: number;\n longitude: number;\n bubbleSize: Required<TooltipProps['additionalFields'][number] & { value: number }>[];\n additionalFields?: TooltipProps['additionalFields'];\n tooltipHeader?: TooltipProps['tooltipHeader'];\n map: React.MutableRefObject<Map>;\n handleMapClick?: any;\n icon?: string;\n showCoordinates?: boolean;\n stylesManagedExternally?: boolean;\n segmentStartIndex?: number;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n setElementRef?: (index: number, element: Element) => void;\n hasEventHandlers?: boolean;\n}\n\nexport const Bubble = React.memo(\n ({\n originalValues,\n valueRange,\n colors,\n themeColor,\n isPie,\n latitude,\n longitude,\n bubbleSize,\n additionalFields = [],\n tooltipHeader = null,\n map,\n handleMapClick,\n icon,\n showCoordinates,\n stylesManagedExternally,\n segmentStartIndex = 0,\n onKeyDown,\n onFocus,\n onBlur,\n setElementRef,\n hasEventHandlers,\n }: BubbleProps): JSX.Element => {\n const onBubbleClick = React.useCallback(\n (e, name, value) => {\n handleMapClick(e, name, value);\n e.stopPropagation();\n },\n [handleMapClick]\n );\n\n // sanitize values\n const allZeros = originalValues.every(v => v === 0);\n const values = originalValues.map(v => Math.max(v, 0));\n\n if (allZeros || !originalValues.length) return null;\n\n return (\n <MarkerWrapper\n longitude={longitude}\n latitude={latitude}\n additionalFields={[...bubbleSize, ...additionalFields]}\n tooltipHeader={tooltipHeader}\n map={map}\n data-test-type=\"bubble\"\n showCoordinates={showCoordinates}\n stylesManagedExternally={stylesManagedExternally}\n >\n <BubbleSvg\n values={values}\n valueRange={valueRange}\n colors={colors}\n bubbleSize={bubbleSize}\n isPie={isPie}\n themeColor={themeColor}\n segmentStartIndex={segmentStartIndex}\n latitude={latitude}\n longitude={longitude}\n tooltipHeader={tooltipHeader}\n icon={icon}\n onClick={onBubbleClick}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n setElementRef={setElementRef}\n hasEventHandlers={hasEventHandlers}\n />\n </MarkerWrapper>\n );\n }\n);\nBubble.displayName = 'MapBubble';\n\nexport interface BubbleLayerProps {\n bubbleLayer: BubbleLayerType;\n themeColorScheme: string;\n zoom: number;\n map: React.MutableRefObject<Map>;\n onMapClick?: any;\n showCoordinates?: boolean;\n stylesManagedExternally?: boolean;\n hasEventHandlers?: boolean;\n}\n\nconst BubbleLayer = (props: BubbleLayerProps): JSX.Element => {\n const {\n bubbleLayer,\n themeColorScheme,\n map,\n zoom,\n onMapClick,\n showCoordinates,\n stylesManagedExternally = false,\n hasEventHandlers,\n } = props;\n\n bubbleLayer.seriesColors = bubbleLayer.seriesColors || DEFAULT_SERIES_COLORS;\n bubbleLayer.bubbleSize = bubbleLayer.bubbleSize || [];\n bubbleLayer.icon = bubbleLayer.icon || [];\n const bakedData = React.useMemo(() => bakeBubbleData(bubbleLayer), [bubbleLayer]);\n const staticColors = React.useMemo(\n () => getStaticColors(bubbleLayer.bubbleSize.length, bubbleLayer.seriesColors),\n [bubbleLayer.bubbleSize.length, bubbleLayer.seriesColors]\n );\n const { data = [], dataRange = [], resultLimit, bubbleSizeFields, isPie } = bakedData ?? {};\n const { additionalTooltipFields = [], tooltipHeaderFieldName = null } = bubbleLayer;\n const roundedZoom = Math.round(zoom);\n const themeColor = themeColorScheme === 'light' ? '#ffffff' : '#1a1c20';\n const dynamicColors = bubbleLayer.dataColors;\n\n // filter data for the current zoom level and sort base on values\n const dataToRender = React.useMemo(\n () =>\n data\n .reduce((acc, datum, i) => {\n const shouldRender =\n datum.zoom === null || datum.zoom === undefined || datum.zoom === roundedZoom;\n if (shouldRender) {\n acc.push({ data: datum, idx: i });\n }\n return acc;\n }, [])\n .slice(0, resultLimit || DEFAULT_RESULT_LIMIT)\n .sort((a, b) => sum(b.data.values) - sum(a.data.values)),\n [data, resultLimit, roundedZoom]\n );\n\n const handleMapClick = React.useCallback(\n (e, name, value, i) => {\n // retrieve metadata from the appropriate datum, indexed by i\n const metadata = dataToRender[i]?.data?.metadata ?? {};\n const payload = Object.keys(metadata).reduce(\n (acc, curr) => {\n const key = `row.${curr}.value`;\n const val = String(metadata[curr]);\n return { ...acc, [key]: val };\n },\n { name, value: String(value) }\n );\n\n onMapClick({ e, payload });\n },\n [dataToRender, onMapClick]\n );\n\n const { handleKeyDown, handleFocus, handleBlur, setElementRef } = useRovingTabindex(map);\n\n let globalSegmentIndex = 0;\n\n return (\n <>\n {dataToRender.map((datum, i) => {\n const allZeros = datum.data.values.every(v => v === 0);\n const segmentStartIndex = globalSegmentIndex;\n const segmentCount = datum.data.values.length;\n if (!allZeros) {\n globalSegmentIndex += segmentCount;\n }\n const colors = dynamicColors\n ? [\n dataToRender.map(obj =>\n isColor(dynamicColors[obj.idx]) ? dynamicColors[obj.idx] : DEFAULT_CLUSTER_COLOR\n )[i],\n ]\n : staticColors;\n\n const [longitude, latitude] = datum.data.coordinates;\n const bubbleSize = datum.data.values.map((value, index) => ({\n name: bubbleSizeFields[index],\n value,\n color: colors[index],\n }));\n\n const additionalFields = bubbleLayer.metadata\n ? additionalTooltipFields.map(field => ({\n name: field,\n value: datum.data.metadata[field],\n icon: bubbleLayer.tooltipFieldIcons?.[field],\n }))\n : [];\n\n const tooltipHeaderField =\n bubbleLayer.metadata && datum.data.metadata[tooltipHeaderFieldName];\n\n return (\n <Bubble\n key={String(datum.idx)}\n originalValues={datum.data.values}\n valueRange={dataRange}\n colors={colors}\n themeColor={themeColor}\n isPie={isPie}\n longitude={longitude}\n latitude={latitude}\n bubbleSize={bubbleSize}\n additionalFields={additionalFields}\n tooltipHeader={tooltipHeaderField}\n map={map}\n handleMapClick={(e, name, value) => handleMapClick(e, name, value, i)}\n icon={bubbleLayer.icon[datum.idx]}\n showCoordinates={showCoordinates}\n stylesManagedExternally={stylesManagedExternally}\n segmentStartIndex={segmentStartIndex}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n setElementRef={setElementRef}\n hasEventHandlers={hasEventHandlers}\n />\n );\n })}\n </>\n );\n};\n\nexport default BubbleLayer;\n"],
3
+ "sources": ["../../src/common/utils/mapUtils.ts", "esm-externals:@splunk/visualization-encoding/utils/types", "esm-externals:@splunk/visualization-encoding/utils/dsl", "esm-externals:@splunk/visualizations-shared/hocUtils", "esm-externals:@splunk/visualizations-shared/JSONSchemaUtils", "esm-externals:react", "esm-externals:styled-components", "esm-externals:lodash", "esm-externals:@splunk/visualizations-shared/iconUtils", "esm-externals:@splunk/visualizations-shared/colorUtils", "esm-externals:@splunk/visualizations-shared/RemoteIcon", "esm-externals:@splunk/visualization-context/FeatureFlagContext", "esm-externals:@splunk/ui-utils/i18n", "esm-externals:@splunk/ui-utils/format", "../../src/Map/PureMap/keyboardConstants.ts", "esm-externals:@splunk/react-ui/Popover", "esm-externals:@splunk/themes", "esm-externals:@splunk/ui-utils/id", "../../src/common/utils/shadowDomUtils.ts", "../../src/Map/PureMap/Tooltip.tsx", "esm-externals:d3-scale", "esm-externals:chroma-js", "esm-externals:@splunk/visualization-color-palettes", "esm-externals:@splunk/visualization-schemas", "../../src/Map/PureMap/MapUtils.ts", "esm-externals:maplibre-gl/dist/maplibre-gl.mjs", "../../src/Map/PureMap/MapContext.tsx", "../../src/Map/PureMap/MarkerWrapper.tsx", "../../src/Map/PureMap/BubbleLayer.tsx"],
4
+ "sourcesContent": ["import { isNumber } from '@splunk/visualization-encoding/utils/types';\nimport { getFieldsFromDSL } from '@splunk/visualization-encoding/utils/dsl';\nimport { deepMergeWithArrayPrimitiveOverrides } from '@splunk/visualizations-shared/hocUtils';\nimport { pickFieldFromJSONSchema } from '@splunk/visualizations-shared/JSONSchemaUtils';\nimport { GEO_LAT_AND_LONG_FIELD } from '../../Map/PureMap/BubbleLayer';\n\nexport const columnsNullToZeros = (config, dataSources, options) => {\n const { primary } = dataSources;\n const { columns, fields } = primary.data;\n let newColumns = columns;\n const mergedOptions = deepMergeWithArrayPrimitiveOverrides(\n {},\n options,\n pickFieldFromJSONSchema(config.optionsSchema, 'default')\n );\n if (mergedOptions.layers?.[0]?.type === 'bubble') {\n const latitudeField = getFieldsFromDSL(mergedOptions.layers[0].latitude, dataSources)[0] || '';\n const longitudeField = getFieldsFromDSL(mergedOptions.layers[0].longitude, dataSources)[0] || '';\n const stringsFields = getFieldsFromDSL(\"> primary | frameBySeriesTypes('string')\", dataSources);\n const excludedFields = new Set([\n latitudeField,\n longitudeField,\n 'geobin',\n 'name',\n ...stringsFields,\n ...GEO_LAT_AND_LONG_FIELD,\n ]);\n const indicesToEvaluate = new Set(\n fields.reduce((arr, e, i) => {\n const field = typeof e === 'string' ? e : e.name.toString();\n if (!excludedFields.has(field)) {\n arr.push(i);\n }\n return arr;\n }, [])\n );\n\n newColumns = columns.map((column, i) => {\n if (indicesToEvaluate.has(i)) {\n // sanitize value and convert string to numeric numbers\n return column.map(value => (!value || !isNumber(value) ? 0 : +value));\n }\n return column;\n });\n }\n\n const modifiedDatasources = {\n ...dataSources,\n primary: {\n ...primary,\n data: {\n ...primary.data,\n columns: newColumns,\n },\n },\n };\n\n return modifiedDatasources;\n};\n", "\nimport * as defaultImport from \"@splunk/visualization-encoding/utils/types\";\nexport * from \"@splunk/visualization-encoding/utils/types\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-encoding/utils/dsl\";\nexport * from \"@splunk/visualization-encoding/utils/dsl\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/hocUtils\";\nexport * from \"@splunk/visualizations-shared/hocUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/JSONSchemaUtils\";\nexport * from \"@splunk/visualizations-shared/JSONSchemaUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"react\";\nexport * from \"react\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"styled-components\";\nexport * from \"styled-components\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"lodash\";\nexport * from \"lodash\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/iconUtils\";\nexport * from \"@splunk/visualizations-shared/iconUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/colorUtils\";\nexport * from \"@splunk/visualizations-shared/colorUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/RemoteIcon\";\nexport * from \"@splunk/visualizations-shared/RemoteIcon\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-context/FeatureFlagContext\";\nexport * from \"@splunk/visualization-context/FeatureFlagContext\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/i18n\";\nexport * from \"@splunk/ui-utils/i18n\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/format\";\nexport * from \"@splunk/ui-utils/format\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "export const KEYBOARD_KEYS = {\n ARROW_RIGHT: 'ArrowRight',\n ARROW_LEFT: 'ArrowLeft',\n ARROW_UP: 'ArrowUp',\n ARROW_DOWN: 'ArrowDown',\n HOME: 'Home',\n END: 'End',\n ENTER: 'Enter',\n SPACE: ' ',\n} as const;\n", "\nimport * as defaultImport from \"@splunk/react-ui/Popover\";\nexport * from \"@splunk/react-ui/Popover\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/themes\";\nexport * from \"@splunk/themes\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/id\";\nexport * from \"@splunk/ui-utils/id\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "export const getFloatingLayerStyleTarget = (anchor?: HTMLElement | null): HTMLElement | undefined => {\n if (!anchor || typeof anchor.getRootNode !== 'function') {\n return undefined;\n }\n\n const rootNode = anchor.getRootNode();\n\n if (typeof ShadowRoot !== 'undefined' && rootNode instanceof ShadowRoot) {\n return anchor.ownerDocument.head;\n }\n\n return undefined;\n};\n", "import * as React from 'react';\nimport styled, { StyleSheetManager } from 'styled-components';\nimport Popover from '@splunk/react-ui/Popover';\nimport { isRemoteIcon, isDataURI } from '@splunk/visualizations-shared/iconUtils';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport FeatureFlagContext from '@splunk/visualization-context/FeatureFlagContext';\nimport RemoteIcon from '@splunk/visualizations-shared/RemoteIcon';\nimport { variables } from '@splunk/themes';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport { getFloatingLayerStyleTarget } from '../../common/utils/shadowDomUtils';\n\ntype FeatureFlagContextValue = Record<string, boolean | undefined> | null;\n\nconst StyledPopover = styled(Popover)`\n min-width: 250px;\n max-width: 332px;\n max-width: fit-content;\n font-size: 12px;\n`;\n\nconst StyledTable = styled.table`\n margin: 2px 6px 2px 6px;\n width: calc(100% - 12px);\n`;\n\nconst StyledTitleColumn = styled.td`\n opacity: 0.85;\n word-break: break-all;\n vertical-align: top;\n`;\n\nconst StyledValueColumn = styled.td`\n text-align: right;\n word-break: break-all;\n vertical-align: top;\n`;\n\nconst StyledColorBlock = styled.div`\n background-color: ${props => props.color};\n display: inline-block;\n margin-right: 4px;\n border-radius: 2px;\n width: 6px;\n height: 11px;\n transform: translateY(1px);\n`;\n\nconst StyledIconWrapper = styled.span`\n margin-left: 4px;\n display: inline-block;\n vertical-align: middle;\n`;\n\nconst StyledTooltipHeader = styled.thead`\n th {\n height: 16px;\n color: ${variables.contentColorActive};\n padding: 0;\n }\n\n span {\n display: block;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n width: 100%;\n }\n`;\n\nexport const convertDegToDMS = (decimalDegree: number, type: 'latitude' | 'longitude'): string => {\n const truncate = n => (n > 0 ? Math.floor(n) : Math.ceil(n));\n const absoluteDegree = Math.abs(decimalDegree);\n let degrees = truncate(absoluteDegree);\n let minutes = truncate((absoluteDegree - degrees) * 60);\n let seconds = Math.round((absoluteDegree - degrees - minutes / 60) * 3600);\n if (seconds === 60) {\n minutes += 1;\n seconds = 0;\n }\n if (minutes === 60) {\n degrees += 1;\n minutes = 0;\n }\n let direction: string;\n if (type === 'longitude') {\n direction = decimalDegree < 0 ? 'W' : 'E';\n } else if (type === 'latitude') {\n direction = decimalDegree < 0 ? 'S' : 'N';\n }\n return `${degrees}\u00B0 ${minutes}' ${seconds}\" ${direction}`;\n};\n\nexport interface TooltipProps {\n id?: string;\n open?: boolean;\n anchor?: HTMLElement;\n latitude?: number;\n longitude?: number;\n areaId?: string;\n areaValue?: number;\n additionalFields?: Array<{ name: string; value: number | string; color?: string; icon?: string }>;\n showCoordinates?: boolean;\n tooltipHeader?: string;\n stylesManagedExternally?: boolean;\n onMouseEnter?: (e: React.MouseEvent) => void;\n onMouseLeave?: (e: React.MouseEvent) => void;\n}\n// only want latitude/longitude for marker and bubble\n// omit for choropleth, and put areaid, areavalue instead\nconst Tooltip = ({\n id,\n open,\n anchor,\n latitude,\n longitude,\n areaId,\n areaValue,\n additionalFields = [],\n showCoordinates = true,\n tooltipHeader = null,\n stylesManagedExternally = false,\n onMouseEnter,\n onMouseLeave,\n}: TooltipProps): JSX.Element => {\n const featureFlagContext = React.useContext<FeatureFlagContextValue>(FeatureFlagContext);\n const isTooltipIconFlagEnabled = Boolean(featureFlagContext?.visualizations_enableTooltipIcon);\n const styleTarget = stylesManagedExternally ? undefined : getFloatingLayerStyleTarget(anchor);\n\n const popover = (\n <StyledPopover\n id={id}\n role=\"tooltip\"\n open={open}\n animation={false}\n anchor={anchor}\n data-test=\"map-marker-tooltip\"\n defaultPlacement=\"above\"\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n >\n <StyledTable>\n {tooltipHeader && (\n <StyledTooltipHeader data-test=\"tooltip-header\">\n <tr>\n <th colSpan={2}>\n <span data-test=\"tooltip-header-value\">{tooltipHeader}</span>\n </th>\n </tr>\n </StyledTooltipHeader>\n )}\n <tbody>\n {Boolean(areaId && areaValue) && (\n <tr>\n <StyledTitleColumn data-test=\"area-id\">{areaId}</StyledTitleColumn>\n <StyledValueColumn data-test=\"area-value\">{areaValue}</StyledValueColumn>\n </tr>\n )}\n {Boolean(showCoordinates && latitude) && (\n <tr>\n <StyledTitleColumn>{_('Latitude')}</StyledTitleColumn>\n <StyledValueColumn data-test=\"latitude\">\n {convertDegToDMS(latitude, 'latitude')}\n </StyledValueColumn>\n </tr>\n )}\n {Boolean(showCoordinates && longitude) && (\n <tr>\n <StyledTitleColumn>{_('Longitude')}</StyledTitleColumn>\n <StyledValueColumn data-test=\"longitude\">\n {convertDegToDMS(longitude, 'longitude')}\n </StyledValueColumn>\n </tr>\n )}\n {additionalFields\n .filter(({ value }) => value && String(value) !== '0')\n .map(({ name, value, color, icon }) => (\n <tr key={createDOMID()}>\n <StyledTitleColumn data-test=\"field-title\">\n {color ? (\n <StyledColorBlock data-test=\"field-color\" color={color} />\n ) : null}\n <span>\n {name}\n {isTooltipIconFlagEnabled &&\n icon &&\n (isRemoteIcon(icon) || isDataURI(icon)) ? (\n <StyledIconWrapper data-test=\"field-icon\">\n <RemoteIcon iconURL={icon} width={16} height={16} />\n </StyledIconWrapper>\n ) : null}\n </span>\n </StyledTitleColumn>\n <StyledValueColumn data-test=\"field-value\">{value}</StyledValueColumn>\n </tr>\n ))}\n </tbody>\n </StyledTable>\n </StyledPopover>\n );\n\n return styleTarget ? <StyleSheetManager target={styleTarget}>{popover}</StyleSheetManager> : popover;\n};\n\nexport default Tooltip;\n", "\nimport * as defaultImport from \"d3-scale\";\nexport * from \"d3-scale\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"chroma-js\";\nexport * from \"chroma-js\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-color-palettes\";\nexport * from \"@splunk/visualization-color-palettes\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualization-schemas\";\nexport * from \"@splunk/visualization-schemas\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "import { forEach, sum, isNumber, min as lodashMin, max as lodashMax, get, isEqual, isObject } from 'lodash';\nimport { LngLatBoundsLike } from 'maplibre-gl';\nimport { scalePow } from 'd3-scale';\nimport chroma from 'chroma-js';\nimport type { MapContextInterface, BaseTileConfig } from '@splunk/visualization-context/MapContext';\nimport { isColor } from '@splunk/visualizations-shared/colorUtils';\nimport { VIZ_CATEGORICAL } from '@splunk/visualization-color-palettes';\nimport { isNumber as isNumberUtil } from '@splunk/visualization-encoding/utils/types';\nimport type { GeoJsonDataType } from '@splunk/visualizations-shared/mapUtils';\nimport { LAYER_TYPE } from '@splunk/visualization-schemas';\n\nexport const MAX_LATITUDE = 90;\nexport const MIN_LATITUDE = -90;\nexport const MAX_LONGITUDE = 180;\nexport const MIN_LONGITUDE = -180;\nexport const DEFAULT_RESULT_LIMIT = 1000;\nexport const DEFAULT_CLUSTER_COLOR = '#909090';\nexport const DEFAULT_SERIES_COLORS = VIZ_CATEGORICAL;\n// MapLibre requires a map style specification number which is always 8\nexport const MAP_STYLE_VERSION_NUMBER = 8;\n// currently using one [min, max] value set for bubbles across all zoom levels\nexport const MIN_BUBBLE_RADIUS = 7.11; // 10px\nexport const MAX_BUBBLE_RADIUS = 45.26; // 85px\nexport const DEFAULT_OPACITY = 0.8;\nconst LONGITUDE = 'longitude';\nconst LATITUDE = 'latitude';\nexport type MaybeBaseTileConfig = BaseTileConfig | Record<string, never>;\ninterface GenericLayerType {\n type: string;\n latitude: number[];\n longitude: number[];\n dataColors?: string[] | '';\n seriesColors: string[];\n additionalTooltipFields?: string[];\n tooltipHeaderField?: string[];\n resultLimit: number;\n metadata?: Array<{ [key: string]: number | string }>;\n}\n\nexport interface MarkerLayerType extends GenericLayerType {\n type: LAYER_TYPE.Marker;\n}\n\nexport interface BubbleLayerType extends GenericLayerType {\n type: LAYER_TYPE.Bubble;\n bubbleSize?: number[][] | number[];\n bubbleSizeFields: string[];\n dataValuesField?: string;\n tooltipHeaderFieldName?: string;\n geobin?: string[];\n icon?: string[];\n tooltipFieldIcons?: string;\n}\n\ninterface BubbleLayerDatumType {\n zoom?: number | null;\n values: number[];\n sanitizedValues: number[];\n coordinates: number[];\n}\n\nexport interface BubbleLayerDataType {\n data: BubbleLayerDatumType[];\n dataRange: number[];\n isPie: boolean;\n resultLimit: number;\n bubbleSizeFields: string[];\n}\n\nexport interface ChoroplethLayerType {\n type: LAYER_TYPE.Choropleth;\n areaIds: string[];\n areaValues: number[];\n dataColors: string[];\n additionalTooltipFields?: string[];\n tooltipHeaderField?: string[];\n geom?: GeoJsonDataType[] | null;\n resultLimit?: number;\n metadata?: Array<{ [key: string]: number | string | GeoJsonDataType }>;\n source?: string;\n width?: string | number;\n height?: string | number;\n choroplethEmptyAreaColor?: string;\n choroplethStrokeColor?: string;\n choroplethOpacity?: number;\n}\n\nexport interface MapLayerClickPayloadType {\n name?: string;\n value?: string | number;\n /* cell values of all cells of clicked row with the field and value - in shape row.<field>.value */\n [key: string]: string | number;\n}\n\nexport type ClusterLayerType = BubbleLayerType | MarkerLayerType;\nexport type LayerType = ClusterLayerType | ChoroplethLayerType;\n/**\n * Construct a tile preset {key: config} by combining the default + custom tile configs\n * Also returns the default tile config for each theme - light/dark\n * @param {MapContextInterface} args\n * @param {BaseTileConfig[]} args.defaultTileConfig\n * @param {BaseTileConfig[]} args.customTileConfig\n * @returns {Object} tile preset\n */\nexport const getTilePreset = ({\n defaultTileConfig = [],\n customTileConfig = [],\n}: MapContextInterface): {\n tilePreset: Record<string, BaseTileConfig>;\n defaultTileLight: MaybeBaseTileConfig;\n defaultTileDark: MaybeBaseTileConfig;\n} => {\n const tilePreset: Record<string, BaseTileConfig> = {};\n let defaultTileLight: MaybeBaseTileConfig = {};\n let defaultTileDark: MaybeBaseTileConfig = {};\n const tileConfigs = [...defaultTileConfig, ...customTileConfig];\n forEach(tileConfigs, tileConfig => {\n const key = tileConfig?.key;\n if (!key) {\n return;\n }\n const updatedConfig: BaseTileConfig = {\n ...tileConfig,\n version: MAP_STYLE_VERSION_NUMBER,\n };\n tilePreset[key] = updatedConfig;\n });\n\n if (defaultTileConfig.length > 0) {\n defaultTileLight =\n defaultTileConfig.find(config => config.theme === 'light') ??\n defaultTileConfig.find(config => config.theme === undefined) ??\n {};\n defaultTileDark =\n defaultTileConfig.find(config => config.theme === 'dark') ??\n defaultTileConfig.find(config => config.theme === undefined) ??\n {};\n }\n\n return { tilePreset, defaultTileLight, defaultTileDark };\n};\n\n/**\n * Check if baseLayerTileServer is in tilePreset and config matches current theme, if yes, return.\n * If no, construct a mapStyle with baseLayerTilerServer and baseLayerTileServerType\n * Else return default tile config based on current theme\n * @param {Object} args\n * @param {BaseTileConfig[]} args.tilePreset\n * @param {String} args.baseLayerTilerServer\n * @param {String} args.baseLayerTileServerType\n * @param {String} args.colorScheme\n * @param {BaseTileConfig} args.defaultTileDark\n * @param {BaseTileConfig} args.defaultTileLight\n * @returns {BaseTileConfig} mapStyle\n */\nexport const getMapStyle = ({\n showBaseLayer,\n baseLayerTileServer = '',\n baseLayerTileServerType = '',\n tilePreset = {},\n colorScheme = 'light',\n defaultTileLight = {},\n defaultTileDark = {},\n}: {\n showBaseLayer: boolean;\n baseLayerTileServer?: string;\n baseLayerTileServerType?: string;\n tilePreset?: Record<string, BaseTileConfig>;\n colorScheme?: string;\n defaultTileLight?: MaybeBaseTileConfig;\n defaultTileDark?: MaybeBaseTileConfig;\n}): MaybeBaseTileConfig => {\n if (!showBaseLayer) {\n return {\n name: 'empty-base-layer',\n key: 'empty-base-layer',\n version: MAP_STYLE_VERSION_NUMBER,\n sources: {\n 'base-tiles': {\n type: 'raster',\n tiles: [\n 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=',\n ],\n tileSize: 256,\n },\n },\n layers: [\n {\n id: 'base-layer',\n type: 'raster',\n source: 'base-tiles',\n minzoom: 0,\n maxzoom: 22,\n },\n ],\n };\n }\n\n if (\n baseLayerTileServer &&\n tilePreset[baseLayerTileServer] &&\n (!tilePreset[baseLayerTileServer].theme || tilePreset[baseLayerTileServer].theme === colorScheme)\n ) {\n return tilePreset[baseLayerTileServer];\n }\n\n if (baseLayerTileServer && baseLayerTileServerType) {\n let tiles: string[] = [];\n /**\n * Tile Server URLs (eg: http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png) can specify the variable {s} which refers to a subdomain\n * Subdomains are used to help with browser parallel requests per domain limitation. These subdomains are typically single letters 'a', 'b' and 'c'\n * Refer to https://leafletjs.com/SlavaUkraini/reference.html#tilelayer and https://wiki.openstreetmap.org/wiki/Tile_servers\n */\n if (/^(https?):\\/\\/{[sS]}\\./.exec(baseLayerTileServer)) {\n /**\n * sXML (Leaflet) allows users to define their own tile server URLs + list of available subdomains\n * In order to preserve this behavior during conversion to splunk.map,\n * if the variable {s} or {S} is detected, replace it with 'a', 'b' and 'c' - default values for subdomains\n */\n tiles = [\n baseLayerTileServer.replace(/{[sS]}/, 'a'),\n baseLayerTileServer.replace(/{[sS]}/, 'b'),\n baseLayerTileServer.replace(/{[sS]}/, 'c'),\n ];\n } else {\n tiles = [baseLayerTileServer];\n }\n const mapStyle: BaseTileConfig = {\n name: baseLayerTileServer,\n key: baseLayerTileServer,\n version: MAP_STYLE_VERSION_NUMBER,\n sources: {\n 'base-tiles': {\n type: baseLayerTileServerType,\n tiles,\n tileSize: 256,\n },\n },\n layers: [\n {\n id: 'base-layer',\n type: 'raster',\n source: 'base-tiles',\n minzoom: 0,\n maxzoom: 24, // https://maplibre.org/maplibre-gl-js-docs/api/map/\n },\n ],\n };\n return mapStyle;\n }\n\n // if tile server is not present in the preset AND we can't construct a mapStyle, fall back on defaults\n return colorScheme === 'light' ? defaultTileLight : defaultTileDark;\n};\n\nexport interface ZoomConstraints {\n minZoom: number;\n maxZoom: number;\n}\n\nexport const getZoomConstraintsFromTileConfig = (\n tileConfig: BaseTileConfig,\n baseLayerTileServer?: string\n): ZoomConstraints => {\n const { sources, layers } = tileConfig;\n let matchedBaseLayerTileServer = false;\n // check sources for minzoom maxzoom first\n const sourceKeys = Object.keys(sources);\n for (const key of sourceKeys) {\n const source = sources[key] as { [key: string]: unknown };\n const { minzoom, maxzoom } = source;\n const tiles = Array.isArray(source?.tiles) ? (source.tiles as string[]) : [];\n if (baseLayerTileServer && tiles.includes(baseLayerTileServer)) {\n matchedBaseLayerTileServer = true;\n }\n if (\n ((baseLayerTileServer && matchedBaseLayerTileServer) || !baseLayerTileServer) &&\n isNumber(minzoom) &&\n isNumber(maxzoom)\n ) {\n return {\n minZoom: minzoom,\n maxZoom: maxzoom,\n };\n }\n }\n // then check layers\n for (const layer of layers) {\n const { minzoom, maxzoom } = layer;\n if (\n ((baseLayerTileServer && matchedBaseLayerTileServer) || !baseLayerTileServer) &&\n isNumber(minzoom) &&\n isNumber(maxzoom)\n ) {\n return {\n minZoom: minzoom,\n maxZoom: maxzoom,\n };\n }\n }\n // Maplibre default - would reset previous min/maxZoom https://maplibre.org/maplibre-gl-js-docs/api/map/\n return {\n minZoom: 0,\n maxZoom: 24,\n };\n};\n\nexport const isBaseTileConfig = (config: MaybeBaseTileConfig): config is BaseTileConfig =>\n Boolean(config && 'name' in config && 'key' in config && 'sources' in config && 'layers' in config);\n\nexport const getZoomLevelFromGeobin = (geobinStr?: string | null): number | null => {\n if (!geobinStr) {\n return null;\n }\n // geostats cmds return geobin with zoom level 0-18, 0-99 in the geobinPattern covers the range\n const geobinPattern = /bin_id_zl_(\\d{1,2})_y_/g;\n const match = geobinPattern.exec(geobinStr);\n return (match?.length && Number.parseInt(match[1], 10)) ?? null;\n};\n\n// Bubble colors - static\nexport const getStaticColors = (colorCount: number, colorArray: string[]): string[] => {\n if (colorCount < 0 || !colorCount) {\n return [DEFAULT_CLUSTER_COLOR];\n }\n if (!colorArray?.length) {\n return [...new Array(colorCount).keys()].map(i => DEFAULT_SERIES_COLORS[i]);\n }\n // loop through colorArray to pick the first $colorCount colors\n // start from begining again if colorCount > colorArray.length\n return [...new Array(colorCount).keys()].map(i =>\n isColor(colorArray[i % colorArray.length]) ? colorArray[i % colorArray.length] : DEFAULT_CLUSTER_COLOR\n );\n};\n\n// Bubble size\nexport const matchBubbleSize = (dataRange: number[], data: number): any => {\n const size = scalePow().exponent(0.2).domain(dataRange).range([MIN_BUBBLE_RADIUS, MAX_BUBBLE_RADIUS])(\n data\n );\n\n if (size > MAX_BUBBLE_RADIUS) {\n return MAX_BUBBLE_RADIUS;\n }\n if (size < MIN_BUBBLE_RADIUS) {\n return MIN_BUBBLE_RADIUS;\n }\n return size;\n};\n\nexport const transposeArray = (array: number[][]): number[][] => {\n if (!array?.length || !array[0]?.length) {\n return [];\n }\n return array[0].map((_, i) => array.map(row => row[i]));\n};\n\n// sanitize values: update all null, undefined, or negative values to 0\nexport const sanitizeValues = (values: number[] | number[][]) => {\n // null / undefined\n if (!values) {\n return 0;\n }\n // number\n if (!Array.isArray(values)) {\n return Math.max(values, 0);\n }\n // array\n return values.map(arr => sanitizeValues(arr));\n};\n\n// eslint-disable-next-line consistent-return\nexport const sortByValuesField = (bubbleLayer: BubbleLayerType) => {\n const { bubbleSizeFields, dataValuesField } = bubbleLayer;\n\n // Find the index of dataValuesField in fields\n const index = bubbleSizeFields.indexOf(dataValuesField);\n if (index === -1) return bubbleLayer; // If not found, return as is\n\n // Move dataValuesField and corresponding sizes to the first position\n bubbleLayer.bubbleSizeFields.unshift(bubbleLayer.bubbleSizeFields.splice(index, 1)[0]);\n bubbleLayer.bubbleSize.unshift(bubbleLayer.bubbleSize.splice(index, 1)[0] as number & number[]);\n};\n\nexport const bakeBubbleData = (layer: BubbleLayerType): BubbleLayerDataType => {\n if (!layer?.bubbleSize?.length || !layer?.latitude?.length || !layer?.longitude?.length) {\n return null;\n }\n const hasGeobinData = Array.isArray(layer.geobin) && layer.geobin.length > 0;\n // if bubbleSize is passed as an array of single number array (data series)\n // e.g. [value0, value1, ...]\n // format each value as an array to unify data operations for data series and frames\n const sanitizedBubbleSize = sanitizeValues(layer.bubbleSize);\n let transposedBubbleSize: number[][];\n let transposedSanitizedBubbleSize: number[][];\n let isPie = false;\n // format array if bubbleSize is passed as an array of array (data frame)\n if (Array.isArray(layer.bubbleSize[0])) {\n // one-time array transpose,\n // e.g. from [column0data, column0data] (multi series)\n // to [[column0datum0, column1datum0], [column0datum1, column1data1], ...]\n // or e.g. from [column0data] (single series)\n // to [[column0data]]\n // for easy access of values at each geo location,\n // and min max pie size computation\n transposedBubbleSize = transposeArray(layer.bubbleSize as number[][]);\n transposedSanitizedBubbleSize = transposeArray(sanitizedBubbleSize);\n // if multiple series in the dataframe, set isPie to true\n if (layer.bubbleSize.length > 1) {\n isPie = true;\n // when dynamic coloring is enabled,\n // set the configured dataValues field as the first field\n // to apply dynamic colors only to the first pie slice.\n if (layer.dataValuesField && !!layer.dataColors) {\n sortByValuesField(layer); // here\n }\n }\n } else {\n transposedBubbleSize = layer.bubbleSize.map(n => [n]);\n transposedSanitizedBubbleSize = sanitizedBubbleSize.map(n => [n]);\n }\n if (!transposedBubbleSize?.length) {\n return null;\n }\n const data = layer.latitude\n .map((lat, i) => ({\n zoom: hasGeobinData ? getZoomLevelFromGeobin(layer.geobin[i]) : null,\n values: transposedBubbleSize[i],\n sanitizedValues: transposedSanitizedBubbleSize[i],\n coordinates: [layer.longitude[i], lat],\n metadata: layer.metadata ? layer.metadata[i] : {},\n }))\n .filter(d => Boolean(d.values));\n\n // compute the min/max value to encode min/max pie or bubble size\n let min = sum(transposedSanitizedBubbleSize[0]);\n let max = min;\n transposedSanitizedBubbleSize.forEach(row => {\n const bubbleSize = sum(row);\n max = Math.max(bubbleSize, max);\n min = Math.min(bubbleSize, min);\n });\n return {\n data,\n dataRange: [min, max],\n isPie,\n resultLimit: layer.resultLimit,\n bubbleSizeFields: layer.bubbleSizeFields,\n };\n};\n\nexport const isValidLatLon = (latlon: Array<number | string>): boolean => {\n if (!latlon || !Array.isArray(latlon) || latlon.length !== 2) {\n return false;\n }\n const [lat, lon] = latlon;\n if (!isNumberUtil(lat) || !(Number(lat) >= MIN_LATITUDE && Number(lat) <= MAX_LATITUDE)) {\n return false;\n }\n if (!isNumberUtil(lon) || !(Number(lon) >= MIN_LONGITUDE && Number(lon) <= MAX_LONGITUDE)) {\n return false;\n }\n return true;\n};\n\nexport const getChoroplethValues = (field: string, choroplethLayer: ChoroplethLayerType): number[] => {\n if (!Array.isArray(choroplethLayer.geom) || choroplethLayer.geom.length === 0) {\n return [];\n }\n const limit = choroplethLayer.resultLimit ?? DEFAULT_RESULT_LIMIT;\n const slicedGeomList = choroplethLayer.geom.slice(0, limit);\n const flatCoordinates = slicedGeomList.flatMap(geomObject => {\n if (!geomObject) {\n return [];\n }\n if (geomObject.type === 'MultiPolygon') {\n return geomObject.coordinates.flat(2);\n }\n if (geomObject.type === 'Polygon') {\n return geomObject.coordinates.flat();\n }\n return [];\n });\n return flatCoordinates.map(coord => coord[field === LONGITUDE ? 0 : 1]);\n};\n\n/**\n * Returns a list of all lat or lon coordinates used in a specified layer\n * @param {LayerType[]} layer\n * @param {string} field\n * @returns {number[]} list of lat coordinates or lon coordinates\n */\nconst getLatOrLonCoordinates = (layer: LayerType, field: string): number[] => {\n const getClusterValues = (clusterLayer: ClusterLayerType): number[] =>\n get(clusterLayer, field, []).slice(\n 0,\n clusterLayer.type === LAYER_TYPE.Marker && clusterLayer.resultLimit\n ? clusterLayer.resultLimit\n : DEFAULT_RESULT_LIMIT\n );\n return layer.type === LAYER_TYPE.Choropleth ? getChoroplethValues(field, layer) : getClusterValues(layer);\n};\n\n/**\n * Returns the min and max LongLat pairs to determine the layer boundaries to fit all markers/bubbles\n * @param {LayerType[]} layers\n * @returns {LngLatBoundsLike}\n */\nexport const getGlobalLayerBoundaries = (layers: LayerType[]): LngLatBoundsLike => {\n const isLayerValid = (field: string): boolean =>\n layers.every(layer => layer[field] || (layer as ChoroplethLayerType).geom);\n const getDefaultMax = (field: string) => (field === LONGITUDE ? MAX_LONGITUDE : MAX_LATITUDE);\n const getDefaultMin = (field: string) => (field === LONGITUDE ? MIN_LONGITUDE : MIN_LATITUDE);\n\n if (!layers || !Array.isArray(layers) || !layers.length) {\n return null;\n }\n\n const getMin = (field: string): number => {\n if (!isLayerValid(field)) {\n return getDefaultMin(field);\n }\n return layers.reduce((prevVal, layer) => {\n const coordinatesNumArr = getLatOrLonCoordinates(layer, field).map(x => +x);\n return lodashMin([prevVal, ...coordinatesNumArr]);\n }, getDefaultMax(field));\n };\n\n const getMax = (field: string): number => {\n if (!isLayerValid(field)) {\n return getDefaultMax(field);\n }\n return layers.reduce((prevVal, layer) => {\n const coordinatesNumArr = getLatOrLonCoordinates(layer, field).map(Number);\n return lodashMax([prevVal, ...coordinatesNumArr]);\n }, getDefaultMin(field));\n };\n\n return [\n [getMin(LONGITUDE), getMin(LATITUDE)],\n [getMax(LONGITUDE), getMax(LATITUDE)],\n ];\n};\n\nexport const formatTooltipFieldValue = (value: unknown): string | number => {\n if (value === null || value === undefined) {\n return '';\n }\n if (typeof value === 'string' || typeof value === 'number') {\n return value;\n }\n return JSON.stringify(value);\n};\n\nexport const getScaledOpacities = (colors: string[], cfgOpacity: number): number[] => {\n // extract opacity information from 8 digit hex codes\n const opacities = colors?.map(color => (color?.length === 9 ? (chroma(color).alpha() ?? 1) : 1));\n // opacity cannot be greater than configured opacity\n return opacities?.map(opacity => opacity * cfgOpacity);\n};\n\nexport const compareBaseStyles = (curr, next): boolean => {\n const currBaseLayer = curr?.layers?.find(layer => layer?.id === 'base-layer');\n const nextBaseLayer = next?.layers?.find(layer => layer?.id === 'base-layer');\n const currBaseSource = get(curr?.sources, (currBaseLayer?.source as string) ?? '');\n const nextBaseSource = get(next?.sources, (nextBaseLayer?.source as string) ?? '');\n\n if (!currBaseLayer || !nextBaseLayer || !currBaseSource || !nextBaseSource) {\n return false;\n }\n\n return isEqual(currBaseLayer, nextBaseLayer) && isEqual(currBaseSource, nextBaseSource);\n};\n\nexport const formatMetadata = (\n choroplethLayer: ChoroplethLayerType,\n i: number\n): { [key: string]: string } => {\n if (!choroplethLayer?.areaIds || !choroplethLayer?.areaValues) return {};\n if (i >= choroplethLayer.areaIds.length) return {};\n\n const metadata = choroplethLayer.metadata ? choroplethLayer.metadata[i] : {};\n const name = choroplethLayer.areaIds[i];\n const value = choroplethLayer.areaValues[i];\n const base = { name, value: String(value) };\n\n return Object.keys(metadata).reduce((result, curr) => {\n const key = `row.${curr}.value`;\n const val = isObject(metadata[curr]) ? JSON.stringify(metadata[curr]) : String(metadata[curr]);\n return { ...result, [key]: val };\n }, base);\n};\n", "\nimport * as defaultImport from \"maplibre-gl/dist/maplibre-gl.mjs\";\nexport * from \"maplibre-gl/dist/maplibre-gl.mjs\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "import * as React from 'react';\n\ninterface MapContextValue {\n activeTooltipId: string | null;\n setActiveTooltipId: (id: string | null | ((prev: string | null) => string | null)) => void;\n activeChoroplethId: string | null;\n setActiveChoroplethId: (id: string | null) => void;\n}\n\nconst MapContext = React.createContext<MapContextValue>({\n activeTooltipId: null,\n setActiveTooltipId: () => {},\n activeChoroplethId: null,\n setActiveChoroplethId: () => {},\n});\n\nexport const MapProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {\n const [activeTooltipId, setActiveTooltipId] = React.useState<string | null>(null);\n const [activeChoroplethId, setActiveChoroplethId] = React.useState<string | null>(null);\n\n const value = React.useMemo(\n () => ({\n activeTooltipId,\n setActiveTooltipId,\n activeChoroplethId,\n setActiveChoroplethId,\n }),\n [activeTooltipId, activeChoroplethId]\n );\n\n return <MapContext.Provider value={value}>{children}</MapContext.Provider>;\n};\n\nexport const useMapContext = () => React.useContext(MapContext);\n", "import type { Map } from 'maplibre-gl';\nimport { Marker } from 'maplibre-gl';\nimport * as React from 'react';\nimport { createDOMID } from '@splunk/ui-utils/id';\nimport Tooltip from './Tooltip';\nimport type { TooltipProps } from './Tooltip';\nimport { useMapContext } from './MapContext';\n\nexport interface MarkerWrapperProps extends React.HTMLAttributes<HTMLDivElement> {\n latitude: number;\n longitude: number;\n areaId?: string;\n areaValue?: number;\n additionalFields?: TooltipProps['additionalFields'];\n tooltipHeader?: TooltipProps['tooltipHeader'];\n map: React.MutableRefObject<Map>;\n showCoordinates?: boolean;\n stylesManagedExternally?: boolean;\n customMarkerId?: string;\n}\n\nconst MarkerWrapper = ({\n longitude,\n latitude,\n areaId,\n areaValue,\n additionalFields = [],\n tooltipHeader = null,\n map,\n children,\n showCoordinates = true,\n stylesManagedExternally = false,\n customMarkerId,\n ...otherProps\n}: MarkerWrapperProps): JSX.Element => {\n const container = React.useRef<HTMLDivElement>();\n const marker = React.useRef<Marker>();\n const [isTooltipOpen, setTooltipOpenStatus] = React.useState(false);\n const [isFocused, setIsFocused] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n const [isPopoverHovered, setIsPopoverHovered] = React.useState(false);\n const tooltipId = React.useMemo(() => createDOMID(), []);\n const pendingMoveEndHandler = React.useRef<(() => void) | null>(null);\n const closeTimeoutRef = React.useRef<NodeJS.Timeout | null>(null);\n const generatedMarkerId = React.useMemo(() => createDOMID(), []);\n const markerId = customMarkerId || generatedMarkerId;\n const { activeTooltipId, setActiveTooltipId } = useMapContext();\n const mapMoveHandlerRef = React.useRef<(() => void) | null>(null);\n\n const openTooltip = React.useCallback(() => {\n setActiveTooltipId(markerId);\n setTooltipOpenStatus(true);\n }, [markerId, setActiveTooltipId]);\n\n const cleanupPendingMoveEnd = React.useCallback(() => {\n if (pendingMoveEndHandler.current && map.current && typeof map.current.off === 'function') {\n map.current.off('moveend', pendingMoveEndHandler.current);\n pendingMoveEndHandler.current = null;\n }\n }, [map]);\n\n const cleanupMapMoveHandler = React.useCallback(() => {\n if (mapMoveHandlerRef.current && map.current && typeof map.current.off === 'function') {\n map.current.off('move', mapMoveHandlerRef.current);\n mapMoveHandlerRef.current = null;\n }\n }, [map]);\n\n // Consolidated close logic: only close if nothing is keeping tooltip open\n const shouldCloseTooltip = React.useCallback(\n (focused: boolean, hovered: boolean, popoverHovered: boolean) => {\n return !focused && !hovered && !popoverHovered;\n },\n []\n );\n\n const cancelCloseTimeout = React.useCallback(() => {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n }, []);\n\n const closeTooltipIfShould = React.useCallback(\n (focused: boolean, hovered: boolean, popoverHovered: boolean) => {\n cancelCloseTimeout();\n\n if (shouldCloseTooltip(focused, hovered, popoverHovered)) {\n // Small delay to allow mouse to reach tooltip\n closeTimeoutRef.current = setTimeout(() => {\n setTooltipOpenStatus(false);\n setActiveTooltipId(currentId => (currentId === markerId ? null : currentId));\n closeTimeoutRef.current = null;\n }, 100);\n }\n },\n [shouldCloseTooltip, markerId, setActiveTooltipId, cancelCloseTimeout]\n );\n\n const handleMouseEnter = React.useCallback(() => {\n cancelCloseTimeout();\n setIsHovered(true);\n openTooltip();\n }, [openTooltip, cancelCloseTimeout]);\n\n const handleMouseLeave = React.useCallback(() => {\n setIsHovered(false);\n closeTooltipIfShould(isFocused, false, isPopoverHovered);\n }, [isFocused, isPopoverHovered, closeTooltipIfShould]);\n\n const handlePopoverMouseEnter = React.useCallback(() => {\n cancelCloseTimeout();\n setIsPopoverHovered(true);\n }, [cancelCloseTimeout]);\n\n const handlePopoverMouseLeave = React.useCallback(() => {\n setIsPopoverHovered(false);\n closeTooltipIfShould(isFocused, isHovered, false);\n }, [isFocused, isHovered, closeTooltipIfShould]);\n\n const handleBlur = React.useCallback(() => {\n setIsFocused(false);\n cleanupPendingMoveEnd();\n closeTooltipIfShould(false, isHovered, isPopoverHovered);\n }, [isHovered, isPopoverHovered, cleanupPendingMoveEnd, closeTooltipIfShould]);\n\n const handleEscapeKey = React.useCallback(\n (e: KeyboardEvent) => {\n if (e.key === 'Escape' && activeTooltipId === markerId) {\n cancelCloseTimeout();\n setIsFocused(false);\n setIsHovered(false);\n setIsPopoverHovered(false);\n cleanupPendingMoveEnd();\n setTooltipOpenStatus(false);\n setActiveTooltipId(null);\n }\n },\n [activeTooltipId, markerId, cleanupPendingMoveEnd, setActiveTooltipId, cancelCloseTimeout]\n );\n\n const handleFocus = React.useCallback(() => {\n // Clean up any pending moveend handler from previous focus\n cleanupPendingMoveEnd();\n\n // Pan map to show focused datapoint if it's outside current bounds\n if (\n map.current &&\n longitude !== undefined &&\n latitude !== undefined &&\n typeof map.current.once === 'function'\n ) {\n const bounds = map.current.getBounds();\n if (!bounds.contains([longitude, latitude])) {\n // Set focused state and open tooltip after pan completes\n const moveEndHandler = () => {\n pendingMoveEndHandler.current = null;\n setIsFocused(true);\n openTooltip();\n };\n pendingMoveEndHandler.current = moveEndHandler;\n map.current.once('moveend', moveEndHandler);\n map.current.panTo([longitude, latitude]);\n return;\n }\n }\n // No pan needed, set focused immediately\n setIsFocused(true);\n openTooltip();\n }, [openTooltip, map, longitude, latitude, cleanupPendingMoveEnd]);\n\n const cleanupMarker = React.useCallback(() => {\n if (marker.current) {\n marker.current.remove();\n marker.current = undefined;\n }\n }, []);\n\n React.useEffect(() => {\n try {\n if (marker.current) {\n marker.current.setLngLat([longitude, latitude]);\n } else {\n marker.current = new Marker({ element: container.current });\n marker.current.setLngLat([longitude, latitude]);\n marker.current.addTo(map.current);\n }\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error(error);\n cleanupMarker();\n }\n }, [latitude, longitude, map]);\n\n // Add Escape key listener when tooltip is open\n React.useEffect(() => {\n if (isTooltipOpen && activeTooltipId === markerId) {\n document.addEventListener('keydown', handleEscapeKey);\n return () => {\n document.removeEventListener('keydown', handleEscapeKey);\n };\n }\n return undefined;\n }, [isTooltipOpen, activeTooltipId, markerId, handleEscapeKey]);\n\n // Close tooltip if another marker becomes active\n React.useEffect(() => {\n if (isTooltipOpen && activeTooltipId !== markerId && activeTooltipId !== null) {\n setTooltipOpenStatus(false);\n }\n }, [activeTooltipId, markerId, isTooltipOpen]);\n\n // Reopen tooltip if this marker has focus/hover/popoverHover when another tooltip closes\n React.useEffect(() => {\n if (!isTooltipOpen && activeTooltipId === null && (isFocused || isHovered || isPopoverHovered)) {\n openTooltip();\n }\n }, [activeTooltipId, isTooltipOpen, isFocused, isHovered, isPopoverHovered, openTooltip]);\n\n // For choropleths: sync local tooltip state with global active state\n // Choropleths set activeTooltipId from MapLibre event handlers, so open tooltip when this marker becomes active\n React.useEffect(() => {\n if (!customMarkerId) return;\n\n if (activeTooltipId === markerId) {\n setTooltipOpenStatus(true);\n } else {\n setTooltipOpenStatus(false);\n }\n }, [customMarkerId, activeTooltipId, markerId]);\n\n // Update marker position during map movement/zoom when tooltip is open\n // Use requestAnimationFrame to throttle updates to once per frame\n const [, forceUpdate] = React.useReducer(x => x + 1, 0);\n\n React.useEffect(() => {\n if (!isTooltipOpen || !map.current || typeof map.current.on !== 'function') {\n return undefined;\n }\n\n let rafId: number | null = null;\n\n const handleMapMove = () => {\n rafId ??= requestAnimationFrame(() => {\n forceUpdate();\n rafId = null;\n });\n };\n\n mapMoveHandlerRef.current = handleMapMove;\n map.current.on('move', handleMapMove);\n\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n }\n cleanupMapMoveHandler();\n };\n }, [isTooltipOpen, map, cleanupMapMoveHandler]);\n\n React.useEffect(\n () => () => {\n cancelCloseTimeout();\n cleanupPendingMoveEnd();\n cleanupMapMoveHandler();\n cleanupMarker();\n },\n [cancelCloseTimeout, cleanupPendingMoveEnd, cleanupMapMoveHandler, cleanupMarker]\n );\n const filteredAdditionalFields = additionalFields.filter(({ value }) => value && String(value) !== '0');\n const showTooltip =\n showCoordinates || filteredAdditionalFields.length || (areaId && !Number.isNaN(areaValue));\n // Only show tooltip if this marker is the active one in the global context\n // keepChildrenVisible allows tooltip to show during state sync for choropleths\n const isTooltipVisible = activeTooltipId === markerId && (isTooltipOpen || customMarkerId !== undefined);\n\n const childrenWithTooltipId = React.useMemo(() => {\n if (!children) return null;\n if (!React.isValidElement(children)) return children;\n return React.cloneElement(children, {\n 'aria-describedby': tooltipId,\n } as any);\n }, [children, tooltipId]);\n\n return (\n <div>\n {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}\n <div // NOSONAR typescript:S6848 - this wrapper only forwards hover/focus events to position a tooltip; it is not an interactive control and adding a role would misrepresent it to assistive tech\n ref={container}\n data-test=\"map-marker\"\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...otherProps}\n >\n {childrenWithTooltipId}\n </div>\n <div>\n {showTooltip && (\n <Tooltip\n id={tooltipId}\n open={isTooltipVisible}\n anchor={container.current}\n latitude={showCoordinates ? latitude : null}\n longitude={showCoordinates ? longitude : null}\n areaId={areaId}\n areaValue={areaValue}\n additionalFields={additionalFields}\n showCoordinates={showCoordinates}\n tooltipHeader={tooltipHeader}\n stylesManagedExternally={stylesManagedExternally}\n onMouseEnter={handlePopoverMouseEnter}\n onMouseLeave={handlePopoverMouseLeave}\n />\n )}\n </div>\n </div>\n );\n};\n\nexport default MarkerWrapper;\n", "import * as React from 'react';\nimport styled from 'styled-components';\nimport type { Map } from 'maplibre-gl';\nimport { sum } from 'lodash';\nimport { isRemoteIcon, isDataURI } from '@splunk/visualizations-shared/iconUtils';\nimport { isColor } from '@splunk/visualizations-shared/colorUtils';\nimport RemoteIcon from '@splunk/visualizations-shared/RemoteIcon';\nimport FeatureFlagContext from '@splunk/visualization-context/FeatureFlagContext';\nimport { _ } from '@splunk/ui-utils/i18n';\nimport { sprintf } from '@splunk/ui-utils/format';\nimport { KEYBOARD_KEYS } from './keyboardConstants';\nimport { convertDegToDMS } from './Tooltip';\nimport {\n bakeBubbleData,\n BubbleLayerType,\n DEFAULT_SERIES_COLORS,\n DEFAULT_RESULT_LIMIT,\n DEFAULT_CLUSTER_COLOR,\n getStaticColors,\n matchBubbleSize,\n} from './MapUtils';\nimport MarkerWrapper from './MarkerWrapper';\nimport type { TooltipProps } from './Tooltip';\nimport { useRovingTabindex } from './useRovingTabindex';\n\ntype FeatureFlagContextValue = Record<string, boolean | undefined> | null;\n\nexport const GEO_BOUND_PREFIX = '_geo_bounds_';\nexport const GEO_LAT_AND_LONG_FIELD = ['_geo_long_field', '_geo_lat_field'];\nexport const ICON_DISPLAY_CUTOFF = 16;\n\nexport interface PieSegmentProps {\n start: number;\n end: number;\n radius: number;\n color: string;\n themeColor: string;\n segmentMetadata?: { name: string; value: number; color: string };\n handleBubbleClick?: (e: React.UIEvent, name: string, count: number) => void;\n ariaLabel?: string;\n 'aria-describedby'?: string;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n elementRef?: React.Ref<Element>;\n hasEventHandlers?: boolean;\n}\n\nexport const PieSegment = React.memo(\n ({\n start,\n end,\n radius,\n color,\n themeColor,\n segmentMetadata,\n handleBubbleClick,\n ariaLabel,\n 'aria-describedby': ariaDescribedBy,\n onKeyDown,\n onFocus,\n onBlur,\n elementRef,\n hasEventHandlers,\n }: PieSegmentProps): JSX.Element => {\n const { name, value } = segmentMetadata ?? {};\n const handleInteraction = React.useCallback(\n (e: React.UIEvent) => {\n if ('key' in e && e.key !== KEYBOARD_KEYS.ENTER && e.key !== KEYBOARD_KEYS.SPACE) {\n return;\n }\n e.preventDefault();\n handleBubbleClick(e, name, value);\n },\n [name, value, handleBubbleClick]\n );\n\n const handleKeyDown = React.useCallback(\n (e: React.KeyboardEvent) => {\n // Handle Enter/Space for activation only when interactive\n if (hasEventHandlers && (e.key === KEYBOARD_KEYS.ENTER || e.key === KEYBOARD_KEYS.SPACE)) {\n handleInteraction(e);\n }\n\n // Always call the navigation handler for arrow keys, Home, End\n if (onKeyDown) {\n onKeyDown(e);\n }\n },\n [hasEventHandlers, handleInteraction, onKeyDown]\n );\n\n if (end - start === 1) {\n return (\n <BubbleSegment\n $hasEventHandlers={hasEventHandlers}\n ref={elementRef as React.Ref<SVGCircleElement>}\n as=\"circle\"\n role={hasEventHandlers ? 'button' : 'graphics-symbol'}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n onClick={hasEventHandlers ? handleInteraction : undefined}\n onKeyDown={handleKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n cx={radius}\n cy={radius}\n r={radius}\n fill={color}\n fillOpacity={0.5}\n strokeWidth={1.5}\n stroke={color}\n />\n );\n }\n const a0 = 2 * Math.PI * (start - 0.25);\n const a1 = 2 * Math.PI * (end - 0.25);\n const x0 = Math.cos(a0);\n const y0 = Math.sin(a0);\n const x1 = Math.cos(a1);\n const y1 = Math.sin(a1);\n const arc = end - start > 0.5 ? 1 : 0;\n\n return (\n <BubbleSegment\n $hasEventHandlers={hasEventHandlers}\n ref={elementRef as React.Ref<SVGPathElement>}\n as=\"path\"\n role={hasEventHandlers ? 'button' : 'graphics-symbol'}\n aria-label={ariaLabel}\n aria-describedby={ariaDescribedBy}\n onClick={hasEventHandlers ? handleInteraction : undefined}\n onKeyDown={handleKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n d={`M ${radius} ${radius} L ${radius + radius * x0} ${\n radius + radius * y0\n } A ${radius} ${radius} 0 ${arc} 1 ${radius + radius * x1} ${\n radius + radius * y1\n } L ${radius} ${radius} A 0 0 0 ${arc} 0 ${radius} ${radius}`}\n fill={color}\n fillOpacity={0.8}\n stroke={themeColor}\n strokeWidth={2}\n strokeOpacity={0.3}\n />\n );\n }\n);\n\nPieSegment.displayName = 'MapBubblePieSegment';\n\nexport const BubbleSegment = styled.path<{ $hasEventHandlers: boolean }>`\n transition: 0.2s ease-in-out;\n transition-property: fill, stroke;\n ${({ $hasEventHandlers }) => $hasEventHandlers && 'cursor: pointer;'}\n\n &:focus {\n outline: none;\n }\n`;\n\nexport const BUBBLE_SEGMENT_DIMMED_STYLES = {\n fill: 'rgba(150, 150, 150, 0.3)',\n stroke: 'rgba(200, 200, 200, 0.4)',\n} as const;\n\ninterface BubbleSvgProps {\n values: number[];\n valueRange: number[];\n tooltipHeader?: string;\n latitude: number;\n longitude: number;\n icon?: string;\n isPie: boolean;\n themeColor: string;\n segmentStartIndex: number;\n colors: string[];\n bubbleSize: Required<TooltipProps['additionalFields'][number] & { value: number }>[];\n onClick: (e: React.UIEvent, name: string, count: number) => void;\n 'aria-describedby'?: string;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n setElementRef?: (index: number, element: Element | null) => void;\n hasEventHandlers?: boolean;\n}\n\nconst BubbleSvg = React.memo(\n ({\n values,\n valueRange,\n tooltipHeader,\n latitude,\n longitude,\n icon,\n isPie,\n themeColor,\n segmentStartIndex,\n colors,\n bubbleSize,\n onClick,\n 'aria-describedby': ariaDescribedBy,\n onKeyDown,\n onFocus,\n onBlur,\n setElementRef,\n hasEventHandlers,\n }: BubbleSvgProps) => {\n const featureFlagContext = React.useContext<FeatureFlagContextValue>(FeatureFlagContext);\n const isBubbleMapIconFlagEnabled = Boolean(featureFlagContext?.visualizations_enableBubbleMapIcon);\n\n const total = values.reduce((totalValue, v) => totalValue + v, 0);\n const radius = matchBubbleSize(valueRange, total);\n\n const getAriaLabel = React.useCallback(\n (segmentName?: string, segmentValue?: number) => {\n let segmentLabel = _('Map marker');\n if (tooltipHeader) {\n segmentLabel = tooltipHeader;\n } else if (latitude !== undefined && longitude !== undefined) {\n segmentLabel = sprintf(_('Location: %(lat)s, %(lng)s'), {\n lat: convertDegToDMS(latitude, 'latitude'),\n lng: convertDegToDMS(longitude, 'longitude'),\n });\n }\n\n if (segmentName != null && segmentValue != null) {\n segmentLabel = sprintf(_('%(locationLabel)s, %(segmentName)s: %(segmentValue)s'), {\n locationLabel: segmentLabel,\n segmentName,\n segmentValue: segmentValue.toString(),\n });\n }\n if (hasEventHandlers) {\n segmentLabel = sprintf(_('%(label)s, Click for drilldown'), { label: segmentLabel });\n }\n\n return segmentLabel;\n },\n [tooltipHeader, latitude, longitude, hasEventHandlers]\n );\n\n const offsets: number[] = [];\n let runningTotal = 0;\n values.forEach(count => {\n offsets.push(runningTotal);\n runningTotal += count;\n });\n\n const width = radius * 2;\n const showIcon =\n isBubbleMapIconFlagEnabled &&\n radius >= ICON_DISPLAY_CUTOFF &&\n icon &&\n (isRemoteIcon(icon) || isDataURI(icon));\n\n return (\n <svg width={width} height={width} viewBox={`-3 -3 ${width + 6} ${width + 6}`}>\n {isPie && (\n <circle\n cx={radius}\n cy={radius}\n r={radius}\n fill=\"none\"\n strokeWidth={2}\n stroke={themeColor}\n strokeOpacity={0.3}\n />\n )}\n {values.map((v, i) => {\n const globalIndex = segmentStartIndex + i;\n return (\n <PieSegment\n key={globalIndex}\n start={offsets[i] / total}\n end={(offsets[i] + v) / total}\n radius={radius}\n color={colors[i]}\n themeColor={themeColor}\n segmentMetadata={bubbleSize[i]}\n handleBubbleClick={onClick}\n ariaLabel={getAriaLabel(bubbleSize[i]?.name, bubbleSize[i]?.value)}\n aria-describedby={ariaDescribedBy}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n elementRef={\n setElementRef ? element => setElementRef(globalIndex, element) : undefined\n }\n hasEventHandlers={hasEventHandlers}\n />\n );\n })}\n {showIcon && (\n <foreignObject\n x={radius - (radius * 0.8) / 2}\n y={radius - (radius * 0.8) / 2}\n width={radius * 0.8}\n height={radius * 0.8}\n style={{ pointerEvents: 'none' }}\n data-test=\"bubble-icon-wrapper\"\n >\n <RemoteIcon iconURL={icon} width={radius * 0.8} height={radius * 0.8} />\n </foreignObject>\n )}\n </svg>\n );\n }\n);\n\nexport interface BubbleProps {\n originalValues: number[];\n valueRange: number[];\n colors: string[];\n themeColor: string;\n isPie: boolean;\n latitude: number;\n longitude: number;\n bubbleSize: Required<TooltipProps['additionalFields'][number] & { value: number }>[];\n additionalFields?: TooltipProps['additionalFields'];\n tooltipHeader?: TooltipProps['tooltipHeader'];\n map: React.MutableRefObject<Map>;\n handleMapClick?: any;\n icon?: string;\n showCoordinates?: boolean;\n stylesManagedExternally?: boolean;\n segmentStartIndex?: number;\n onKeyDown?: (e: React.KeyboardEvent) => void;\n onFocus?: () => void;\n onBlur?: () => void;\n setElementRef?: (index: number, element: Element) => void;\n hasEventHandlers?: boolean;\n}\n\nexport const Bubble = React.memo(\n ({\n originalValues,\n valueRange,\n colors,\n themeColor,\n isPie,\n latitude,\n longitude,\n bubbleSize,\n additionalFields = [],\n tooltipHeader = null,\n map,\n handleMapClick,\n icon,\n showCoordinates,\n stylesManagedExternally,\n segmentStartIndex = 0,\n onKeyDown,\n onFocus,\n onBlur,\n setElementRef,\n hasEventHandlers,\n }: BubbleProps): JSX.Element => {\n const onBubbleClick = React.useCallback(\n (e, name, value) => {\n handleMapClick(e, name, value);\n e.stopPropagation();\n },\n [handleMapClick]\n );\n\n // sanitize values\n const allZeros = originalValues.every(v => v === 0);\n const values = originalValues.map(v => Math.max(v, 0));\n\n if (allZeros || !originalValues.length) return null;\n\n return (\n <MarkerWrapper\n longitude={longitude}\n latitude={latitude}\n additionalFields={[...bubbleSize, ...additionalFields]}\n tooltipHeader={tooltipHeader}\n map={map}\n data-test-type=\"bubble\"\n showCoordinates={showCoordinates}\n stylesManagedExternally={stylesManagedExternally}\n >\n <BubbleSvg\n values={values}\n valueRange={valueRange}\n colors={colors}\n bubbleSize={bubbleSize}\n isPie={isPie}\n themeColor={themeColor}\n segmentStartIndex={segmentStartIndex}\n latitude={latitude}\n longitude={longitude}\n tooltipHeader={tooltipHeader}\n icon={icon}\n onClick={onBubbleClick}\n onKeyDown={onKeyDown}\n onFocus={onFocus}\n onBlur={onBlur}\n setElementRef={setElementRef}\n hasEventHandlers={hasEventHandlers}\n />\n </MarkerWrapper>\n );\n }\n);\nBubble.displayName = 'MapBubble';\n\nexport interface BubbleLayerProps {\n bubbleLayer: BubbleLayerType;\n themeColorScheme: string;\n zoom: number;\n map: React.MutableRefObject<Map>;\n onMapClick?: any;\n showCoordinates?: boolean;\n stylesManagedExternally?: boolean;\n hasEventHandlers?: boolean;\n}\n\nconst BubbleLayer = (props: BubbleLayerProps): JSX.Element => {\n const {\n bubbleLayer,\n themeColorScheme,\n map,\n zoom,\n onMapClick,\n showCoordinates,\n stylesManagedExternally = false,\n hasEventHandlers,\n } = props;\n\n bubbleLayer.seriesColors = bubbleLayer.seriesColors || DEFAULT_SERIES_COLORS;\n bubbleLayer.bubbleSize = bubbleLayer.bubbleSize || [];\n bubbleLayer.icon = bubbleLayer.icon || [];\n const bakedData = React.useMemo(() => bakeBubbleData(bubbleLayer), [bubbleLayer]);\n const staticColors = React.useMemo(\n () => getStaticColors(bubbleLayer.bubbleSize.length, bubbleLayer.seriesColors),\n [bubbleLayer.bubbleSize.length, bubbleLayer.seriesColors]\n );\n const { data = [], dataRange = [], resultLimit, bubbleSizeFields, isPie } = bakedData ?? {};\n const { additionalTooltipFields = [], tooltipHeaderFieldName = null } = bubbleLayer;\n const roundedZoom = Math.round(zoom);\n const themeColor = themeColorScheme === 'light' ? '#ffffff' : '#1a1c20';\n const dynamicColors = bubbleLayer.dataColors;\n\n // filter data for the current zoom level and sort base on values\n const dataToRender = React.useMemo(\n () =>\n data\n .reduce((acc, datum, i) => {\n const shouldRender =\n datum.zoom === null || datum.zoom === undefined || datum.zoom === roundedZoom;\n if (shouldRender) {\n acc.push({ data: datum, idx: i });\n }\n return acc;\n }, [])\n .slice(0, resultLimit || DEFAULT_RESULT_LIMIT)\n .sort((a, b) => sum(b.data.values) - sum(a.data.values)),\n [data, resultLimit, roundedZoom]\n );\n\n const handleMapClick = React.useCallback(\n (e, name, value, i) => {\n // retrieve metadata from the appropriate datum, indexed by i\n const metadata = dataToRender[i]?.data?.metadata ?? {};\n const payload = Object.keys(metadata).reduce(\n (acc, curr) => {\n const key = `row.${curr}.value`;\n const val = String(metadata[curr]);\n return { ...acc, [key]: val };\n },\n { name, value: String(value) }\n );\n\n onMapClick({ e, payload });\n },\n [dataToRender, onMapClick]\n );\n\n const { handleKeyDown, handleFocus, handleBlur, setElementRef } = useRovingTabindex(map);\n\n let globalSegmentIndex = 0;\n\n return (\n <>\n {dataToRender.map((datum, i) => {\n const allZeros = datum.data.values.every(v => v === 0);\n const segmentStartIndex = globalSegmentIndex;\n const segmentCount = datum.data.values.length;\n if (!allZeros) {\n globalSegmentIndex += segmentCount;\n }\n const colors = dynamicColors\n ? [\n dataToRender.map(obj =>\n isColor(dynamicColors[obj.idx]) ? dynamicColors[obj.idx] : DEFAULT_CLUSTER_COLOR\n )[i],\n ]\n : staticColors;\n\n const [longitude, latitude] = datum.data.coordinates;\n const bubbleSize = datum.data.values.map((value, index) => ({\n name: bubbleSizeFields[index],\n value,\n color: colors[index],\n }));\n\n const additionalFields = bubbleLayer.metadata\n ? additionalTooltipFields.map(field => ({\n name: field,\n value: datum.data.metadata[field],\n icon: bubbleLayer.tooltipFieldIcons?.[field],\n }))\n : [];\n\n const tooltipHeaderField =\n bubbleLayer.metadata && datum.data.metadata[tooltipHeaderFieldName];\n\n return (\n <Bubble\n key={String(datum.idx)}\n originalValues={datum.data.values}\n valueRange={dataRange}\n colors={colors}\n themeColor={themeColor}\n isPie={isPie}\n longitude={longitude}\n latitude={latitude}\n bubbleSize={bubbleSize}\n additionalFields={additionalFields}\n tooltipHeader={tooltipHeaderField}\n map={map}\n handleMapClick={(e, name, value) => handleMapClick(e, name, value, i)}\n icon={bubbleLayer.icon[datum.idx]}\n showCoordinates={showCoordinates}\n stylesManagedExternally={stylesManagedExternally}\n segmentStartIndex={segmentStartIndex}\n onKeyDown={handleKeyDown}\n onFocus={handleFocus}\n onBlur={handleBlur}\n setElementRef={setElementRef}\n hasEventHandlers={hasEventHandlers}\n />\n );\n })}\n </>\n );\n};\n\nexport default BubbleLayer;\n"],
5
5
  "mappings": "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",
6
6
  "names": ["defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport", "defaultImport"]
7
7
  }