diff --git a/.betterer.results b/.betterer.results index 41d23da9f1c11..7c07c78c43ab8 100644 --- a/.betterer.results +++ b/.betterer.results @@ -17,25 +17,13 @@ exports[`better eslint`] = { ], "packages/grafana-data/src/dataframe/DataFrameJSON.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"] - ], - "packages/grafana-data/src/dataframe/DataFrameView.test.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "packages/grafana-data/src/dataframe/DataFrameView.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Do not use any type assertions.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"] + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "packages/grafana-data/src/dataframe/MutableDataFrame.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -48,14 +36,12 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], + [0, 0, 0, "Do not use any type assertions.", "10"], [0, 0, 0, "Unexpected any. Specify a different type.", "11"], [0, 0, 0, "Do not use any type assertions.", "12"], [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Do not use any type assertions.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"], - [0, 0, 0, "Do not use any type assertions.", "17"] + [0, 0, 0, "Unexpected any. Specify a different type.", "14"], + [0, 0, 0, "Do not use any type assertions.", "15"] ], "packages/grafana-data/src/dataframe/StreamingDataFrame.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -63,9 +49,7 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Do not use any type assertions.", "7"] + [0, 0, 0, "Do not use any type assertions.", "5"] ], "packages/grafana-data/src/dataframe/dimensions.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -80,24 +64,23 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], [0, 0, 0, "Do not use any type assertions.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Do not use any type assertions.", "7"], [0, 0, 0, "Do not use any type assertions.", "8"], [0, 0, 0, "Do not use any type assertions.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Do not use any type assertions.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], + [0, 0, 0, "Unexpected any. Specify a different type.", "10"], + [0, 0, 0, "Do not use any type assertions.", "11"], + [0, 0, 0, "Unexpected any. Specify a different type.", "12"], + [0, 0, 0, "Do not use any type assertions.", "13"], + [0, 0, 0, "Unexpected any. Specify a different type.", "14"], + [0, 0, 0, "Do not use any type assertions.", "15"], [0, 0, 0, "Do not use any type assertions.", "16"], [0, 0, 0, "Do not use any type assertions.", "17"], [0, 0, 0, "Do not use any type assertions.", "18"], [0, 0, 0, "Do not use any type assertions.", "19"], [0, 0, 0, "Do not use any type assertions.", "20"], [0, 0, 0, "Do not use any type assertions.", "21"], - [0, 0, 0, "Do not use any type assertions.", "22"], - [0, 0, 0, "Do not use any type assertions.", "23"] + [0, 0, 0, "Do not use any type assertions.", "22"] ], "packages/grafana-data/src/datetime/datemath.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -139,10 +122,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "packages/grafana-data/src/events/common.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "packages/grafana-data/src/events/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -153,32 +132,18 @@ exports[`better eslint`] = { "packages/grafana-data/src/field/displayProcessor.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] - ], - "packages/grafana-data/src/field/fieldOverrides.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Do not use any type assertions.", "2"] ], "packages/grafana-data/src/field/overrides/processors.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Do not use any type assertions.", "11"] - ], - "packages/grafana-data/src/field/scale.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"] + [0, 0, 0, "Do not use any type assertions.", "8"] ], "packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -191,8 +156,7 @@ exports[`better eslint`] = { ], "packages/grafana-data/src/geo/layer.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "packages/grafana-data/src/panel/PanelPlugin.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -204,16 +168,8 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "6"], [0, 0, 0, "Do not use any type assertions.", "7"] ], - "packages/grafana-data/src/panel/getPanelOptionsWithDefaults.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], "packages/grafana-data/src/panel/registryFactories.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "packages/grafana-data/src/themes/colorManipulator.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -223,9 +179,6 @@ exports[`better eslint`] = { "packages/grafana-data/src/themes/createColors.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "packages/grafana-data/src/transformations/fieldReducer.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "packages/grafana-data/src/transformations/matchers/valueMatchers/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -236,25 +189,14 @@ exports[`better eslint`] = { "packages/grafana-data/src/transformations/transformDataFrame.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "packages/grafana-data/src/transformations/transformers/groupBy.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], - "packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "packages/grafana-data/src/transformations/transformers/histogram.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "packages/grafana-data/src/transformations/transformers/joinDataFrames.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "packages/grafana-data/src/transformations/transformers/merge.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + "packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"] + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "packages/grafana-data/src/transformations/transformers/reduce.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -344,8 +286,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "21"], [0, 0, 0, "Unexpected any. Specify a different type.", "22"], [0, 0, 0, "Unexpected any. Specify a different type.", "23"], - [0, 0, 0, "Unexpected any. Specify a different type.", "24"], - [0, 0, 0, "Unexpected any. Specify a different type.", "25"] + [0, 0, 0, "Unexpected any. Specify a different type.", "24"] ], "packages/grafana-data/src/types/explore.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -362,8 +303,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"] + [0, 0, 0, "Unexpected any. Specify a different type.", "11"] ], "packages/grafana-data/src/types/flot.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -413,8 +353,7 @@ exports[`better eslint`] = { ], "packages/grafana-data/src/types/plugin.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "packages/grafana-data/src/types/select.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -445,98 +384,31 @@ exports[`better eslint`] = { "packages/grafana-data/src/utils/OptionsUIBuilders.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"], + [0, 0, 0, "Unexpected any. Specify a different type.", "10"], [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], + [0, 0, 0, "Unexpected any. Specify a different type.", "12"], [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Do not use any type assertions.", "14"], + [0, 0, 0, "Unexpected any. Specify a different type.", "14"], [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Do not use any type assertions.", "16"], + [0, 0, 0, "Unexpected any. Specify a different type.", "16"], [0, 0, 0, "Unexpected any. Specify a different type.", "17"], [0, 0, 0, "Unexpected any. Specify a different type.", "18"], - [0, 0, 0, "Do not use any type assertions.", "19"], + [0, 0, 0, "Unexpected any. Specify a different type.", "19"], [0, 0, 0, "Unexpected any. Specify a different type.", "20"], - [0, 0, 0, "Do not use any type assertions.", "21"], + [0, 0, 0, "Unexpected any. Specify a different type.", "21"], [0, 0, 0, "Unexpected any. Specify a different type.", "22"], [0, 0, 0, "Unexpected any. Specify a different type.", "23"], - [0, 0, 0, "Do not use any type assertions.", "24"], + [0, 0, 0, "Unexpected any. Specify a different type.", "24"], [0, 0, 0, "Unexpected any. Specify a different type.", "25"], - [0, 0, 0, "Do not use any type assertions.", "26"], - [0, 0, 0, "Unexpected any. Specify a different type.", "27"], - [0, 0, 0, "Unexpected any. Specify a different type.", "28"], - [0, 0, 0, "Do not use any type assertions.", "29"], - [0, 0, 0, "Unexpected any. Specify a different type.", "30"], - [0, 0, 0, "Do not use any type assertions.", "31"], - [0, 0, 0, "Unexpected any. Specify a different type.", "32"], - [0, 0, 0, "Unexpected any. Specify a different type.", "33"], - [0, 0, 0, "Do not use any type assertions.", "34"], - [0, 0, 0, "Unexpected any. Specify a different type.", "35"], - [0, 0, 0, "Do not use any type assertions.", "36"], - [0, 0, 0, "Unexpected any. Specify a different type.", "37"], - [0, 0, 0, "Unexpected any. Specify a different type.", "38"], - [0, 0, 0, "Do not use any type assertions.", "39"], - [0, 0, 0, "Unexpected any. Specify a different type.", "40"], - [0, 0, 0, "Do not use any type assertions.", "41"], - [0, 0, 0, "Unexpected any. Specify a different type.", "42"], - [0, 0, 0, "Unexpected any. Specify a different type.", "43"], - [0, 0, 0, "Unexpected any. Specify a different type.", "44"], - [0, 0, 0, "Do not use any type assertions.", "45"], - [0, 0, 0, "Unexpected any. Specify a different type.", "46"], - [0, 0, 0, "Do not use any type assertions.", "47"], - [0, 0, 0, "Unexpected any. Specify a different type.", "48"], - [0, 0, 0, "Unexpected any. Specify a different type.", "49"], - [0, 0, 0, "Unexpected any. Specify a different type.", "50"], - [0, 0, 0, "Unexpected any. Specify a different type.", "51"], - [0, 0, 0, "Unexpected any. Specify a different type.", "52"], - [0, 0, 0, "Unexpected any. Specify a different type.", "53"], - [0, 0, 0, "Unexpected any. Specify a different type.", "54"], - [0, 0, 0, "Unexpected any. Specify a different type.", "55"], - [0, 0, 0, "Unexpected any. Specify a different type.", "56"], - [0, 0, 0, "Unexpected any. Specify a different type.", "57"], - [0, 0, 0, "Unexpected any. Specify a different type.", "58"], - [0, 0, 0, "Unexpected any. Specify a different type.", "59"], - [0, 0, 0, "Unexpected any. Specify a different type.", "60"], - [0, 0, 0, "Unexpected any. Specify a different type.", "61"], - [0, 0, 0, "Do not use any type assertions.", "62"], - [0, 0, 0, "Unexpected any. Specify a different type.", "63"], - [0, 0, 0, "Do not use any type assertions.", "64"], - [0, 0, 0, "Unexpected any. Specify a different type.", "65"], - [0, 0, 0, "Do not use any type assertions.", "66"], - [0, 0, 0, "Unexpected any. Specify a different type.", "67"], - [0, 0, 0, "Do not use any type assertions.", "68"], - [0, 0, 0, "Unexpected any. Specify a different type.", "69"], - [0, 0, 0, "Do not use any type assertions.", "70"], - [0, 0, 0, "Unexpected any. Specify a different type.", "71"], - [0, 0, 0, "Do not use any type assertions.", "72"], - [0, 0, 0, "Unexpected any. Specify a different type.", "73"], - [0, 0, 0, "Do not use any type assertions.", "74"], - [0, 0, 0, "Unexpected any. Specify a different type.", "75"], - [0, 0, 0, "Unexpected any. Specify a different type.", "76"], - [0, 0, 0, "Do not use any type assertions.", "77"], - [0, 0, 0, "Unexpected any. Specify a different type.", "78"], - [0, 0, 0, "Unexpected any. Specify a different type.", "79"], - [0, 0, 0, "Do not use any type assertions.", "80"], - [0, 0, 0, "Unexpected any. Specify a different type.", "81"], - [0, 0, 0, "Unexpected any. Specify a different type.", "82"], - [0, 0, 0, "Do not use any type assertions.", "83"], - [0, 0, 0, "Unexpected any. Specify a different type.", "84"], - [0, 0, 0, "Unexpected any. Specify a different type.", "85"], - [0, 0, 0, "Do not use any type assertions.", "86"], - [0, 0, 0, "Unexpected any. Specify a different type.", "87"], - [0, 0, 0, "Unexpected any. Specify a different type.", "88"], - [0, 0, 0, "Do not use any type assertions.", "89"], - [0, 0, 0, "Unexpected any. Specify a different type.", "90"], - [0, 0, 0, "Unexpected any. Specify a different type.", "91"], - [0, 0, 0, "Do not use any type assertions.", "92"], - [0, 0, 0, "Unexpected any. Specify a different type.", "93"] + [0, 0, 0, "Unexpected any. Specify a different type.", "26"] ], "packages/grafana-data/src/utils/Registry.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -556,34 +428,26 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "packages/grafana-data/src/utils/datasource.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"] - ], - "packages/grafana-data/src/utils/fieldParser.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Do not use any type assertions.", "1"] ], "packages/grafana-data/src/utils/flotPairs.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "packages/grafana-data/src/utils/location.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "packages/grafana-data/src/utils/url.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Do not use any type assertions.", "4"], + [0, 0, 0, "Unexpected any. Specify a different type.", "5"], [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"] + [0, 0, 0, "Do not use any type assertions.", "7"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"] ], "packages/grafana-data/src/utils/valueMappings.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -603,8 +467,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "packages/grafana-data/src/vector/CircularVector.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "packages/grafana-data/src/vector/ConstantVector.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -622,8 +485,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"] + [0, 0, 0, "Unexpected any. Specify a different type.", "9"] ], "packages/grafana-data/src/vector/SortedVector.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -669,9 +531,7 @@ exports[`better eslint`] = { ], "packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] + [0, 0, 0, "Styles should be written using objects.", "1"] ], "packages/grafana-runtime/src/analytics/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -735,7 +595,8 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"] + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Do not use any type assertions.", "6"] ], "packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -767,20 +628,6 @@ exports[`better eslint`] = { "packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], - "packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], - "packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], - "packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], - "packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"] - ], "packages/grafana-ui/src/components/Drawer/Drawer.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], @@ -796,40 +643,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "packages/grafana-ui/src/components/Graph/GraphContextMenu.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "packages/grafana-ui/src/components/Graph/utils.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "packages/grafana-ui/src/components/GraphNG/GraphNG.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Do not use any type assertions.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"], - [0, 0, 0, "Do not use any type assertions.", "11"] - ], - "packages/grafana-ui/src/components/GraphNG/hooks.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], - "packages/grafana-ui/src/components/GraphNG/nullInsertThreshold.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] - ], - "packages/grafana-ui/src/components/GraphNG/nullToUndefThreshold.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"] - ], "packages/grafana-ui/src/components/InfoBox/InfoBox.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -884,8 +697,7 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"] + [0, 0, 0, "Unexpected any. Specify a different type.", "11"] ], "packages/grafana-ui/src/components/Select/SelectOptionGroup.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -981,11 +793,6 @@ exports[`better eslint`] = { "packages/grafana-ui/src/components/Tags/Tag.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "packages/grafana-ui/src/components/TimeSeries/utils.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], "packages/grafana-ui/src/components/ValuePicker/ValuePicker.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"] @@ -1032,6 +839,45 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] ], + "packages/grafana-ui/src/graveyard/Graph/GraphContextMenu.tsx:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], + "packages/grafana-ui/src/graveyard/Graph/utils.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], + "packages/grafana-ui/src/graveyard/GraphNG/GraphNG.tsx:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Do not use any type assertions.", "6"], + [0, 0, 0, "Do not use any type assertions.", "7"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"], + [0, 0, 0, "Do not use any type assertions.", "9"], + [0, 0, 0, "Do not use any type assertions.", "10"], + [0, 0, 0, "Do not use any type assertions.", "11"] + ], + "packages/grafana-ui/src/graveyard/GraphNG/hooks.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], + "packages/grafana-ui/src/graveyard/GraphNG/nullInsertThreshold.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] + ], + "packages/grafana-ui/src/graveyard/GraphNG/nullToUndefThreshold.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Do not use any type assertions.", "2"] + ], + "packages/grafana-ui/src/graveyard/TimeSeries/utils.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Do not use any type assertions.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + ], "packages/grafana-ui/src/options/builder/axis.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -1041,9 +887,6 @@ exports[`better eslint`] = { "packages/grafana-ui/src/options/builder/hideSeries.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "packages/grafana-ui/src/options/builder/stacking.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "packages/grafana-ui/src/slate-plugins/braces.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -1107,233 +950,68 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "packages/grafana-ui/src/utils/useAsyncDependency.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "plugins-bundled/internal/input-datasource/src/InputDatasource.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/core/TableModel.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"] - ], - "public/app/core/components/AppChrome/MegaMenu/NavFeatureHighlight.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/core/components/AppChrome/News/NewsContainer.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], - "public/app/core/components/AppChrome/SectionNav/SectionNavItem.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] - ], - "public/app/core/components/AppChrome/TopBar/TopSearchBarCommandPaletteTrigger.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/core/components/Branding/Branding.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/core/components/CardButton.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/core/components/CloseButton/CloseButton.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/core/components/ColorScale/ColorScale.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] - ], - "public/app/core/components/Divider.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/core/components/DynamicImports/SafeDynamicImport.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/core/components/EmptyListCTA/EmptyListCTA.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] - ], - "public/app/core/components/FolderFilter/FolderFilter.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/core/components/ForgottenPassword/ChangePassword.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], - "public/app/core/components/ForgottenPassword/ForgottenPassword.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/core/components/Layers/LayerDragDropList.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"] - ], - "public/app/core/components/Layers/LayerName.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"] - ], - "public/app/core/components/Login/LoginForm.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "3"] - ], - "public/app/core/components/Login/LoginLayout.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"], - [0, 0, 0, "Styles should be written using objects.", "9"], - [0, 0, 0, "Styles should be written using objects.", "10"] + "packages/grafana-ui/src/utils/useAsyncDependency.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/core/components/Login/LoginPage.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] + "plugins-bundled/internal/input-datasource/src/InputDatasource.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/core/components/Login/LoginServiceButtons.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], + "public/app/core/TableModel.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Unexpected any. Specify a different type.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"] + ], + "public/app/core/components/AppChrome/News/NewsContainer.tsx:5381": [ + [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] + ], + "public/app/core/components/AppChrome/SectionNav/SectionNavItem.tsx:5381": [ + [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"] + [0, 0, 0, "Styles should be written using objects.", "3"] ], - "public/app/core/components/Login/UserSignup.tsx:5381": [ + "public/app/core/components/AppChrome/TopBar/TopSearchBarCommandPaletteTrigger.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], - "public/app/core/components/NestedFolderPicker/Trigger.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] + "public/app/core/components/DynamicImports/SafeDynamicImport.tsx:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/core/components/NodeGraphSettings.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] + "public/app/core/components/GraphNG/GraphNG.tsx:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Do not use any type assertions.", "6"], + [0, 0, 0, "Do not use any type assertions.", "7"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"], + [0, 0, 0, "Do not use any type assertions.", "9"], + [0, 0, 0, "Do not use any type assertions.", "10"], + [0, 0, 0, "Do not use any type assertions.", "11"] ], - "public/app/core/components/OptionsUI/color.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] + "public/app/core/components/GraphNG/hooks.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/core/components/OptionsUI/fieldColor.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] + "public/app/core/components/NestedFolderPicker/Trigger.tsx:5381": [ + [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/core/components/OptionsUI/registry.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Do not use any type assertions.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Do not use any type assertions.", "16"], - [0, 0, 0, "Unexpected any. Specify a different type.", "17"], - [0, 0, 0, "Do not use any type assertions.", "18"], - [0, 0, 0, "Unexpected any. Specify a different type.", "19"], - [0, 0, 0, "Unexpected any. Specify a different type.", "20"], - [0, 0, 0, "Do not use any type assertions.", "21"], - [0, 0, 0, "Unexpected any. Specify a different type.", "22"], - [0, 0, 0, "Do not use any type assertions.", "23"], - [0, 0, 0, "Unexpected any. Specify a different type.", "24"], - [0, 0, 0, "Unexpected any. Specify a different type.", "25"], - [0, 0, 0, "Do not use any type assertions.", "26"], - [0, 0, 0, "Unexpected any. Specify a different type.", "27"], - [0, 0, 0, "Do not use any type assertions.", "28"], - [0, 0, 0, "Unexpected any. Specify a different type.", "29"], - [0, 0, 0, "Unexpected any. Specify a different type.", "30"], - [0, 0, 0, "Do not use any type assertions.", "31"], - [0, 0, 0, "Unexpected any. Specify a different type.", "32"], - [0, 0, 0, "Do not use any type assertions.", "33"], - [0, 0, 0, "Unexpected any. Specify a different type.", "34"], - [0, 0, 0, "Unexpected any. Specify a different type.", "35"], - [0, 0, 0, "Do not use any type assertions.", "36"], - [0, 0, 0, "Unexpected any. Specify a different type.", "37"], - [0, 0, 0, "Do not use any type assertions.", "38"], - [0, 0, 0, "Unexpected any. Specify a different type.", "39"], - [0, 0, 0, "Unexpected any. Specify a different type.", "40"], - [0, 0, 0, "Do not use any type assertions.", "41"], - [0, 0, 0, "Unexpected any. Specify a different type.", "42"], - [0, 0, 0, "Do not use any type assertions.", "43"], - [0, 0, 0, "Unexpected any. Specify a different type.", "44"], - [0, 0, 0, "Unexpected any. Specify a different type.", "45"], - [0, 0, 0, "Do not use any type assertions.", "46"], - [0, 0, 0, "Unexpected any. Specify a different type.", "47"], - [0, 0, 0, "Do not use any type assertions.", "48"], - [0, 0, 0, "Unexpected any. Specify a different type.", "49"], - [0, 0, 0, "Unexpected any. Specify a different type.", "50"], - [0, 0, 0, "Do not use any type assertions.", "51"], - [0, 0, 0, "Unexpected any. Specify a different type.", "52"], - [0, 0, 0, "Do not use any type assertions.", "53"], - [0, 0, 0, "Unexpected any. Specify a different type.", "54"], - [0, 0, 0, "Unexpected any. Specify a different type.", "55"], - [0, 0, 0, "Do not use any type assertions.", "56"], - [0, 0, 0, "Unexpected any. Specify a different type.", "57"], - [0, 0, 0, "Do not use any type assertions.", "58"], - [0, 0, 0, "Unexpected any. Specify a different type.", "59"], - [0, 0, 0, "Unexpected any. Specify a different type.", "60"], - [0, 0, 0, "Do not use any type assertions.", "61"], - [0, 0, 0, "Unexpected any. Specify a different type.", "62"], - [0, 0, 0, "Do not use any type assertions.", "63"], - [0, 0, 0, "Unexpected any. Specify a different type.", "64"], - [0, 0, 0, "Unexpected any. Specify a different type.", "65"], - [0, 0, 0, "Do not use any type assertions.", "66"], - [0, 0, 0, "Unexpected any. Specify a different type.", "67"], - [0, 0, 0, "Do not use any type assertions.", "68"], - [0, 0, 0, "Unexpected any. Specify a different type.", "69"], - [0, 0, 0, "Unexpected any. Specify a different type.", "70"], - [0, 0, 0, "Do not use any type assertions.", "71"], - [0, 0, 0, "Unexpected any. Specify a different type.", "72"], - [0, 0, 0, "Do not use any type assertions.", "73"], - [0, 0, 0, "Unexpected any. Specify a different type.", "74"], - [0, 0, 0, "Do not use any type assertions.", "75"], - [0, 0, 0, "Unexpected any. Specify a different type.", "76"], - [0, 0, 0, "Do not use any type assertions.", "77"], - [0, 0, 0, "Unexpected any. Specify a different type.", "78"] - ], - "public/app/core/components/OptionsUI/slider.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/core/components/OptionsUI/strings.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/core/components/OptionsUI/units.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "10"] ], "public/app/core/components/PageHeader/PageHeader.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -1346,9 +1024,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/core/components/PasswordField/PasswordField.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], "public/app/core/components/QueryOperationRow/OperationRowHelp.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], @@ -1377,11 +1052,7 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "3"], [0, 0, 0, "Styles should be written using objects.", "4"], [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"] - ], - "public/app/core/components/RolePicker/RolePickerMenu.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] + [0, 0, 0, "Styles should be written using objects.", "6"] ], "public/app/core/components/RolePicker/ValueContainer.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -1412,10 +1083,13 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "2"] ], + "public/app/core/components/TimeSeries/utils.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Do not use any type assertions.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + ], "public/app/core/components/TraceToLogs/TagMappingInput.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/core/components/TraceToMetrics/TraceToMetricsSettings.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -1459,9 +1133,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "6"], [0, 0, 0, "Styles should be written using objects.", "7"] ], - "public/app/core/navigation/GrafanaRouteError.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], "public/app/core/navigation/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -1546,8 +1217,7 @@ exports[`better eslint`] = { "public/app/core/utils/explore.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/core/utils/fetch.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -1594,17 +1264,6 @@ exports[`better eslint`] = { "public/app/features/admin/OrgRolePicker.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/admin/ServerStats.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"] - ], "public/app/features/admin/UpgradePage.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -1660,8 +1319,7 @@ exports[`better eslint`] = { ], "public/app/features/alerting/AlertTab.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/features/alerting/AlertTabCtrl.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -1723,12 +1381,6 @@ exports[`better eslint`] = { "public/app/features/alerting/components/OptionElement.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/features/alerting/getAlertingValidationMessage.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] - ], "public/app/features/alerting/state/ThresholdMapper.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -1801,10 +1453,9 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/features/alerting/unified/PanelAlertTabContent.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], + [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] + [0, 0, 0, "Styles should be written using objects.", "2"] ], "public/app/features/alerting/unified/RedirectToRuleViewer.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -1820,14 +1471,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "4"], [0, 0, 0, "Styles should be written using objects.", "5"] ], - "public/app/features/alerting/unified/api/alertmanager.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], - "public/app/features/alerting/unified/api/ruler.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"] - ], "public/app/features/alerting/unified/components/AlertLabel.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], @@ -1982,7 +1625,7 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/features/alerting/unified/components/contact-points/ContactPoints.v2.tsx:5381": [ + "public/app/features/alerting/unified/components/contact-points/ContactPoints.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/features/alerting/unified/components/export/FileExportPreview.tsx:5381": [ @@ -2165,9 +1808,8 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] + [0, 0, 0, "Styles should be written using objects.", "3"], + [0, 0, 0, "Styles should be written using objects.", "4"] ], "public/app/features/alerting/unified/components/receivers/form/TestContactPointModal.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -2182,12 +1824,10 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"] + [0, 0, 0, "Styles should be written using objects.", "4"], + [0, 0, 0, "Styles should be written using objects.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Unexpected any. Specify a different type.", "7"] ], "public/app/features/alerting/unified/components/receivers/form/fields/StringArrayInput.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -2292,16 +1932,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/features/alerting/unified/components/rule-editor/LabelsField.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"] - ], "public/app/features/alerting/unified/components/rule-editor/NeedHelpInfo.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] @@ -2397,11 +2027,10 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"] ], "public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], + [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"] + [0, 0, 0, "Styles should be written using objects.", "3"] ], "public/app/features/alerting/unified/components/rule-editor/rule-types/RuleType.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -2715,8 +2344,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"] + [0, 0, 0, "Do not use any type assertions.", "3"] ], "public/app/features/annotations/components/StandardAnnotationQueryEditor.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -2738,27 +2366,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "2"] ], - "public/app/features/auth-config/AuthConfigPage.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] - ], - "public/app/features/auth-config/components/ConfigureAuthCTA.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/features/auth-config/components/ProviderCard.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"] - ], "public/app/features/canvas/element.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -2766,43 +2373,8 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Unexpected any. Specify a different type.", "4"] ], - "public/app/features/canvas/elements/droneFront.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/features/canvas/elements/droneSide.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/features/canvas/elements/droneTop.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] - ], "public/app/features/canvas/elements/ellipse.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/features/canvas/elements/icon.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/features/canvas/elements/metricValue.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] - ], - "public/app/features/canvas/elements/server/server.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"] - ], - "public/app/features/canvas/elements/text.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] - ], - "public/app/features/canvas/elements/windTurbine.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/features/canvas/runtime/element.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -2875,13 +2447,12 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/features/correlations/Forms/TransformationsEditor.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], "public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], + "public/app/features/dashboard-scene/scene/DashboardScene.test.tsx:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], "public/app/features/dashboard-scene/scene/PanelMenuBehavior.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -2895,7 +2466,9 @@ exports[`better eslint`] = { ], "public/app/features/dashboard-scene/serialization/transformSaveModelToScene.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -2905,7 +2478,8 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"] + [0, 0, 0, "Unexpected any. Specify a different type.", "7"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"] ], "public/app/features/dashboard-scene/serialization/transformSceneToSaveModel.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -2980,12 +2554,11 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Do not use any type assertions.", "7"], [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"] + [0, 0, 0, "Unexpected any. Specify a different type.", "9"] ], "public/app/features/dashboard/components/DashNav/DashNavButton.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -3006,9 +2579,10 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"] + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Do not use any type assertions.", "7"], + [0, 0, 0, "Unexpected any. Specify a different type.", "8"] ], "public/app/features/dashboard/components/DashboardRow/DashboardRow.test.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -3126,9 +2700,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], - "public/app/features/dashboard/components/PanelEditor/types.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/dashboard/components/PanelEditor/utils.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -3213,14 +2784,14 @@ exports[`better eslint`] = { "public/app/features/dashboard/components/ShareModal/SharePublicDashboard/ModalAlerts/UnsupportedDataSourcesAlert.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], - "public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], "public/app/features/dashboard/components/SubMenu/AnnotationPicker.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], + "public/app/features/dashboard/components/SubMenu/DashboardLinksDashboard.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + ], "public/app/features/dashboard/components/SubMenu/SubMenu.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] @@ -3243,11 +2814,7 @@ exports[`better eslint`] = { ], "public/app/features/dashboard/components/TransformationsEditor/TransformationsEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/features/dashboard/components/VersionHistory/DiffGroup.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -3297,16 +2864,8 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"] ], - "public/app/features/dashboard/dashgrid/DashboardGrid.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/dashboard/dashgrid/DashboardPanel.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/dashboard/dashgrid/PanelStateWrapper.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/features/dashboard/dashgrid/SeriesVisibilityConfigFactory.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -3358,20 +2917,17 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "17"], [0, 0, 0, "Unexpected any. Specify a different type.", "18"], [0, 0, 0, "Unexpected any. Specify a different type.", "19"], - [0, 0, 0, "Unexpected any. Specify a different type.", "20"], + [0, 0, 0, "Do not use any type assertions.", "20"], [0, 0, 0, "Unexpected any. Specify a different type.", "21"], - [0, 0, 0, "Do not use any type assertions.", "22"], + [0, 0, 0, "Unexpected any. Specify a different type.", "22"], [0, 0, 0, "Unexpected any. Specify a different type.", "23"], [0, 0, 0, "Unexpected any. Specify a different type.", "24"], [0, 0, 0, "Unexpected any. Specify a different type.", "25"], - [0, 0, 0, "Unexpected any. Specify a different type.", "26"], - [0, 0, 0, "Unexpected any. Specify a different type.", "27"], + [0, 0, 0, "Do not use any type assertions.", "26"], + [0, 0, 0, "Do not use any type assertions.", "27"], [0, 0, 0, "Unexpected any. Specify a different type.", "28"], - [0, 0, 0, "Do not use any type assertions.", "29"], - [0, 0, 0, "Do not use any type assertions.", "30"], - [0, 0, 0, "Unexpected any. Specify a different type.", "31"], - [0, 0, 0, "Unexpected any. Specify a different type.", "32"], - [0, 0, 0, "Do not use any type assertions.", "33"] + [0, 0, 0, "Unexpected any. Specify a different type.", "29"], + [0, 0, 0, "Do not use any type assertions.", "30"] ], "public/app/features/dashboard/state/DashboardModel.repeat.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -3408,12 +2964,8 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "19"], [0, 0, 0, "Unexpected any. Specify a different type.", "20"], [0, 0, 0, "Unexpected any. Specify a different type.", "21"], - [0, 0, 0, "Unexpected any. Specify a different type.", "22"], - [0, 0, 0, "Unexpected any. Specify a different type.", "23"], - [0, 0, 0, "Unexpected any. Specify a different type.", "24"], - [0, 0, 0, "Unexpected any. Specify a different type.", "25"], - [0, 0, 0, "Do not use any type assertions.", "26"], - [0, 0, 0, "Unexpected any. Specify a different type.", "27"] + [0, 0, 0, "Do not use any type assertions.", "22"], + [0, 0, 0, "Unexpected any. Specify a different type.", "23"] ], "public/app/features/dashboard/state/PanelModel.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -3471,9 +3023,6 @@ exports[`better eslint`] = { "public/app/features/dashboard/state/initDashboard.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/features/dashboard/state/reducers.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/dashboard/utils/getPanelMenu.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -3488,17 +3037,12 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "public/app/features/datasources/components/BasicSettings.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/features/datasources/components/DataSourceReadOnlyMessage.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] + [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/features/datasources/components/DataSourceTestingStatus.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "3"] + [0, 0, 0, "Do not use any type assertions.", "2"] ], "public/app/features/datasources/components/DataSourceTypeCard.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] @@ -3651,8 +3195,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/features/dimensions/utils.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/features/explore/ContentOutline/ContentOutline.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -3867,8 +3410,7 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "2"], [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] + [0, 0, 0, "Styles should be written using objects.", "4"] ], "public/app/features/explore/TraceView/components/TracePageHeader/SpanFilters/SpanFilters.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -3988,6 +3530,9 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "4"], [0, 0, 0, "Styles should be written using objects.", "5"] ], + "public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/SpanFlameGraph.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/TextList.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -4169,9 +3714,8 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "5"] ], "public/app/features/expressions/ExpressionDatasource.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"] + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/features/expressions/components/Condition.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -4201,12 +3745,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/features/geo/format/geohash.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/geo/format/geojson.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/geo/gazetteer/gazetteer.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] @@ -4227,9 +3765,6 @@ exports[`better eslint`] = { "public/app/features/inspector/InspectDataTab.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], - "public/app/features/inspector/InspectErrorTab.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/inspector/InspectJSONTab.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], @@ -4247,11 +3782,9 @@ exports[`better eslint`] = { ], "public/app/features/inspector/QueryInspector.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "5"] + [0, 0, 0, "Styles should be written using objects.", "1"], + [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "2"], + [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "3"] ], "public/app/features/inspector/styles.ts:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -4266,12 +3799,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "9"], [0, 0, 0, "Styles should be written using objects.", "10"] ], - "public/app/features/invites/state/selectors.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], "public/app/features/library-panels/components/LibraryPanelInfo/LibraryPanelInfo.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -4288,14 +3815,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "7"], [0, 0, 0, "Styles should be written using objects.", "8"] ], - "public/app/features/library-panels/components/LibraryPanelsView/LibraryPanelsView.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] - ], "public/app/features/library-panels/components/LibraryPanelsView/actions.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -4320,11 +3839,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/features/live/centrifuge/LiveDataStream.test.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], "public/app/features/live/centrifuge/LiveDataStream.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -4334,9 +3848,6 @@ exports[`better eslint`] = { "public/app/features/live/centrifuge/serviceWorkerProxy.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/live/centrifuge/transferHandlers.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/live/data/amendTimeSeries.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], @@ -4344,9 +3855,6 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"] ], - "public/app/features/live/index.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/features/logs/components/LogDetailsRow.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -4482,10 +3990,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "13"], [0, 0, 0, "Unexpected any. Specify a different type.", "14"], [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"], - [0, 0, 0, "Unexpected any. Specify a different type.", "17"], - [0, 0, 0, "Unexpected any. Specify a different type.", "18"], - [0, 0, 0, "Unexpected any. Specify a different type.", "19"] + [0, 0, 0, "Unexpected any. Specify a different type.", "16"] ], "public/app/features/manage-dashboards/state/reducers.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -4495,27 +4000,13 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "4"] ], "public/app/features/org/state/actions.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/features/org/state/reducers.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/features/panel/components/VizTypePicker/PanelTypeCard.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"], - [0, 0, 0, "Styles should be written using objects.", "9"], - [0, 0, 0, "Styles should be written using objects.", "10"] + [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], "public/app/features/panel/components/VizTypePicker/VisualizationSuggestionCard.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -4524,12 +4015,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "3"], [0, 0, 0, "Styles should be written using objects.", "4"] ], - "public/app/features/panel/components/VizTypePicker/VizTypePicker.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/features/panel/components/VizTypePicker/types.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/panel/panellinks/linkSuppliers.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -4537,15 +4022,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"] - ], - "public/app/features/panel/state/actions.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/panel/state/reducers.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "public/app/features/playlist/EmptyQueryListBanner.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -4583,9 +4060,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "2"] ], - "public/app/features/plugins/admin/components/PluginDetailsDisabledError.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], "public/app/features/plugins/admin/components/PluginDetailsHeaderDependencies.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] @@ -4600,17 +4074,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "2"], [0, 0, 0, "Styles should be written using objects.", "3"] ], - "public/app/features/plugins/admin/components/PluginDetailsSignature.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], - "public/app/features/plugins/admin/components/PluginListItem.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] - ], "public/app/features/plugins/admin/components/PluginSignatureDetailsBadge.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -4624,9 +4087,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/features/plugins/admin/components/SearchField.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/plugins/admin/components/VersionList.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -4640,11 +4100,7 @@ exports[`better eslint`] = { ], "public/app/features/plugins/admin/pages/Browse.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/features/plugins/admin/state/actions.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -4652,9 +4108,6 @@ exports[`better eslint`] = { "public/app/features/plugins/admin/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/features/plugins/components/PluginsErrorsInfo.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] - ], "public/app/features/plugins/datasource_srv.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -4668,19 +4121,11 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "9"], [0, 0, 0, "Do not use any type assertions.", "10"], [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Do not use any type assertions.", "13"] - ], - "public/app/features/plugins/pluginSettings.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Do not use any type assertions.", "12"] ], "public/app/features/plugins/sandbox/distortion_map.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/plugins/sandbox/sandbox_components.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/plugins/sandbox/sandbox_plugin_loader.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], @@ -4703,9 +4148,7 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"] ], "public/app/features/plugins/sql/components/visual-query-builder/AwesomeQueryBuilder.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/features/plugins/sql/components/visual-query-builder/SQLWhereRow.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -4714,9 +4157,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"] + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "public/app/features/plugins/utils.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -4812,84 +4253,10 @@ exports[`better eslint`] = { "public/app/features/sandbox/TestStuffPage.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/search/components/DashboardListPage.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/features/search/components/ManageDashboardsNew.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"] - ], - "public/app/features/search/components/SearchCard.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"], - [0, 0, 0, "Styles should be written using objects.", "9"], - [0, 0, 0, "Styles should be written using objects.", "10"], - [0, 0, 0, "Styles should be written using objects.", "11"] - ], - "public/app/features/search/components/SearchCardExpanded.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"], - [0, 0, 0, "Styles should be written using objects.", "9"], - [0, 0, 0, "Styles should be written using objects.", "10"] - ], - "public/app/features/search/components/SearchItem.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] - ], - "public/app/features/search/hooks/useSearchKeyboardSelection.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/features/search/page/components/ActionRow.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/features/search/page/components/ConfirmDeleteModal.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/features/search/page/components/FolderSection.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"] - ], - "public/app/features/search/page/components/MoveToFolderModal.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/features/search/page/components/RootFolderView.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] - ], - "public/app/features/search/page/components/SearchResultsCards.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], "public/app/features/search/page/components/SearchResultsTable.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -4905,11 +4272,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "11"], [0, 0, 0, "Styles should be written using objects.", "12"] ], - "public/app/features/search/page/components/SearchView.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] - ], "public/app/features/search/page/components/columns.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -4923,27 +4285,15 @@ exports[`better eslint`] = { "public/app/features/search/service/utils.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/search/state/SearchStateManager.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], - "public/app/features/search/types.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/app/features/search/utils.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], - "public/app/features/serviceaccounts/ServiceAccountsListPage.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"], - [0, 0, 0, "Styles should be written using objects.", "9"] - ], + "public/app/features/search/state/SearchStateManager.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], + "public/app/features/search/types.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], + "public/app/features/search/utils.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "public/app/features/serviceaccounts/components/CreateTokenModal.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -4965,14 +4315,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "5"], [0, 0, 0, "Styles should be written using objects.", "6"] ], - "public/app/features/serviceaccounts/components/ServiceAccountsListItem.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"] - ], "public/app/features/serviceaccounts/state/reducers.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -5061,6 +4403,10 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "14"], [0, 0, 0, "Do not use any type assertions.", "15"] ], + "public/app/features/trails/SelectMetricTrailView.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + ], "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/BasicMatcherEditor.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -5094,9 +4440,17 @@ exports[`better eslint`] = { "public/app/features/transformers/configFromQuery/ConfigFromQueryTransformerEditor.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], - "public/app/features/transformers/editors/CalculateFieldTransformerEditor.tsx:5381": [ + "public/app/features/transformers/editors/CalculateFieldTransformerEditor/CumulativeOptionsEditor.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], + "public/app/features/transformers/editors/CalculateFieldTransformerEditor/ReduceRowOptionsEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], + "public/app/features/transformers/editors/CalculateFieldTransformerEditor/WindowOptionsEditor.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Do not use any type assertions.", "1"], + [0, 0, 0, "Do not use any type assertions.", "2"] + ], "public/app/features/transformers/editors/ConvertFieldTypeTransformerEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -5112,13 +4466,7 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "2"] ], "public/app/features/transformers/editors/ReduceTransformerEditor.tsx:5381": [ - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], - [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"] - ], - "public/app/features/transformers/editors/RenameByRegexTransformer.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/features/transformers/editors/SortByTransformerEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -5191,9 +4539,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"], [0, 0, 0, "Styles should be written using objects.", "2"] ], - "public/app/features/users/state/reducers.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/features/variables/adapters.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -5214,9 +4559,6 @@ exports[`better eslint`] = { "public/app/features/variables/datasource/actions.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/features/variables/datasource/reducer.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/features/variables/editor/LegacyVariableQueryEditor.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] ], @@ -5298,9 +4640,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"] ], - "public/app/features/variables/interval/reducer.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/features/variables/pickers/OptionsPicker/actions.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -5382,9 +4721,8 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/features/variables/query/reducer.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/features/variables/query/variableQueryObserver.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -5394,13 +4732,9 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] ], - "public/app/features/variables/shared/testing/datasourceVariableBuilder.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/variables/shared/testing/optionsVariableBuilder.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/features/variables/shared/testing/variableBuilder.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -5411,15 +4745,8 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Do not use any type assertions.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"] + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Do not use any type assertions.", "6"] ], "public/app/features/variables/state/keyedVariablesReducer.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -5450,13 +4777,12 @@ exports[`better eslint`] = { "public/app/features/variables/system/adapter.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Do not use any type assertions.", "5"], [0, 0, 0, "Do not use any type assertions.", "6"], - [0, 0, 0, "Do not use any type assertions.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"] + [0, 0, 0, "Unexpected any. Specify a different type.", "7"] ], "public/app/features/variables/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -5473,9 +4799,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"] + [0, 0, 0, "Do not use any type assertions.", "7"] ], "public/app/features/visualization/data-hover/DataHoverRows.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -5511,8 +4835,7 @@ exports[`better eslint`] = { ], "public/app/plugins/datasource/cloud-monitoring/CloudMonitoringMetricFindQuery.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/cloud-monitoring/annotationSupport.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -5521,42 +4844,24 @@ exports[`better eslint`] = { "public/app/plugins/datasource/cloud-monitoring/components/Aggregation.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/plugins/datasource/cloud-monitoring/components/AliasBy.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "public/app/plugins/datasource/cloud-monitoring/components/CloudMonitoringCheatSheet.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], - "public/app/plugins/datasource/cloud-monitoring/components/MQLQueryEditor.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/datasource/cloud-monitoring/components/VariableQueryEditor.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/plugins/datasource/cloud-monitoring/components/VisualMetricQueryEditor.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] + [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/plugins/datasource/cloud-monitoring/datasource.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], - [0, 0, 0, "Do not use any type assertions.", "6"] + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Do not use any type assertions.", "3"] ], "public/app/plugins/datasource/cloud-monitoring/functions.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/plugins/datasource/cloud-monitoring/types/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -5580,9 +4885,6 @@ exports[`better eslint`] = { "public/app/plugins/datasource/cloudwatch/components/shared/LogGroups/LegacyLogGroupNamesSelection.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], - "public/app/plugins/datasource/cloudwatch/components/shared/LogGroups/LogGroupsField.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], "public/app/plugins/datasource/cloudwatch/datasource.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -5598,9 +4900,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "public/app/plugins/datasource/cloudwatch/query-runner/CloudWatchLogsQueryRunner.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/plugins/datasource/cloudwatch/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -5612,12 +4911,10 @@ exports[`better eslint`] = { ], "public/app/plugins/datasource/cloudwatch/utils/datalinks.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/plugins/datasource/cloudwatch/utils/logsRetry.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/datasource/dashboard/DashboardQueryEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -5632,27 +4929,27 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "5"], [0, 0, 0, "Unexpected any. Specify a different type.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Do not use any type assertions.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], + [0, 0, 0, "Do not use any type assertions.", "10"], + [0, 0, 0, "Unexpected any. Specify a different type.", "11"], + [0, 0, 0, "Unexpected any. Specify a different type.", "12"], [0, 0, 0, "Unexpected any. Specify a different type.", "13"], [0, 0, 0, "Unexpected any. Specify a different type.", "14"], [0, 0, 0, "Unexpected any. Specify a different type.", "15"], [0, 0, 0, "Unexpected any. Specify a different type.", "16"], [0, 0, 0, "Unexpected any. Specify a different type.", "17"], - [0, 0, 0, "Unexpected any. Specify a different type.", "18"], + [0, 0, 0, "Do not use any type assertions.", "18"], [0, 0, 0, "Unexpected any. Specify a different type.", "19"], [0, 0, 0, "Unexpected any. Specify a different type.", "20"], [0, 0, 0, "Unexpected any. Specify a different type.", "21"], [0, 0, 0, "Unexpected any. Specify a different type.", "22"], [0, 0, 0, "Unexpected any. Specify a different type.", "23"], [0, 0, 0, "Unexpected any. Specify a different type.", "24"], - [0, 0, 0, "Do not use any type assertions.", "25"], + [0, 0, 0, "Unexpected any. Specify a different type.", "25"], [0, 0, 0, "Unexpected any. Specify a different type.", "26"], [0, 0, 0, "Unexpected any. Specify a different type.", "27"], [0, 0, 0, "Unexpected any. Specify a different type.", "28"], @@ -5660,19 +4957,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "30"], [0, 0, 0, "Unexpected any. Specify a different type.", "31"], [0, 0, 0, "Unexpected any. Specify a different type.", "32"], - [0, 0, 0, "Unexpected any. Specify a different type.", "33"], - [0, 0, 0, "Unexpected any. Specify a different type.", "34"], - [0, 0, 0, "Unexpected any. Specify a different type.", "35"], - [0, 0, 0, "Unexpected any. Specify a different type.", "36"], - [0, 0, 0, "Unexpected any. Specify a different type.", "37"], - [0, 0, 0, "Unexpected any. Specify a different type.", "38"], - [0, 0, 0, "Unexpected any. Specify a different type.", "39"], - [0, 0, 0, "Unexpected any. Specify a different type.", "40"], - [0, 0, 0, "Unexpected any. Specify a different type.", "41"], - [0, 0, 0, "Unexpected any. Specify a different type.", "42"], - [0, 0, 0, "Unexpected any. Specify a different type.", "43"], - [0, 0, 0, "Unexpected any. Specify a different type.", "44"], - [0, 0, 0, "Unexpected any. Specify a different type.", "45"] + [0, 0, 0, "Unexpected any. Specify a different type.", "33"] ], "public/app/plugins/datasource/elasticsearch/LanguageProvider.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -5696,17 +4981,12 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Unexpected any. Specify a different type.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Do not use any type assertions.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"] + [0, 0, 0, "Unexpected any. Specify a different type.", "8"] ], "public/app/plugins/datasource/elasticsearch/components/AddRemove.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] + [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/plugins/datasource/elasticsearch/components/MetricPicker.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -5723,21 +5003,14 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "2"] ], "public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/SettingsEditor/TermsSettingsEditor.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/aggregations.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/actions.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/datasource/elasticsearch/components/QueryEditor/BucketAggregationsEditor/state/reducer.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/plugins/datasource/elasticsearch/components/QueryEditor/ElasticsearchQueryContext.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/MetricEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -5757,11 +5030,6 @@ exports[`better eslint`] = { "public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/aggregations.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/actions.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], "public/app/plugins/datasource/elasticsearch/components/QueryEditor/MetricAggregationsEditor/state/reducer.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -5800,13 +5068,11 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "2"] ], "public/app/plugins/datasource/elasticsearch/datasource.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"] + [0, 0, 0, "Unexpected any. Specify a different type.", "4"] ], "public/app/plugins/datasource/elasticsearch/hooks/useStatelessReducer.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -5818,32 +5084,22 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/plugins/datasource/grafana-testdata-datasource/ConfigEditor.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/datasource/grafana-testdata-datasource/QueryEditor.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"] + [0, 0, 0, "Do not use any type assertions.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"] ], "public/app/plugins/datasource/grafana-testdata-datasource/components/RandomWalkEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"] - ], - "public/app/plugins/datasource/grafana-testdata-datasource/components/RawFrameEditor.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Do not use any type assertions.", "2"] ], "public/app/plugins/datasource/grafana-testdata-datasource/components/SimulationQueryEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/plugins/datasource/grafana-testdata-datasource/components/SimulationSchemaForm.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -5855,9 +5111,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/grafana-testdata-datasource/nodeGraphUtils.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/datasource/grafana-testdata-datasource/runStreams.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -5875,11 +5129,6 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "6"], [0, 0, 0, "Styles should be written using objects.", "7"] ], - "public/app/plugins/datasource/grafana/components/SearchEditor.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"] - ], "public/app/plugins/datasource/grafana/components/TimePickerInput.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"], @@ -5898,22 +5147,18 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Do not use any type assertions.", "6"], [0, 0, 0, "Do not use any type assertions.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"] + [0, 0, 0, "Unexpected any. Specify a different type.", "8"], + [0, 0, 0, "Do not use any type assertions.", "9"] ], "public/app/plugins/datasource/graphite/components/AddGraphiteFunction.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/plugins/datasource/graphite/components/FunctionEditor.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Styles should be written using objects.", "0"] ], "public/app/plugins/datasource/graphite/components/FunctionParamEditor.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -5958,16 +5203,16 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], + [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "5"], [0, 0, 0, "Unexpected any. Specify a different type.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], + [0, 0, 0, "Do not use any type assertions.", "10"], [0, 0, 0, "Do not use any type assertions.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], + [0, 0, 0, "Unexpected any. Specify a different type.", "12"], [0, 0, 0, "Unexpected any. Specify a different type.", "13"], [0, 0, 0, "Unexpected any. Specify a different type.", "14"], [0, 0, 0, "Unexpected any. Specify a different type.", "15"], @@ -6009,15 +5254,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "51"], [0, 0, 0, "Unexpected any. Specify a different type.", "52"], [0, 0, 0, "Unexpected any. Specify a different type.", "53"], - [0, 0, 0, "Unexpected any. Specify a different type.", "54"], - [0, 0, 0, "Unexpected any. Specify a different type.", "55"], - [0, 0, 0, "Unexpected any. Specify a different type.", "56"], - [0, 0, 0, "Unexpected any. Specify a different type.", "57"], - [0, 0, 0, "Unexpected any. Specify a different type.", "58"], - [0, 0, 0, "Unexpected any. Specify a different type.", "59"], - [0, 0, 0, "Unexpected any. Specify a different type.", "60"], - [0, 0, 0, "Unexpected any. Specify a different type.", "61"], - [0, 0, 0, "Unexpected any. Specify a different type.", "62"] + [0, 0, 0, "Unexpected any. Specify a different type.", "54"] ], "public/app/plugins/datasource/graphite/gfunc.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6030,11 +5267,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"] + [0, 0, 0, "Unexpected any. Specify a different type.", "10"] ], "public/app/plugins/datasource/graphite/graphite_query.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6052,15 +5285,11 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "12"], [0, 0, 0, "Unexpected any. Specify a different type.", "13"], [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], + [0, 0, 0, "Do not use any type assertions.", "15"], [0, 0, 0, "Unexpected any. Specify a different type.", "16"], [0, 0, 0, "Unexpected any. Specify a different type.", "17"], [0, 0, 0, "Unexpected any. Specify a different type.", "18"], - [0, 0, 0, "Do not use any type assertions.", "19"], - [0, 0, 0, "Unexpected any. Specify a different type.", "20"], - [0, 0, 0, "Unexpected any. Specify a different type.", "21"], - [0, 0, 0, "Unexpected any. Specify a different type.", "22"], - [0, 0, 0, "Unexpected any. Specify a different type.", "23"] + [0, 0, 0, "Unexpected any. Specify a different type.", "19"] ], "public/app/plugins/datasource/graphite/lexer.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6074,11 +5303,6 @@ exports[`better eslint`] = { "public/app/plugins/datasource/graphite/migrations.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/plugins/datasource/graphite/parser.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], "public/app/plugins/datasource/graphite/specs/graphite_query.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -6095,17 +5319,14 @@ exports[`better eslint`] = { ], "public/app/plugins/datasource/graphite/state/store.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"] + [0, 0, 0, "Do not use any type assertions.", "1"] ], "public/app/plugins/datasource/graphite/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/graphite/utils.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/datasource/influxdb/components/editor/config/ConfigEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -6138,9 +5359,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "12"], [0, 0, 0, "Unexpected any. Specify a different type.", "13"], [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"], - [0, 0, 0, "Do not use any type assertions.", "17"] + [0, 0, 0, "Do not use any type assertions.", "15"] ], "public/app/plugins/datasource/influxdb/influx_query_model.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6155,14 +5374,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "9"], [0, 0, 0, "Unexpected any. Specify a different type.", "10"], [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"], - [0, 0, 0, "Unexpected any. Specify a different type.", "17"], - [0, 0, 0, "Unexpected any. Specify a different type.", "18"], - [0, 0, 0, "Unexpected any. Specify a different type.", "19"] + [0, 0, 0, "Unexpected any. Specify a different type.", "12"] ], "public/app/plugins/datasource/influxdb/influx_series.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6210,8 +5422,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "12"], [0, 0, 0, "Unexpected any. Specify a different type.", "13"], [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"] + [0, 0, 0, "Unexpected any. Specify a different type.", "15"] ], "public/app/plugins/datasource/influxdb/response_parser.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6232,14 +5443,8 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "1"] ], "public/app/plugins/datasource/jaeger/datasource.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"] + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/jaeger/testResponse.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6248,13 +5453,9 @@ exports[`better eslint`] = { "public/app/plugins/datasource/jaeger/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/plugins/datasource/jaeger/util.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/datasource/loki/LanguageProvider.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/loki/LiveStreams.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -6286,9 +5487,7 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "10"], [0, 0, 0, "Styles should be written using objects.", "11"], [0, 0, 0, "Styles should be written using objects.", "12"], - [0, 0, 0, "Styles should be written using objects.", "13"], - [0, 0, 0, "Do not use any type assertions.", "14"], - [0, 0, 0, "Do not use any type assertions.", "15"] + [0, 0, 0, "Styles should be written using objects.", "13"] ], "public/app/plugins/datasource/loki/components/LokiOptionFields.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -6331,8 +5530,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"] + [0, 0, 0, "Unexpected any. Specify a different type.", "5"] ], "public/app/plugins/datasource/loki/queryUtils.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -6364,8 +5562,7 @@ exports[`better eslint`] = { ], "public/app/plugins/datasource/loki/streaming.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/datasource/opentsdb/components/OpenTsdbQueryEditor.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -6451,15 +5648,11 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/plugins/datasource/prometheus/components/PromLink.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/plugins/datasource/prometheus/components/PromQueryField.test.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/datasource/prometheus/components/PromQueryField.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -6473,9 +5666,7 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "8"], [0, 0, 0, "Styles should be written using objects.", "9"], [0, 0, 0, "Styles should be written using objects.", "10"], - [0, 0, 0, "Styles should be written using objects.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], - [0, 0, 0, "Do not use any type assertions.", "13"] + [0, 0, 0, "Styles should be written using objects.", "11"] ], "public/app/plugins/datasource/prometheus/components/monaco-query-field/MonacoQueryField.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"], @@ -6532,22 +5723,10 @@ exports[`better eslint`] = { [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/plugins/datasource/prometheus/configuration/PromSettings.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/plugins/datasource/prometheus/datasource.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"] + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/plugins/datasource/prometheus/datasource.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6561,44 +5740,20 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Do not use any type assertions.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"], - [0, 0, 0, "Unexpected any. Specify a different type.", "17"], - [0, 0, 0, "Unexpected any. Specify a different type.", "18"], - [0, 0, 0, "Unexpected any. Specify a different type.", "19"], - [0, 0, 0, "Unexpected any. Specify a different type.", "20"], - [0, 0, 0, "Unexpected any. Specify a different type.", "21"], - [0, 0, 0, "Unexpected any. Specify a different type.", "22"], - [0, 0, 0, "Unexpected any. Specify a different type.", "23"], - [0, 0, 0, "Unexpected any. Specify a different type.", "24"], - [0, 0, 0, "Unexpected any. Specify a different type.", "25"], - [0, 0, 0, "Unexpected any. Specify a different type.", "26"], - [0, 0, 0, "Unexpected any. Specify a different type.", "27"], - [0, 0, 0, "Unexpected any. Specify a different type.", "28"] + [0, 0, 0, "Unexpected any. Specify a different type.", "11"], + [0, 0, 0, "Unexpected any. Specify a different type.", "12"] ], "public/app/plugins/datasource/prometheus/language_provider.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"] + [0, 0, 0, "Unexpected any. Specify a different type.", "4"] ], "public/app/plugins/datasource/prometheus/language_utils.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Do not use any type assertions.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Do not use any type assertions.", "7"], - [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"] + [0, 0, 0, "Do not use any type assertions.", "2"] ], "public/app/plugins/datasource/prometheus/metric_find_query.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -6607,7 +5762,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"], [0, 0, 0, "Unexpected any. Specify a different type.", "4"] ], "public/app/plugins/datasource/prometheus/query_hints.ts:5381": [ @@ -6706,6 +5861,9 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "17"], [0, 0, 0, "Styles should be written using objects.", "18"] ], + "public/app/plugins/datasource/prometheus/querybuilder/operationUtils.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "public/app/plugins/datasource/prometheus/querybuilder/shared/LabelFilterItem.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], @@ -6734,9 +5892,6 @@ exports[`better eslint`] = { [0, 0, 0, "Styles should be written using objects.", "0"], [0, 0, 0, "Styles should be written using objects.", "1"] ], - "public/app/plugins/datasource/prometheus/querybuilder/shared/operationUtils.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/plugins/datasource/prometheus/querybuilder/shared/parsingUtils.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -6746,44 +5901,12 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/plugins/datasource/prometheus/result_transformer.test.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"], - [0, 0, 0, "Unexpected any. Specify a different type.", "17"], - [0, 0, 0, "Unexpected any. Specify a different type.", "18"], - [0, 0, 0, "Unexpected any. Specify a different type.", "19"], - [0, 0, 0, "Unexpected any. Specify a different type.", "20"], - [0, 0, 0, "Unexpected any. Specify a different type.", "21"], - [0, 0, 0, "Unexpected any. Specify a different type.", "22"], - [0, 0, 0, "Unexpected any. Specify a different type.", "23"], - [0, 0, 0, "Unexpected any. Specify a different type.", "24"], - [0, 0, 0, "Unexpected any. Specify a different type.", "25"], - [0, 0, 0, "Unexpected any. Specify a different type.", "26"], - [0, 0, 0, "Unexpected any. Specify a different type.", "27"], - [0, 0, 0, "Unexpected any. Specify a different type.", "28"], - [0, 0, 0, "Unexpected any. Specify a different type.", "29"], - [0, 0, 0, "Unexpected any. Specify a different type.", "30"], - [0, 0, 0, "Unexpected any. Specify a different type.", "31"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/datasource/prometheus/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/plugins/datasource/tempo/LokiSearch.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -6816,9 +5939,8 @@ exports[`better eslint`] = { ], "public/app/plugins/datasource/tempo/ServiceGraphSection.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] + [0, 0, 0, "Styles should be written using objects.", "1"], + [0, 0, 0, "Styles should be written using objects.", "2"] ], "public/app/plugins/datasource/tempo/configuration/ConfigEditor.tsx:5381": [ [0, 0, 0, "Styles should be written using objects.", "0"] @@ -6855,17 +5977,10 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], + [0, 0, 0, "Do not use any type assertions.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"], - [0, 0, 0, "Do not use any type assertions.", "11"], - [0, 0, 0, "Do not use any type assertions.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"], - [0, 0, 0, "Unexpected any. Specify a different type.", "16"] + [0, 0, 0, "Unexpected any. Specify a different type.", "9"] ], "public/app/plugins/datasource/tempo/language_provider.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -7006,77 +6121,24 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "public/app/plugins/panel/canvas/components/CanvasContextMenu.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/plugins/panel/canvas/components/CanvasTooltip.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/plugins/panel/canvas/components/SetBackground.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"] - ], - "public/app/plugins/panel/canvas/components/connections/ConnectionAnchors.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] - ], - "public/app/plugins/panel/canvas/components/connections/ConnectionSVG.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/plugins/panel/canvas/editor/connectionEditor.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/panel/canvas/editor/element/APIEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/plugins/panel/canvas/editor/element/ConstraintSelectionBox.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"] - ], "public/app/plugins/panel/canvas/editor/element/PlacementEditor.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/plugins/panel/canvas/editor/element/QuickPositioning.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], "public/app/plugins/panel/canvas/editor/element/elementEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "public/app/plugins/panel/canvas/editor/inline/InlineEdit.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"] - ], "public/app/plugins/panel/canvas/editor/inline/InlineEditBody.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"] + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "public/app/plugins/panel/canvas/editor/layer/TreeNavigationEditor.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] - ], - "public/app/plugins/panel/canvas/editor/layer/TreeNodeTitle.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], "public/app/plugins/panel/canvas/editor/layer/layerEditor.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -7164,9 +6226,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] ], - "public/app/plugins/panel/geomap/utils/selection.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/plugins/panel/geomap/utils/tooltip.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -7210,18 +6269,11 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/heatmap/HeatmapPanel.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/panel/heatmap/migrations.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/plugins/panel/heatmap/module.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] - ], "public/app/plugins/panel/heatmap/palettes.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -7249,11 +6301,9 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "16"] ], "public/app/plugins/panel/histogram/Histogram.tsx:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"] + [0, 0, 0, "Do not use any type assertions.", "0"], + [0, 0, 0, "Do not use any type assertions.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/plugins/panel/live/LiveChannelEditor.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -7275,18 +6325,6 @@ exports[`better eslint`] = { "public/app/plugins/panel/logs/LogsPanel.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/plugins/panel/news/component/News.tsx:5381": [ - [0, 0, 0, "Styles should be written using objects.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"], - [0, 0, 0, "Styles should be written using objects.", "2"], - [0, 0, 0, "Styles should be written using objects.", "3"], - [0, 0, 0, "Styles should be written using objects.", "4"], - [0, 0, 0, "Styles should be written using objects.", "5"], - [0, 0, 0, "Styles should be written using objects.", "6"], - [0, 0, 0, "Styles should be written using objects.", "7"], - [0, 0, 0, "Styles should be written using objects.", "8"], - [0, 0, 0, "Styles should be written using objects.", "9"] - ], "public/app/plugins/panel/nodeGraph/Edge.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -7349,9 +6387,7 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/nodeGraph/utils.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/plugins/panel/piechart/PieChart.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"], @@ -7617,7 +6653,8 @@ exports[`better eslint`] = { ], "public/app/plugins/panel/xychart/XYChartPanel2.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Styles should be written using objects.", "1"] + [0, 0, 0, "Do not use any type assertions.", "1"], + [0, 0, 0, "Styles should be written using objects.", "2"] ], "public/app/plugins/panel/xychart/dims.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -7638,8 +6675,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Do not use any type assertions.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], - [0, 0, 0, "Do not use any type assertions.", "10"], - [0, 0, 0, "Do not use any type assertions.", "11"] + [0, 0, 0, "Do not use any type assertions.", "10"] ], "public/app/store/configureStore.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -7697,19 +6733,8 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"] ], - "public/app/types/templates.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/types/unified-alerting-dto.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"] - ], - "public/test/core/redux/mocks.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/test/core/redux/reducerTester.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/test/core/redux/reduxTester.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -7727,15 +6752,11 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"], [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"] + [0, 0, 0, "Unexpected any. Specify a different type.", "7"] ], "public/test/global-jquery-shim.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/test/helpers/convertToStoreState.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/test/helpers/getDashboardModel.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -7748,20 +6769,6 @@ exports[`better eslint`] = { "public/test/lib/common.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/test/matchers/index.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/test/matchers/toEmitValuesWith.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] - ], - "public/test/matchers/utils.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], - "public/test/mocks/workers.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/test/specs/helpers.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -7774,11 +6781,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "8"], [0, 0, 0, "Unexpected any. Specify a different type.", "9"], [0, 0, 0, "Unexpected any. Specify a different type.", "10"], - [0, 0, 0, "Unexpected any. Specify a different type.", "11"], - [0, 0, 0, "Unexpected any. Specify a different type.", "12"], - [0, 0, 0, "Unexpected any. Specify a different type.", "13"], - [0, 0, 0, "Unexpected any. Specify a different type.", "14"], - [0, 0, 0, "Unexpected any. Specify a different type.", "15"] + [0, 0, 0, "Unexpected any. Specify a different type.", "11"] ] }` }; diff --git a/.drone.yml b/.drone.yml index aa50476196c7e..c83e4cb51f279 100644 --- a/.drone.yml +++ b/.drone.yml @@ -17,14 +17,14 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - ./bin/build verify-drone @@ -67,21 +67,21 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - go install github.com/bazelbuild/buildtools/buildifier@latest - buildifier --lint=warn -mode=check -r . depends_on: - compile-build-cmd - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: lint-starlark trigger: event: @@ -117,7 +117,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -217,7 +217,7 @@ steps: name: clone-enterprise - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -306,7 +306,7 @@ steps: name: clone-enterprise - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -316,7 +316,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -325,21 +325,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go test -tags requires_buildifer -short -covermode=atomic -timeout=5m ./pkg/... depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend - commands: - apk add --update build-base @@ -348,7 +348,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend-integration trigger: event: @@ -365,6 +365,7 @@ trigger: - go.sum - go.mod - public/app/plugins/**/plugin.json + - docs/sources/setup-grafana/configure-grafana/feature-toggles/** - devenv/** type: docker volumes: @@ -390,14 +391,14 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - apk add --update curl jq bash @@ -424,7 +425,7 @@ steps: - apk add --update make - make gen-go depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - apk add --update make build-base @@ -433,16 +434,16 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: lint-backend - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: validate-openapi-spec trigger: event: @@ -485,7 +486,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - mkdir -p bin @@ -498,7 +499,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -508,7 +509,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -517,14 +518,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - yarn install --immutable @@ -556,9 +557,9 @@ steps: token: from_secret: drone_token - commands: - - /src/grafana-build package --distro=linux/amd64,linux/arm64 --go-version=1.20.10 - --yarn-cache=$$YARN_CACHE_FOLDER --build-id=$$DRONE_BUILD_NUMBER --grafana-dir=$$PWD - > packages.txt + - /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64 + --go-version=1.21.3 --yarn-cache=$$YARN_CACHE_FOLDER --build-id=$$DRONE_BUILD_NUMBER + --grafana-dir=$$PWD > packages.txt depends_on: - yarn-install image: grafana/grafana-build:main @@ -579,7 +580,7 @@ steps: GF_APP_MODE: development GF_SERVER_HTTP_PORT: "3001" GF_SERVER_ROUTER_LOGGING: "1" - image: alpine:3.18.3 + image: alpine:3.18.4 name: grafana-server - commands: - ./bin/build e2e-tests --port 3001 --suite dashboards-suite @@ -699,13 +700,15 @@ steps: name: test-a11y-frontend - commands: - docker run --privileged --rm tonistiigi/binfmt --install all - - /src/grafana-build docker $(cat packages.txt | grep tar.gz | grep -v docker | - grep -v sha256 | awk '{print "--package=" $0}') --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.18.3 - --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{ - .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' > docker.txt + - /src/grafana-build artifacts -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu + -a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu --yarn-cache=$$YARN_CACHE_FOLDER + --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.18.4 + --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --grafana-dir=$$PWD + --ubuntu-tag-format='{{ .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' > + docker.txt - find ./dist -name '*docker*.tar.gz' -type f | xargs -n1 docker load -i depends_on: - - rgm-package + - yarn-install image: grafana/grafana-build:main name: rgm-build-docker pull: always @@ -799,7 +802,7 @@ services: - commands: - /bin/mimir -target=backend environment: {} - image: grafana/mimir:latest + image: us.gcr.io/kubernetes-dev/mimir:gotjosh-state-config-grafana-663a0ae78 name: mimir_backend - environment: {} image: redis:6.2.11-alpine @@ -840,11 +843,11 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -854,7 +857,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -863,14 +866,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -891,7 +894,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql57:3306 -timeout 120s @@ -912,7 +915,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql57 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-5.7-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -933,7 +936,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -948,7 +951,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -963,7 +966,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -972,15 +975,14 @@ steps: - commands: - apk add --update build-base - go clean -testcache - - go test -run TestIntegrationRemoteAlertmanager -covermode=atomic -timeout=2m ./pkg/services/ngalert/notifier/... + - go test -run TestIntegrationRemoteAlertmanager -covermode=atomic -timeout=2m ./pkg/services/ngalert/... depends_on: - wire-install - wait-for-remote-alertmanager environment: - AM_PASSWORD: test AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: remote-alertmanager-integration-tests trigger: event: @@ -1030,7 +1032,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -1067,7 +1069,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue trigger: event: @@ -1107,7 +1109,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - apt-get update -yq && apt-get install shellcheck @@ -1174,7 +1176,7 @@ steps: environment: GITHUB_TOKEN: from_secret: github_token - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: swagger-gen trigger: event: @@ -1243,7 +1245,7 @@ services: - commands: - /bin/mimir -target=backend environment: {} - image: grafana/mimir:latest + image: us.gcr.io/kubernetes-dev/mimir:gotjosh-state-config-grafana-663a0ae78 name: mimir_backend - environment: {} image: redis:6.2.11-alpine @@ -1275,7 +1277,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -1286,7 +1288,7 @@ steps: - CODEGEN_VERIFY=1 make gen-cue depends_on: - clone-enterprise - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1296,14 +1298,14 @@ steps: - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: - clone-enterprise - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - apk add --update build-base @@ -1311,7 +1313,7 @@ steps: - go test -v -run=^$ -benchmem -timeout=1h -count=8 -bench=. ${GO_PACKAGES} depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: sqlite-benchmark-integration-tests - commands: - apk add --update build-base @@ -1323,7 +1325,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: postgres-benchmark-integration-tests - commands: - apk add --update build-base @@ -1334,7 +1336,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql57 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-5.7-benchmark-integration-tests - commands: - apk add --update build-base @@ -1345,7 +1347,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-8.0-benchmark-integration-tests trigger: event: @@ -1385,7 +1387,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -1422,7 +1424,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue trigger: branch: main @@ -1460,7 +1462,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -1517,7 +1519,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -1584,7 +1586,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -1594,7 +1596,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1603,21 +1605,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go test -tags requires_buildifer -short -covermode=atomic -timeout=5m ./pkg/... depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend - commands: - apk add --update build-base @@ -1626,7 +1628,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend-integration trigger: branch: main @@ -1663,20 +1665,20 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - apk add --update make - make gen-go depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - apk add --update make build-base @@ -1685,16 +1687,16 @@ steps: - wire-install environment: CGO_ENABLED: "1" - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: lint-backend - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: validate-openapi-spec - commands: - ./bin/build verify-drone @@ -1737,7 +1739,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - mkdir -p bin @@ -1750,7 +1752,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -1760,7 +1762,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1769,14 +1771,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - yarn install --immutable @@ -1807,9 +1809,9 @@ steps: image: node:20.9.0-alpine name: build-frontend-packages - commands: - - /src/grafana-build package --distro=linux/amd64,linux/arm64 --go-version=1.20.10 - --yarn-cache=$$YARN_CACHE_FOLDER --build-id=$$DRONE_BUILD_NUMBER --grafana-dir=$$PWD - > packages.txt + - /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64 + --go-version=1.21.3 --yarn-cache=$$YARN_CACHE_FOLDER --build-id=$$DRONE_BUILD_NUMBER + --grafana-dir=$$PWD > packages.txt depends_on: - update-package-json-version image: grafana/grafana-build:main @@ -1830,7 +1832,7 @@ steps: GF_APP_MODE: development GF_SERVER_HTTP_PORT: "3001" GF_SERVER_ROUTER_LOGGING: "1" - image: alpine:3.18.3 + image: alpine:3.18.4 name: grafana-server - commands: - ./bin/build e2e-tests --port 3001 --suite dashboards-suite @@ -1986,13 +1988,15 @@ steps: - grafana/grafana - commands: - docker run --privileged --rm tonistiigi/binfmt --install all - - /src/grafana-build docker $(cat packages.txt | grep tar.gz | grep -v docker | - grep -v sha256 | awk '{print "--package=" $0}') --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.18.3 - --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{ - .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' > docker.txt + - /src/grafana-build artifacts -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu + -a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu --yarn-cache=$$YARN_CACHE_FOLDER + --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.18.4 + --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --grafana-dir=$$PWD + --ubuntu-tag-format='{{ .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' > + docker.txt - find ./dist -name '*docker*.tar.gz' -type f | xargs -n1 docker load -i depends_on: - - rgm-package + - update-package-json-version image: grafana/grafana-build:main name: rgm-build-docker pull: always @@ -2169,7 +2173,7 @@ services: - commands: - /bin/mimir -target=backend environment: {} - image: grafana/mimir:latest + image: us.gcr.io/kubernetes-dev/mimir:gotjosh-state-config-grafana-663a0ae78 name: mimir_backend - environment: {} image: redis:6.2.11-alpine @@ -2189,11 +2193,11 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -2203,7 +2207,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -2212,14 +2216,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -2240,7 +2244,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql57:3306 -timeout 120s @@ -2261,7 +2265,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql57 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-5.7-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -2282,7 +2286,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -2297,7 +2301,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -2312,7 +2316,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -2321,15 +2325,14 @@ steps: - commands: - apk add --update build-base - go clean -testcache - - go test -run TestIntegrationRemoteAlertmanager -covermode=atomic -timeout=2m ./pkg/services/ngalert/notifier/... + - go test -run TestIntegrationRemoteAlertmanager -covermode=atomic -timeout=2m ./pkg/services/ngalert/... depends_on: - wire-install - wait-for-remote-alertmanager environment: - AM_PASSWORD: test AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: remote-alertmanager-integration-tests trigger: branch: main @@ -2506,7 +2509,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - mkdir -p bin @@ -2519,7 +2522,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - ./bin/build artifacts docker fetch --edition oss @@ -2615,7 +2618,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - ./bin/build artifacts packages --tag $${DRONE_TAG} --src-bucket $${PRERELEASE_BUCKET} @@ -2684,7 +2687,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - yarn install --immutable @@ -2749,7 +2752,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - depends_on: - compile-build-cmd @@ -2838,6 +2841,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token + ALPINE_BASE: alpine:3.18.4 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -2854,7 +2858,7 @@ steps: from_secret: gcp_key_base64 GITHUB_TOKEN: from_secret: github_token - GO_VERSION: 1.20.10 + GO_VERSION: 1.21.3 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -2865,6 +2869,7 @@ steps: from_secret: npm_token STORYBOOK_DESTINATION: from_secret: rgm_storybook_destination + UBUNTU_BASE: ubuntu:22.04 image: grafana/grafana-build:main name: rgm-build pull: always @@ -2910,13 +2915,13 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: compile-build-cmd - commands: - ./bin/build whatsnew-checker depends_on: - compile-build-cmd - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: whats-new-checker trigger: event: @@ -2951,7 +2956,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -3006,7 +3011,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -3016,7 +3021,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -3025,21 +3030,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go test -tags requires_buildifer -short -covermode=atomic -timeout=5m ./pkg/... depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend - commands: - apk add --update build-base @@ -3048,7 +3053,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend-integration trigger: event: @@ -3087,6 +3092,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token + ALPINE_BASE: alpine:3.18.4 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -3103,7 +3109,7 @@ steps: from_secret: gcp_key_base64 GITHUB_TOKEN: from_secret: github_token - GO_VERSION: 1.20.10 + GO_VERSION: 1.21.3 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -3114,6 +3120,7 @@ steps: from_secret: npm_token STORYBOOK_DESTINATION: from_secret: rgm_storybook_destination + UBUNTU_BASE: ubuntu:22.04 image: grafana/grafana-build:main name: rgm-build pull: always @@ -3265,6 +3272,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token + ALPINE_BASE: alpine:3.18.4 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -3281,7 +3289,7 @@ steps: from_secret: gcp_key_base64 GITHUB_TOKEN: from_secret: github_token - GO_VERSION: 1.20.10 + GO_VERSION: 1.21.3 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -3292,6 +3300,7 @@ steps: from_secret: npm_token STORYBOOK_DESTINATION: from_secret: rgm_storybook_destination + UBUNTU_BASE: ubuntu:22.04 image: grafana/grafana-build:main name: rgm-build pull: always @@ -3363,7 +3372,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - yarn install --immutable @@ -3416,7 +3425,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -3426,7 +3435,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -3435,21 +3444,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go test -tags requires_buildifer -short -covermode=atomic -timeout=5m ./pkg/... depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend - commands: - apk add --update build-base @@ -3458,7 +3467,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: test-backend-integration trigger: cron: @@ -3495,6 +3504,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token + ALPINE_BASE: alpine:3.18.4 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -3511,7 +3521,7 @@ steps: from_secret: gcp_key_base64 GITHUB_TOKEN: from_secret: github_token - GO_VERSION: 1.20.10 + GO_VERSION: 1.21.3 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -3522,6 +3532,7 @@ steps: from_secret: npm_token STORYBOOK_DESTINATION: from_secret: rgm_storybook_destination + UBUNTU_BASE: ubuntu:22.04 image: grafana/grafana-build:main name: rgm-build pull: always @@ -3639,6 +3650,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token + ALPINE_BASE: alpine:3.18.4 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -3655,7 +3667,7 @@ steps: from_secret: gcp_key_base64 GITHUB_TOKEN: from_secret: github_token - GO_VERSION: 1.20.10 + GO_VERSION: 1.21.3 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -3666,6 +3678,7 @@ steps: from_secret: npm_token STORYBOOK_DESTINATION: from_secret: rgm_storybook_destination + UBUNTU_BASE: ubuntu:22.04 image: grafana/grafana-build:main name: rgm-publish pull: always @@ -3751,20 +3764,20 @@ steps: - commands: [] depends_on: - clone - image: golang:1.20.10-windowsservercore-1809 + image: golang:1.21.3-windowsservercore-1809 name: windows-init - commands: - go install github.com/google/wire/cmd/wire@v0.5.0 - wire gen -tags oss ./pkg/server depends_on: - windows-init - image: golang:1.20.10-windowsservercore-1809 + image: golang:1.21.3-windowsservercore-1809 name: wire-install - commands: - go test -tags requires_buildifer -short -covermode=atomic -timeout=5m ./pkg/... depends_on: - wire-install - image: golang:1.20.10-windowsservercore-1809 + image: golang:1.21.3-windowsservercore-1809 name: test-backend trigger: event: @@ -3829,7 +3842,7 @@ services: - commands: - /bin/mimir -target=backend environment: {} - image: grafana/mimir:latest + image: us.gcr.io/kubernetes-dev/mimir:gotjosh-state-config-grafana-663a0ae78 name: mimir_backend - environment: {} image: redis:6.2.11-alpine @@ -3846,7 +3859,7 @@ steps: name: grabpl - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.18.3 + image: alpine:3.18.4 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -3856,7 +3869,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -3865,14 +3878,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -3893,7 +3906,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql57:3306 -timeout 120s @@ -3914,7 +3927,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql57 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-5.7-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -3935,7 +3948,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -3950,7 +3963,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -3965,7 +3978,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -3974,15 +3987,14 @@ steps: - commands: - apk add --update build-base - go clean -testcache - - go test -run TestIntegrationRemoteAlertmanager -covermode=atomic -timeout=2m ./pkg/services/ngalert/notifier/... + - go test -run TestIntegrationRemoteAlertmanager -covermode=atomic -timeout=2m ./pkg/services/ngalert/... depends_on: - wire-install - wait-for-remote-alertmanager environment: - AM_PASSWORD: test AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.20.10-alpine + image: golang:1.21.3-alpine name: remote-alertmanager-integration-tests trigger: event: @@ -4068,7 +4080,7 @@ steps: - commands: - if [ -z "${BUILD_CONTAINER_VERSION}" ]; then echo Missing BUILD_CONTAINER_VERSION; false; fi - image: alpine:3.18.3 + image: alpine:3.18.4 name: validate-version - commands: - printenv GCP_KEY > /tmp/key.json @@ -4388,17 +4400,17 @@ steps: path: /root/.docker/ - commands: - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine/git:2.40.1 - - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.20.10-alpine + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.21.3-alpine - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:20.9.0-alpine - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM google/cloud-sdk:431.0.0 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana-ci-deploy:1.3.3 - - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine:3.18.3 + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine:3.18.4 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM ubuntu:22.04 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM byrnedo/alpine-curl:0.1.8 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM plugins/slack - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM python:3.8 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM postgres:12.3-alpine - - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/mimir:latest + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM us.gcr.io/kubernetes-dev/mimir:gotjosh-state-config-grafana-663a0ae78 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM mysql:5.7.39 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM mysql:8.0.32 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM redis:6.2.11-alpine @@ -4422,17 +4434,17 @@ steps: path: /root/.docker/ - commands: - trivy --exit-code 1 --severity HIGH,CRITICAL alpine/git:2.40.1 - - trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.20.10-alpine + - trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.21.3-alpine - trivy --exit-code 1 --severity HIGH,CRITICAL node:20.9.0-alpine - trivy --exit-code 1 --severity HIGH,CRITICAL google/cloud-sdk:431.0.0 - trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana-ci-deploy:1.3.3 - - trivy --exit-code 1 --severity HIGH,CRITICAL alpine:3.18.3 + - trivy --exit-code 1 --severity HIGH,CRITICAL alpine:3.18.4 - trivy --exit-code 1 --severity HIGH,CRITICAL ubuntu:22.04 - trivy --exit-code 1 --severity HIGH,CRITICAL byrnedo/alpine-curl:0.1.8 - trivy --exit-code 1 --severity HIGH,CRITICAL plugins/slack - trivy --exit-code 1 --severity HIGH,CRITICAL python:3.8 - trivy --exit-code 1 --severity HIGH,CRITICAL postgres:12.3-alpine - - trivy --exit-code 1 --severity HIGH,CRITICAL grafana/mimir:latest + - trivy --exit-code 1 --severity HIGH,CRITICAL us.gcr.io/kubernetes-dev/mimir:gotjosh-state-config-grafana-663a0ae78 - trivy --exit-code 1 --severity HIGH,CRITICAL mysql:5.7.39 - trivy --exit-code 1 --severity HIGH,CRITICAL mysql:8.0.32 - trivy --exit-code 1 --severity HIGH,CRITICAL redis:6.2.11-alpine @@ -4670,6 +4682,6 @@ kind: secret name: gcr_credentials --- kind: signature -hmac: 920b57d70a96a29872ce77dc83ca26e2d141ba37627eee58c9d3beebf9ec4055 +hmac: 0e9f67184e414d3afbda81c86dfa58b3c2cf7c1a668be5313c851ff5f42de44d ... diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f363aa6efbfbc..77965604ce73a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -12,9 +12,9 @@ # This should make it easy to add new rules without breaking existing ones. # Documentation -/.changelog-archive @grafana/grafana-delivery +/.changelog-archive @grafana/grafana-release-guild /.codespellignore @grafana/docs-tooling -/CHANGELOG.md @grafana/grafana-delivery +/CHANGELOG.md @grafana/grafana-release-guild /CODE_OF_CONDUCT.md @grafana/grafana-community-support /CONTRIBUTING.md @grafana/grafana-community-support /GOVERNANCE.md @RichiH @@ -48,6 +48,7 @@ /docs/sources/introduction/ @chri2547 /docs/sources/old-alerting/ @brendamuir /docs/sources/panels-visualizations/ @imatwawana +/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md @imatwawana @baldm0mma /docs/sources/release-notes/ @Eve832 @GrafanaWriter /docs/sources/setup-grafana/ @chri2547 /docs/sources/upgrade-guide/ @imatwawana @@ -64,13 +65,15 @@ /.golangci.toml @grafana/backend-platform /build.go @grafana/backend-platform /scripts/modowners/ @grafana/backend-platform +/hack/ @grafana/grafana-app-platform-squad /pkg/api/ @grafana/backend-platform /pkg/apis/ @grafana/grafana-app-platform-squad /pkg/bus/ @grafana/backend-platform /pkg/cmd/ @grafana/backend-platform -/pkg/components/apikeygen/ @grafana/grafana-authnz-team -/pkg/components/satokengen/ @grafana/grafana-authnz-team +/pkg/cmd/grafana/apiserver @grafana/grafana-app-platform-squad +/pkg/components/apikeygen/ @grafana/identity-access-team +/pkg/components/satokengen/ @grafana/identity-access-team /pkg/components/dashdiffs/ @grafana/backend-platform /pkg/components/imguploader/ @grafana/backend-platform /pkg/components/loki/ @grafana/backend-platform @@ -81,7 +84,6 @@ /pkg/ifaces/ @grafana/backend-platform /pkg/infra/appcontext/ @grafana/backend-platform /pkg/infra/db/ @grafana/backend-platform -/pkg/infra/grn/ @grafana/backend-platform /pkg/infra/localcache/ @grafana/backend-platform /pkg/infra/log/ @grafana/backend-platform /pkg/infra/metrics/ @grafana/backend-platform @@ -97,7 +99,7 @@ /pkg/models/ @grafana/backend-platform /pkg/server/ @grafana/backend-platform /pkg/services/annotations/ @grafana/backend-platform -/pkg/services/apikey/ @grafana/grafana-authnz-team +/pkg/services/apikey/ @grafana/identity-access-team /pkg/services/cleanup/ @grafana/backend-platform /pkg/services/contexthandler/ @grafana/backend-platform /pkg/services/correlations/ @grafana/explore-squad @@ -114,7 +116,6 @@ /pkg/services/notifications/ @grafana/backend-platform /pkg/services/org/ @grafana/backend-platform /pkg/services/playlist/ @grafana/grafana-app-platform-squad -/pkg/services/plugindashboards/ @grafana/backend-platform /pkg/services/preference/ @grafana/backend-platform /pkg/services/provisioning/ @grafana/backend-platform /pkg/services/query/ @grafana/backend-platform @@ -127,16 +128,18 @@ /pkg/services/secrets/ @grafana/backend-platform /pkg/services/shorturls/ @grafana/backend-platform /pkg/services/sqlstore/ @grafana/backend-platform +/pkg/services/ssosettings/ @grafana/identity-access-team /pkg/services/star/ @grafana/backend-platform /pkg/services/stats/ @grafana/backend-platform /pkg/services/tag/ @grafana/backend-platform -/pkg/services/team/ @grafana/grafana-authnz-team +/pkg/services/team/ @grafana/identity-access-team /pkg/services/temp_user/ @grafana/backend-platform /pkg/services/updatechecker/ @grafana/backend-platform -/pkg/services/user/ @grafana/grafana-authnz-team +/pkg/services/user/ @grafana/identity-access-team /pkg/services/validations/ @grafana/backend-platform /pkg/setting/ @grafana/backend-platform /pkg/tests/ @grafana/backend-platform +/pkg/tests/apis/ @grafana/grafana-app-platform-squad /pkg/tests/api/correlations/ @grafana/explore-squad /pkg/tsdb/grafanads/ @grafana/backend-platform /pkg/tsdb/intervalv2/ @grafana/backend-platform @@ -147,7 +150,6 @@ /pkg/util/ @grafana/backend-platform /pkg/web/ @grafana/backend-platform -/pkg/services/grpcserver/ @grafana/backend-platform /pkg/infra/kvstore/ @grafana/backend-platform /pkg/infra/fs/ @grafana/backend-platform /pkg/infra/x/ @grafana/backend-platform @@ -155,7 +157,7 @@ # devenv # Backend code, developers environment -/devenv/docker/blocks/auth/ @grafana/grafana-authnz-team +/devenv/docker/blocks/auth/ @grafana/identity-access-team # Logs code, developers environment /devenv/docker/blocks/loki* @grafana/observability-logs @@ -228,15 +230,15 @@ # Continuous Integration -.drone.yml @grafana/grafana-delivery -.drone.star @grafana/grafana-delivery -/scripts/drone/ @grafana/grafana-delivery -/pkg/build/ @grafana/grafana-delivery -/.dockerignore @grafana/grafana-delivery -/Dockerfile @grafana/grafana-delivery -/Makefile @grafana/grafana-delivery -/scripts/build/ @grafana/grafana-delivery -/scripts/list-release-artifacts.sh @grafana/grafana-delivery +.drone.yml @grafana/grafana-release-guild +.drone.star @grafana/grafana-release-guild +/scripts/drone/ @grafana/grafana-release-guild +/pkg/build/ @grafana/grafana-release-guild +/.dockerignore @grafana/grafana-release-guild +/Dockerfile @grafana/grafana-release-guild +/Makefile @grafana/grafana-release-guild +/scripts/build/ @grafana/grafana-release-guild +/scripts/list-release-artifacts.sh @grafana/grafana-release-guild # OSS Plugin Partnerships backend code /pkg/tsdb/cloudwatch/ @grafana/aws-datasources @@ -253,10 +255,12 @@ /pkg/tsdb/grafana-pyroscope-datasource/ @grafana/observability-traces-and-profiling /pkg/tsdb/parca/ @grafana/observability-traces-and-profiling -# BI backend code +# OSS Big Tent backend code /pkg/tsdb/mysql/ @grafana/oss-big-tent -/pkg/tsdb/postgres/ @grafana/oss-big-tent -/pkg/tsdb/mssql/ @grafana/grafana-bi-squad +/pkg/tsdb/grafana-postgresql-datasource/ @grafana/oss-big-tent + +# Partner Datasources backend code +/pkg/tsdb/mssql/ @grafana/partner-datasources # Database migrations /pkg/services/sqlstore/migrations/ @grafana/backend-platform @grafana/hosted-grafana-team @@ -270,6 +274,7 @@ /pkg/util/converter/ @grafana/grafana-app-platform-squad /pkg/modules/ @grafana/grafana-app-platform-squad /pkg/kindsysreport/ @grafana/grafana-app-platform-squad +/pkg/services/grpcserver/ @grafana/grafana-app-platform-squad # Alerting /pkg/services/ngalert/ @grafana/alerting-backend-product @@ -293,6 +298,7 @@ /pkg/tsdb/grafana-testdata-datasource/ @grafana/plugins-platform-backend /pkg/tsdb/Magefile.go @grafana/plugins-platform-backend /pkg/services/pluginsintegration/pluginsettings/ @grafana/plugins-platform-backend +/pkg/services/plugindashboards/ @grafana/plugins-platform-backend # Backend code docs /contribute/backend/ @grafana/backend-platform @@ -310,11 +316,9 @@ /packages/grafana-ui/src/components/ @grafana/grafana-frontend-platform /packages/grafana-ui/src/components/DateTimePickers/ @grafana/grafana-frontend-platform /packages/grafana-ui/src/components/Table/ @grafana/grafana-bi-squad +/packages/grafana-ui/src/components/Table/SparklineCell.tsx @grafana/grafana-bi-squad @grafana/app-o11y-visualizations /packages/grafana-ui/src/components/Gauge/ @grafana/dataviz-squad /packages/grafana-ui/src/components/BarGauge/ @grafana/dataviz-squad -/packages/grafana-ui/src/components/GraphNG/ @grafana/dataviz-squad -/packages/grafana-ui/src/components/Graph/ @grafana/dataviz-squad -/packages/grafana-ui/src/components/TimeSeries/ @grafana/dataviz-squad /packages/grafana-ui/src/components/uPlot/ @grafana/dataviz-squad /packages/grafana-ui/src/components/DataLinks/ @grafana/dataviz-squad /packages/grafana-ui/src/components/ValuePicker/ @grafana/dataviz-squad @@ -322,6 +326,10 @@ /packages/grafana-ui/src/components/VizLegend/ @grafana/dataviz-squad /packages/grafana-ui/src/components/VizRepeater/ @grafana/dataviz-squad /packages/grafana-ui/src/components/VizTooltip/ @grafana/dataviz-squad +/packages/grafana-ui/src/components/Sparkline/ @grafana/grafana-frontend-platform @grafana/app-o11y-visualizations +/packages/grafana-ui/src/graveyard/Graph/ @grafana/dataviz-squad +/packages/grafana-ui/src/graveyard/GraphNG/ @grafana/dataviz-squad +/packages/grafana-ui/src/graveyard/TimeSeries/ @grafana/dataviz-squad /packages/grafana-ui/src/utils/storybook/ @grafana/plugins-platform-frontend /packages/grafana-data/src/transformations/ @grafana/grafana-bi-squad /packages/grafana-data/src/**/*logs* @grafana/observability-logs @@ -366,11 +374,13 @@ cypress.config.js @grafana/grafana-frontend-platform /public/app/core/components/TimePicker/ @grafana/grafana-frontend-platform /public/app/core/components/Layers/ @grafana/dataviz-squad /public/app/core/components/TraceToLogs @grafana/observability-traces-and-profiling +/public/app/core/components/GraphNG/ @grafana/dataviz-squad +/public/app/core/components/TimeSeries/ @grafana/dataviz-squad /public/app/features/all.ts @grafana/grafana-frontend-platform -/public/app/features/admin/ @grafana/grafana-authnz-team -/public/app/features/auth-config/ @grafana/grafana-authnz-team +/public/app/features/admin/ @grafana/identity-access-team +/public/app/features/auth-config/ @grafana/identity-access-team /public/app/features/annotations/ @grafana/grafana-frontend-platform -/public/app/features/api-keys/ @grafana/grafana-authnz-team +/public/app/features/api-keys/ @grafana/identity-access-team /public/app/features/canvas/ @grafana/dataviz-squad /public/app/features/geo/ @grafana/dataviz-squad /public/app/features/visualization/data-hover/ @grafana/dataviz-squad @@ -405,12 +415,14 @@ cypress.config.js @grafana/grafana-frontend-platform /public/app/features/scenes/ @grafana/dashboards-squad /public/app/features/browse-dashboards/ @grafana/grafana-frontend-platform /public/app/features/search/ @grafana/grafana-frontend-platform -/public/app/features/serviceaccounts/ @grafana/grafana-authnz-team +/public/app/features/serviceaccounts/ @grafana/identity-access-team /public/app/features/storage/ @grafana/grafana-app-platform-squad -/public/app/features/teams/ @grafana/grafana-authnz-team +/public/app/features/teams/ @grafana/identity-access-team /public/app/features/templating/ @grafana/dashboards-squad +/public/app/features/trails/ @torkelo /public/app/features/transformers/ @grafana/grafana-bi-squad -/public/app/features/users/ @grafana/grafana-authnz-team +/public/app/features/transformers/timeSeriesTable/ @grafana/grafana-bi-squad @grafana/app-o11y-visualizations +/public/app/features/users/ @grafana/identity-access-team /public/app/features/variables/ @grafana/dashboards-squad /public/app/plugins/panel/alertGroups/ @grafana/alerting-frontend /public/app/plugins/panel/alertlist/ @grafana/alerting-frontend @@ -426,13 +438,14 @@ cypress.config.js @grafana/grafana-frontend-platform /public/app/plugins/panel/heatmap/ @grafana/dataviz-squad /public/app/plugins/panel/histogram/ @grafana/dataviz-squad /public/app/plugins/panel/logs/ @grafana/observability-logs -/public/app/plugins/panel/nodeGraph/ @grafana/observability-traces-and-profiling +/public/app/plugins/panel/nodeGraph/ @grafana/observability-traces-and-profiling @grafana/app-o11y-visualizations /public/app/plugins/panel/traces/ @grafana/observability-traces-and-profiling /public/app/plugins/panel/flamegraph/ @grafana/observability-traces-and-profiling /public/app/plugins/panel/piechart/ @grafana/dataviz-squad /public/app/plugins/panel/state-timeline/ @grafana/dataviz-squad /public/app/plugins/panel/status-history/ @grafana/dataviz-squad /public/app/plugins/panel/table/ @grafana/grafana-bi-squad +/public/app/plugins/panel/table/cells/SparklineCellOptionsEditor.tsx @grafana/grafana-bi-squad @grafana/app-o11y-visualizations /public/app/plugins/panel/table-old/ @grafana/grafana-bi-squad /public/app/plugins/panel/timeseries/ @grafana/dataviz-squad /public/app/plugins/panel/trend/ @grafana/dataviz-squad @@ -461,7 +474,6 @@ cypress.config.js @grafana/grafana-frontend-platform /public/test/ @grafana/grafana-frontend-platform /public/test/helpers/alertingRuleEditor.tsx @grafana/alerting-frontend /public/views/ @grafana/grafana-frontend-platform -/public/views/openapi3.html @grafana/backend-platform /public/views/swagger.html @grafana/backend-platform /public/app/features/explore/Logs/ @grafana/observability-logs @@ -486,29 +498,29 @@ cypress.config.js @grafana/grafana-frontend-platform -/scripts/benchmark-access-control.sh @grafana/grafana-authnz-team +/scripts/benchmark-access-control.sh @grafana/identity-access-team /scripts/check-breaking-changes.sh @grafana/plugins-platform-frontend -/scripts/ci-* @grafana/grafana-delivery -/scripts/circle-* @grafana/grafana-delivery -/scripts/publish-npm-packages.sh @grafana/grafana-delivery @grafana/plugins-platform-frontend -/scripts/validate-npm-packages.sh @grafana/grafana-delivery @grafana/plugins-platform-frontend +/scripts/ci-* @grafana/grafana-release-guild +/scripts/circle-* @grafana/grafana-release-guild +/scripts/publish-npm-packages.sh @grafana/grafana-release-guild @grafana/plugins-platform-frontend +/scripts/validate-npm-packages.sh @grafana/grafana-release-guild @grafana/plugins-platform-frontend /scripts/ci-frontend-metrics.sh @grafana/grafana-frontend-platform @grafana/plugins-platform-frontend @grafana/grafana-bi-squad /scripts/cli/ @grafana/grafana-frontend-platform /scripts/clean-git-or-error.sh @grafana/grafana-as-code /scripts/grafana-server/ @grafana/grafana-frontend-platform -/scripts/helpers/ @grafana/grafana-delivery +/scripts/helpers/ @grafana/grafana-release-guild /scripts/import_many_dashboards.sh @torkelo /scripts/mixin-check.sh @bergquist /scripts/openapi3/ @grafana/grafana-operator-experience-squad /scripts/prepare-packagejson.js @grafana/frontend-ops /scripts/protobuf-check.sh @grafana/plugins-platform-backend /scripts/stripnulls.sh @grafana/grafana-as-code -/scripts/tag_release.sh @grafana/grafana-delivery -/scripts/trigger_docker_build.sh @grafana/grafana-delivery -/scripts/trigger_grafana_packer.sh @grafana/grafana-delivery -/scripts/trigger_windows_build.sh @grafana/grafana-delivery +/scripts/tag_release.sh @grafana/grafana-release-guild +/scripts/trigger_docker_build.sh @grafana/grafana-release-guild +/scripts/trigger_grafana_packer.sh @grafana/grafana-release-guild +/scripts/trigger_windows_build.sh @grafana/grafana-release-guild /scripts/cleanup-husky.sh @grafana/frontend-ops -/scripts/verify-repo-update/ @grafana/grafana-delivery +/scripts/verify-repo-update/ @grafana/grafana-release-guild scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/grafana-frontend-platform /scripts/docs/generate-transformations.ts @grafana/grafana-bi-squad @@ -540,7 +552,7 @@ scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/graf /public/app/plugins/datasource/mssql/ @grafana/grafana-bi-squad /public/app/plugins/datasource/mysql/ @grafana/oss-big-tent /public/app/plugins/datasource/opentsdb/ @grafana/observability-metrics -/public/app/plugins/datasource/postgres/ @grafana/oss-big-tent +/public/app/plugins/datasource/grafana-postgresql-datasource/ @grafana/oss-big-tent /public/app/plugins/datasource/prometheus/ @grafana/observability-metrics /public/app/plugins/datasource/cloud-monitoring/ @grafana/partner-datasources /public/app/plugins/datasource/zipkin/ @grafana/observability-traces-and-profiling @@ -564,25 +576,25 @@ scripts/generate-icon-bundle.js @grafana/plugins-platform-frontend @grafana/graf /grafana-mixin/ @grafana/hosted-grafana-team # Grafana authentication and authorization -/pkg/login/ @grafana/grafana-authnz-team -/pkg/services/accesscontrol/ @grafana/grafana-authnz-team -/pkg/services/anonymous/ @grafana/grafana-authnz-team -/pkg/services/auth/ @grafana/grafana-authnz-team -/pkg/services/authn/ @grafana/grafana-authnz-team -/pkg/services/signingkeys/ @grafana/grafana-authnz-team -/pkg/services/dashboards/accesscontrol.go @grafana/grafana-authnz-team -/pkg/services/datasources/guardian/ @grafana/grafana-authnz-team -/pkg/services/guardian/ @grafana/grafana-authnz-team -/pkg/services/ldap/ @grafana/grafana-authnz-team -/pkg/services/login/ @grafana/grafana-authnz-team -/pkg/services/loginattempt/ @grafana/grafana-authnz-team -/pkg/services/extsvcauth/ @grafana/grafana-authnz-team -/pkg/services/oauthtoken/ @grafana/grafana-authnz-team -/pkg/services/serviceaccounts/ @grafana/grafana-authnz-team +/pkg/login/ @grafana/identity-access-team +/pkg/services/accesscontrol/ @grafana/identity-access-team +/pkg/services/anonymous/ @grafana/identity-access-team +/pkg/services/auth/ @grafana/identity-access-team +/pkg/services/authn/ @grafana/identity-access-team +/pkg/services/signingkeys/ @grafana/identity-access-team +/pkg/services/dashboards/accesscontrol.go @grafana/identity-access-team +/pkg/services/datasources/guardian/ @grafana/identity-access-team +/pkg/services/guardian/ @grafana/identity-access-team +/pkg/services/ldap/ @grafana/identity-access-team +/pkg/services/login/ @grafana/identity-access-team +/pkg/services/loginattempt/ @grafana/identity-access-team +/pkg/services/extsvcauth/ @grafana/identity-access-team +/pkg/services/oauthtoken/ @grafana/identity-access-team +/pkg/services/serviceaccounts/ @grafana/identity-access-team # Support bundles -/public/app/features/support-bundles/ @grafana/grafana-authnz-team -/pkg/services/supportbundles/ @grafana/grafana-authnz-team +/public/app/features/support-bundles/ @grafana/identity-access-team +/pkg/services/supportbundles/ @grafana/identity-access-team # Grafana Operator Experience Team /pkg/infra/httpclient/httpclientprovider/sigv4_middleware.go @grafana/grafana-operator-experience-squad @@ -599,6 +611,7 @@ embed.go @grafana/grafana-as-code /pkg/kinds/ @grafana/grafana-as-code /pkg/cuectx/ @grafana/grafana-as-code /pkg/registry/ @grafana/grafana-as-code +/pkg/registry/apis/ @grafana/grafana-app-platform-squad /pkg/codegen/ @grafana/grafana-as-code /pkg/kinds/*/*_gen.go @grafana/grafana-as-code /pkg/registry/corekind/ @grafana/grafana-as-code @@ -619,38 +632,37 @@ embed.go @grafana/grafana-as-code /.github/renovate.json5 @grafana/frontend-ops /.github/teams.yml @armandgrillet /.github/workflows/alerting-swagger-gen.yml @grafana/alerting-backend-product -/.github/workflows/auto-milestone.yml @grafana/grafana-delivery -/.github/workflows/backport.yml @grafana/grafana-delivery -/.github/workflows/bump-version.yml @grafana/grafana-delivery -/.github/workflows/close-milestone.yml @grafana/grafana-delivery +/.github/workflows/auto-milestone.yml @grafana/grafana-release-guild +/.github/workflows/backport.yml @grafana/grafana-release-guild +/.github/workflows/bump-version.yml @grafana/grafana-release-guild +/.github/workflows/close-milestone.yml @grafana/grafana-release-guild /.github/workflows/codeowners-validator.yml @tolzhabayev /.github/workflows/codeql-analysis.yml @DanCech /.github/workflows/commands.yml @torkelo -/.github/workflows/community-release.yml @grafana/grafana-delivery +/.github/workflows/community-release.yml @grafana/grafana-release-guild /.github/workflows/detect-breaking-changes-* @grafana/plugins-platform-frontend /.github/workflows/doc-validator.yml @grafana/docs-tooling /.github/workflows/epic-add-to-platform-ux-parent-project.yml @meanmina -/.github/workflows/github-release.yml @grafana/grafana-delivery +/.github/workflows/github-release.yml @grafana/grafana-release-guild /.github/workflows/issue-labeled.yml @armandgrillet /.github/workflows/issue-opened.yml @grafana/grafana-community-support /.github/workflows/metrics-collector.yml @torkelo /.github/workflows/milestone.yml @marefr -/.github/workflows/ox-code-coverage.yml @grafana/explore-squad /.github/workflows/pr-checks.yml @marefr /.github/workflows/pr-codeql-analysis-go.yml @DanCech /.github/workflows/pr-codeql-analysis-javascript.yml @DanCech /.github/workflows/pr-codeql-analysis-python.yml @DanCech /.github/workflows/pr-commands.yml @marefr -/.github/workflows/pr-patch-check.yml @grafana/grafana-delivery -/.github/workflows/sync-mirror.yml @grafana/grafana-delivery +/.github/workflows/pr-patch-check.yml @grafana/grafana-release-guild +/.github/workflows/sync-mirror.yml @grafana/grafana-release-guild /.github/workflows/publish-technical-documentation-next.yml @grafana/docs-tooling /.github/workflows/publish-technical-documentation-release.yml @grafana/docs-tooling -/.github/workflows/remove-milestone.yml @grafana/grafana-delivery +/.github/workflows/remove-milestone.yml @grafana/grafana-release-guild /.github/workflows/sbom-report.yml @grafana/security-team /.github/workflows/scripts/json-file-to-job-output.js @grafana/plugins-platform-frontend /.github/workflows/scripts/pr-get-job-link.js @grafana/plugins-platform-frontend -/.github/workflows/stale.yml @grafana/grafana-delivery -/.github/workflows/update-changelog.yml @grafana/grafana-delivery +/.github/workflows/stale.yml @grafana/grafana-release-guild +/.github/workflows/update-changelog.yml @grafana/grafana-release-guild /.github/workflows/update-make-docs.yml @grafana/docs-tooling /.github/workflows/snyk.yml @grafana/security-team /.github/workflows/scripts/kinds/verify-kinds.go @grafana/grafana-as-code @@ -660,8 +672,9 @@ embed.go @grafana/grafana-as-code /.github/workflows/dashboards-issue-add-label.yml @grafana/dashboards-squad /.github/workflows/ephemeral-instances-pr-comment.yml @grafana/grafana-operator-experience-squad /.github/workflows/ephemeral-instances-pr-opened-closed.yml @grafana/grafana-operator-experience-squad -/.github/workflows/create-security-patch-from-security-mirror.yml @grafana/grafana-delivery +/.github/workflows/create-security-patch-from-security-mirror.yml @grafana/grafana-release-guild /.github/workflows/core-plugins-build-and-release.yml @grafana/plugins-platform-frontend @grafana/plugins-platform-backend +/.github/workflows/i18n-crowdin-fix-files.yml @grafana/grafana-frontend-platform # Generated files not requiring owner approval /packages/grafana-data/src/types/featureToggles.gen.ts @grafanabot @@ -673,9 +686,9 @@ embed.go @grafana/grafana-as-code # Conf /conf/defaults.ini @torkelo /conf/sample.ini @torkelo -/conf/ldap.toml @grafana/grafana-authnz-team -/conf/ldap_multiple.toml @grafana/grafana-authnz-team -/conf/provisioning/access-control/ @grafana/grafana-authnz-team +/conf/ldap.toml @grafana/identity-access-team +/conf/ldap_multiple.toml @grafana/identity-access-team +/conf/provisioning/access-control/ @grafana/identity-access-team /conf/provisioning/alerting/ @grafana/alerting-backend-product /conf/provisioning/dashboards/ @grafana/dashboards-squad /conf/provisioning/datasources/ @grafana/plugins-platform-backend diff --git a/.github/ISSUE_TEMPLATE/1-feature_requests.md b/.github/ISSUE_TEMPLATE/1-feature_requests.md index ab43f8c1d83be..67449c9af2a1f 100644 --- a/.github/ISSUE_TEMPLATE/1-feature_requests.md +++ b/.github/ISSUE_TEMPLATE/1-feature_requests.md @@ -1,7 +1,6 @@ --- name: Feature Requests about: Suggest an enhancement or new feature for the Grafana project -labels: 'type/feature-request' --- @@ -18,4 +17,4 @@ labels: 'type/feature-request' **Who is this feature for?** -[Add information on what kind of user the feature is for.] \ No newline at end of file +[Add information on what kind of user the feature is for.] diff --git a/.github/pr-checks.json b/.github/pr-checks.json index fec10a1201dda..b97dbc137ece1 100644 --- a/.github/pr-checks.json +++ b/.github/pr-checks.json @@ -6,25 +6,6 @@ "success": "Milestone set", "failure": "Milestone not set" }, - { - "type": "check-label", - "title": "Backport Check", - "labels": { - "exists": "Backport enabled", - "notExists": "Backport decision needed", - "matches": [ - "backport v*" - ] - }, - "skip": { - "message": "Backport skipped", - "matches": [ - "backport", - "no-backport" - ] - }, - "targetUrl": "https://github.com/grafana/grafana/blob/main/contribute/merge-pull-request.md#should-the-pull-request-be-backported" - }, { "type": "check-changelog", "title": "Changelog Check", diff --git a/.github/pr-commands.json b/.github/pr-commands.json index ec60e516e218e..27ac70337c0ae 100644 --- a/.github/pr-commands.json +++ b/.github/pr-commands.json @@ -149,7 +149,7 @@ }, { "type": "changedfiles", - "matches": [ "public/app/plugins/datasource/postgres/**/*", "pkg/tsdb/postgres/**/*"], + "matches": [ "public/app/plugins/datasource/grafana-postgresql-datasource/**/*", "pkg/tsdb/grafana-postgresql-datasource/**/*"], "action": "updateLabel", "addLabel": "datasource/Postgres" }, diff --git a/.github/renovate.json5 b/.github/renovate.json5 index e8f9da4aba23a..331453813b3c1 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -11,7 +11,7 @@ ], "includePaths": ["package.json", "packages/**", "public/app/plugins/**"], "ignorePaths": ["emails/**", "plugins-bundled/**", "**/mocks/**", "packages/grafana-e2e/**"], - "labels": ["area/frontend", "dependencies", "no-backport", "no-changelog"], + "labels": ["area/frontend", "dependencies", "no-changelog"], "postUpdateOptions": ["yarnDedupeHighest"], "packageRules": [ { diff --git a/.github/workflows/alerting-swagger-gen.yml b/.github/workflows/alerting-swagger-gen.yml index f42389ceeed26..cd901cf8b62de 100644 --- a/.github/workflows/alerting-swagger-gen.yml +++ b/.github/workflows/alerting-swagger-gen.yml @@ -16,7 +16,7 @@ jobs: - name: Set go version uses: actions/setup-go@v4 with: - go-version: '1.20.10' + go-version: '1.21.3' - name: Build swagger run: | make -C pkg/services/ngalert/api/tooling post.json api.json @@ -31,7 +31,7 @@ jobs: Please review and merge. branch: update-alerting-swagger-spec delete-branch: true - labels: 'area/alerting,type/docs,no-backport,no-changelog' + labels: 'area/alerting,type/docs,no-changelog' team-reviewers: 'grafana/alerting-backend-product' draft: false diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 60fe93679cf42..77f8d20905d97 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -47,7 +47,7 @@ jobs: name: Set go version uses: actions/setup-go@v4 with: - go-version: '1.20.10' + go-version: '1.21.3' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/core-plugins-build-and-release.yml b/.github/workflows/core-plugins-build-and-release.yml index 6ae5f37d3f441..aa1136569bf08 100644 --- a/.github/workflows/core-plugins-build-and-release.yml +++ b/.github/workflows/core-plugins-build-and-release.yml @@ -45,11 +45,11 @@ jobs: PLUGINS_GRAFANA_API_KEY=core-plugins-build-and-release:PLUGINS_GRAFANA_API_KEY PLUGINS_GCOM_TOKEN=core-plugins-build-and-release:PLUGINS_GCOM_TOKEN - name: 'Authenticate to Google Cloud' - uses: 'google-github-actions/auth@v1' + uses: 'google-github-actions/auth@v2' with: credentials_json: '${{ env.PLUGINS_GOOGLE_CREDENTIALS }}' - name: 'Set up Cloud SDK' - uses: 'google-github-actions/setup-gcloud@v1' + uses: 'google-github-actions/setup-gcloud@v2' - name: Setup nodejs environment uses: actions/setup-node@v4 with: diff --git a/.github/workflows/detect-breaking-changes-build.yml b/.github/workflows/detect-breaking-changes-build.yml index be0af37f76bca..27d119d638e13 100644 --- a/.github/workflows/detect-breaking-changes-build.yml +++ b/.github/workflows/detect-breaking-changes-build.yml @@ -1,9 +1,9 @@ -# Only runs if anything under the packages/ directory changes. +# Only runs if anything under the packages/ directory changes. # (Otherwise detect-breaking-changes-build-skip.yml takes over) name: Levitate / Detect breaking changes -on: +on: pull_request: paths: - 'packages/**' @@ -24,7 +24,7 @@ jobs: path: './pr' - uses: actions/setup-node@v4 with: - node-version: 16.16.0 + node-version: 20.9.0 - name: Get yarn cache directory path id: yarn-cache-dir-path @@ -72,7 +72,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 16.16.0 + node-version: 20.9.0 - name: Get yarn cache directory path id: yarn-cache-dir-path diff --git a/.github/workflows/i18n-crowdin-fix-files.yml b/.github/workflows/i18n-crowdin-fix-files.yml new file mode 100644 index 0000000000000..5117bd381d6d5 --- /dev/null +++ b/.github/workflows/i18n-crowdin-fix-files.yml @@ -0,0 +1,67 @@ +# When Crowdin creates a pull request from the crowdin-service-branch branch, +# run `yarn i18n:extract` and commit the changed grafana.json files back into the PR +# to reformat crowdin's changes to prevent conflicts with our CI checks. + +name: Fix Crowdin I18n files + +on: + pull_request: + paths: + - 'public/locales/*/grafana.json' + branches: + - main # Only run on pull requests *target* main (will be merged into main) + +jobs: + fix-files: + # Only run on pull requests *from* the crowdin-service-branch branch + if: github.head_ref == 'crowdin-service-branch' + + name: Fix files + runs-on: ubuntu-latest + + + permissions: + contents: write # needed to commit changes back into the PR + pull-requests: write # needed to update PR description + + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + + - uses: actions/setup-node@v4 + with: + node-version: 20.9.0 + cache: 'yarn' + + - name: Install dependencies + run: yarn install + + - name: Extract I18n files + run: yarn i18n:extract + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@8756aa072ef5b4a080af5dc8fef36c5d586e521d # v5.0.0 + with: + commit_message: "Github Action: Auto-fix i18n files" + file_pattern: public/locales/*/grafana.json + + - name: Update PR description + uses: devindford/Append_PR_Comment@32dd2619cd96ac8da9907c416c992fe265233ca8 # v1.1.3 + if: ${{ ! contains(github.event.pull_request.body, 'Steps for merging') }} + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + body-update-action: prefix + body-template: | + :robot: Automatic sync of translations from Crowdin. + + Steps for merging: + 1. Wait for the "Github Action: Auto-fix i18n files" commit that may be required for CI to pass. + 2. A quick sanity check of the changes and approve. Things to look out for: + - No changes to the English strings. The source of truth is already in the main branch, NOT Crowdin. + - Translations maybe be removed if the English phrase was removed, but there should not be many of these + - Anything else that looks 'funky'. Ask if you're not sure. + 3. Approve & (Auto-)merge. :tada: + + If there's a conflict, close the pull request and **delete the branch**. Crowdin will recreate the pull request eventually. + Remember, the longer this pull request is open, the more likely it is that it'll get conflicts. diff --git a/.github/workflows/ox-code-coverage.yml b/.github/workflows/ox-code-coverage.yml deleted file mode 100644 index acc72ed68528e..0000000000000 --- a/.github/workflows/ox-code-coverage.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Observability Experience test code coverage -on: - pull_request: - paths: - - 'pkg/services/queryhistory/**' - - 'pkg/tsdb/loki/**' - - 'pkg/tsdb/elasticsearch/**' - - 'public/app/features/explore/**' - - 'public/app/features/correlations/**' - - 'public/app/plugins/datasource/loki/**' - - 'public/app/plugins/datasource/elasticsearch/**' - branches-ignore: - - dependabot/** - - backport-* - -jobs: - workflow-call: - uses: grafana/code-coverage/.github/workflows/code-coverage.yml@v0.1.20 - with: - frontend-path-regexp: public\/app\/features\/(explore|correlations)|public\/app\/plugins\/datasource\/(loki|elasticsearch) - backend-path-regexp: pkg\/services\/(queryhistory)|pkg\/tsdb\/(loki|elasticsearch) diff --git a/.github/workflows/pr-codeql-analysis-go.yml b/.github/workflows/pr-codeql-analysis-go.yml index 26b45ad58145f..5a4c4d4c63102 100644 --- a/.github/workflows/pr-codeql-analysis-go.yml +++ b/.github/workflows/pr-codeql-analysis-go.yml @@ -26,7 +26,7 @@ jobs: - name: Set go version uses: actions/setup-go@v4 with: - go-version: '1.20.10' + go-version: '1.21.3' # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/publish-kinds-next.yml b/.github/workflows/publish-kinds-next.yml index 97c70377ac559..160384c35a8a6 100644 --- a/.github/workflows/publish-kinds-next.yml +++ b/.github/workflows/publish-kinds-next.yml @@ -36,7 +36,7 @@ jobs: - name: "Setup Go" uses: "actions/setup-go@v4" with: - go-version: '1.20.10' + go-version: '1.21.3' - name: "Verify kinds" run: go run .github/workflows/scripts/kinds/verify-kinds.go diff --git a/.github/workflows/publish-kinds-release.yml b/.github/workflows/publish-kinds-release.yml index 30516f062d895..d2c6ea1b904a3 100644 --- a/.github/workflows/publish-kinds-release.yml +++ b/.github/workflows/publish-kinds-release.yml @@ -39,7 +39,7 @@ jobs: - name: "Setup Go" uses: "actions/setup-go@v4" with: - go-version: '1.20.10' + go-version: '1.21.3' - name: "Verify kinds" run: go run .github/workflows/scripts/kinds/verify-kinds.go diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index de50fe2f26bf2..1a452bb6a01ee 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -10,7 +10,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: repo-token: ${{ secrets.GITHUB_TOKEN }} # Number of days of inactivity before a stale Issue or Pull Request is closed. diff --git a/.github/workflows/update-make-docs.yml b/.github/workflows/update-make-docs.yml index 1bd0f70cb7131..09159af49e718 100644 --- a/.github/workflows/update-make-docs.yml +++ b/.github/workflows/update-make-docs.yml @@ -2,26 +2,18 @@ name: Update `make docs` procedure on: schedule: - cron: '0 7 * * 1-5' + workflow_dispatch: jobs: main: if: github.repository == 'grafana/grafana' runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Update procedure - run: | - curl -s -Lo docs/docs.mk https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/docs.mk - curl -s -Lo docs/make-docs https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/make-docs - if git diff --exit-code; then exit 0; fi - BRANCH="$(date +%Y-%m-%d)/update-make-docs" - git checkout -b "${BRANCH}" - git add . - git config --local user.email "bot@grafana.com" - git config --local user.name "grafanabot" - git commit -m "Update \`make docs\` procedure" - git push -v origin "refs/heads/${BRANCH}" - gh pr create --fill --label no-changelog --label --no-backport --label type/docs - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/checkout@v4 + - uses: grafana/writers-toolkit/update-make-docs@update-make-docs/v1 + with: + pr_options: > + --label 'backport v10.0.x' + --label 'backport v10.1.x' + --label 'backport v10.2.x' + --label no-changelog + --label type/docs diff --git a/.github/workflows/verify-kinds.yml b/.github/workflows/verify-kinds.yml index 7ea1bb46a1c38..030d98d9f1052 100644 --- a/.github/workflows/verify-kinds.yml +++ b/.github/workflows/verify-kinds.yml @@ -18,7 +18,7 @@ jobs: - name: "Setup Go" uses: "actions/setup-go@v4" with: - go-version: '1.20.10' + go-version: '1.21.3' - name: "Verify kinds" run: go run .github/workflows/scripts/kinds/verify-kinds.go diff --git a/.gitignore b/.gitignore index 431a6300f7619..771a993d2a779 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,6 @@ awsconfig /.awcache /dist /public/build -/public/views/index.html -/public/views/error.html /emails/dist /reports /e2e/tmp @@ -78,6 +76,13 @@ public/css/*.min.css /data/* /bin/* +# any certificates generated by grafana apiserver +apiserver.local.config/ +default.etcd/ + +# kubeconfig path used by example apiserver +example-apiserver/ + # devenv /devenv/docker-compose.yaml /devenv/docker-compose.override.yaml diff --git a/.pa11yci-pr.conf.js b/.pa11yci-pr.conf.js index 71990e6a11524..1b29b93022218 100644 --- a/.pa11yci-pr.conf.js +++ b/.pa11yci-pr.conf.js @@ -51,6 +51,7 @@ var config = { useIncognitoBrowserContext: false, standard: 'WCAG2AA', chromeLaunchConfig: { + executablePath: '/usr/bin/google-chrome', args: ['--no-sandbox'], }, // see https://github.com/grafana/grafana/pull/41693#issuecomment-979921463 for context @@ -72,8 +73,8 @@ var config = { "wait for element input[name='user'] to be added", "set field input[name='user'] to admin", "set field input[name='password'] to admin", - "click element button[aria-label='Login button']", - "wait for element [aria-label='Skip change password button'] to be visible", + "click element button[data-testid='data-testid Login button']", + "wait for element button[data-testid='data-testid Skip change password button'] to be visible", ], threshold: 15, rootElement: '.main-view', diff --git a/.pa11yci.conf.js b/.pa11yci.conf.js index b15b7c7d80a95..5c8256c3f3ed7 100644 --- a/.pa11yci.conf.js +++ b/.pa11yci.conf.js @@ -61,8 +61,8 @@ var config = { "wait for element input[name='user'] to be added", "set field input[name='user'] to admin", "set field input[name='password'] to admin", - "click element button[aria-label='Login button']", - "wait for element [aria-label='Skip change password button'] to be visible", + "click element button[data-testid='data-testid Login button']", + "wait for element button[data-testid='data-testid Skip change password button'] to be visible", ], wait: 500, rootElement: '.main-view', diff --git a/.vscode/launch.json b/.vscode/launch.json index 792addee9505c..d2f9c3b15843e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,6 +11,16 @@ "cwd": "${workspaceFolder}", "args": ["server", "--homepath", "${workspaceFolder}", "--packaging", "dev"] }, + { + "name": "Run API Server (k8s)", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/pkg/cmd/grafana/", + "env": {}, + "cwd": "${workspaceFolder}", + "args": ["apiserver", "example.grafana.app"] + }, { "name": "Attach to Chrome", "port": 9222, diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json index 417fa1369db25..d32f3913d7958 100644 --- a/.yarn/sdks/typescript/package.json +++ b/.yarn/sdks/typescript/package.json @@ -1,6 +1,6 @@ { "name": "typescript", - "version": "4.8.4-sdk", + "version": "5.2.2-sdk", "main": "./lib/typescript.js", "type": "commonjs", "bin": { diff --git a/.yarnrc.yml b/.yarnrc.yml index 1b0a2c9768a04..affb1c6d2fe9c 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -7,7 +7,7 @@ enableTelemetry: false nodeLinker: pnp packageExtensions: - '@storybook/core-common@7.4.5': + "@storybook/core-common@7.4.5": dependencies: '@storybook/react-webpack5': 7.4.5 doctrine@3.0.0: @@ -26,14 +26,14 @@ packageExtensions: react-simple-compat: 1.2.2 react-icons@2.2.7: peerDependencies: - prop-types: '*' + prop-types: "*" react-resizable@3.0.4: peerDependencies: react-dom: 17.0.1 plugins: - path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs - spec: 'https://mskelton.dev/yarn-outdated/v2' + spec: "https://mskelton.dev/yarn-outdated/v2" yarnPath: .yarn/releases/yarn-4.0.0.cjs # Uncomment the following lines if you want to use Verdaccio local npm registry. Read more at packages/README.md diff --git a/CHANGELOG.md b/CHANGELOG.md index e26adac50ae78..4e3d2f97f6b33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,53 @@ + + +# 10.2.2 (2023-11-20) + +### Bug fixes + +- **FeatureToggle:** Disable `dashgpt` by default and mark it as preview. [#78349](https://github.com/grafana/grafana/issues/78349), [@ivanortegaalba](https://github.com/ivanortegaalba) +- **SaveDashboardPrompt:** Reduce time to open drawer when many changes applied. [#78308](https://github.com/grafana/grafana/issues/78308), [@ivanortegaalba](https://github.com/ivanortegaalba) +- **Alerting:** Fix export with modifications URL when mounted on subpath. [#78217](https://github.com/grafana/grafana/issues/78217), [@gillesdemey](https://github.com/gillesdemey) +- **Explore:** Fix queries (cached & non) count in usage insights. [#78216](https://github.com/grafana/grafana/issues/78216), [@Elfo404](https://github.com/Elfo404) +- **Plugins:** Keep working when there is no internet access. [#78092](https://github.com/grafana/grafana/issues/78092), [@leventebalogh](https://github.com/leventebalogh) + + + + +# 10.2.1 (2023-11-13) + +### Features and enhancements + +- **Stat:** Add panel option to control wide layout. [#78012](https://github.com/grafana/grafana/issues/78012), [@nmarrs](https://github.com/nmarrs) + +### Bug fixes + +- **Dashboards:** Fix dashboard listing when user can't list any folders. [#77988](https://github.com/grafana/grafana/issues/77988), [@IevaVasiljeva](https://github.com/IevaVasiljeva) +- **Search:** Modify query for better performance. [#77713](https://github.com/grafana/grafana/issues/77713), [@papagian](https://github.com/papagian) +- **Dashboards:** Fix issue causing crashes when saving new dashboard. [#77641](https://github.com/grafana/grafana/issues/77641), [@kaydelaney](https://github.com/kaydelaney) +- **RBAC:** Allow scoping access to root level dashboards. [#77608](https://github.com/grafana/grafana/issues/77608), [@IevaVasiljeva](https://github.com/IevaVasiljeva) +- **CloudWatch Logs:** Add labels to alert and expression queries. [#77594](https://github.com/grafana/grafana/issues/77594), [@iwysiu](https://github.com/iwysiu) +- **Bug Fix:** Respect data source version when provisioning. [#77542](https://github.com/grafana/grafana/issues/77542), [@andresmgot](https://github.com/andresmgot) +- **Explore:** Fix support for angular based datasource editors. [#77505](https://github.com/grafana/grafana/issues/77505), [@Elfo404](https://github.com/Elfo404) +- **Plugins:** Fix status_source always being "plugin" in plugin request logs. [#77436](https://github.com/grafana/grafana/issues/77436), [@xnyo](https://github.com/xnyo) +- **InfluxDB:** Fix aliasing with $measurement or $m on backend mode. [#77383](https://github.com/grafana/grafana/issues/77383), [@itsmylife](https://github.com/itsmylife) +- **InfluxDB:** Fix parsing multiple tags on backend mode. [#77382](https://github.com/grafana/grafana/issues/77382), [@itsmylife](https://github.com/itsmylife) +- **Explore:** Fix panes vertical scrollbar not being draggable. [#77344](https://github.com/grafana/grafana/issues/77344), [@Elfo404](https://github.com/Elfo404) +- **Explore:** Avoid reinitializing graph on every query run. [#77290](https://github.com/grafana/grafana/issues/77290), [@Elfo404](https://github.com/Elfo404) +- **Bug fix:** Correctly set permissions on provisioned dashboards. [#77230](https://github.com/grafana/grafana/issues/77230), [@IevaVasiljeva](https://github.com/IevaVasiljeva) +- **InfluxDB:** Fix adhoc filter calls by properly checking optional parameter in metricFindQuery. [#77145](https://github.com/grafana/grafana/issues/77145), [@itsmylife](https://github.com/itsmylife) +- **InfluxDB:** Fix table parsing with backend mode. [#76990](https://github.com/grafana/grafana/issues/76990), [@itsmylife](https://github.com/itsmylife) +- **Alerting:** Alert rule constraint violations return as 400s in provisioning API. [#76978](https://github.com/grafana/grafana/issues/76978), [@alexweav](https://github.com/alexweav) +- **PresenceIndicators:** Do not retry failed views/recent API calls. (Enterprise) +- **Analytics:** Use panel renderer rather than legacy flot graph. (Enterprise) + +### Breaking changes + +For the existing backend mode users who have table visualization might see some inconsistencies on their panels. We have updated the table column naming. This will potentially affect field transformations and/or field overrides. To resolve this either: + +- Update transformation +- Update field override Issue [#76990](https://github.com/grafana/grafana/issues/76990) + + # 10.2.0 (2023-10-24) @@ -1314,6 +1364,18 @@ The `database` field has been deprecated in the Elasticsearch datasource provisi - **InteractiveTable:** Updated design and minor tweak to Correlactions page. [#66443](https://github.com/grafana/grafana/issues/66443), [@torkelo](https://github.com/torkelo) + + +# 9.5.14 (2023-11-13) + +### Bug fixes + +- **Alerting:** Fix state manager to not keep datasource_uid and ref_id labels in state after Error. [#77391](https://github.com/grafana/grafana/issues/77391), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Transformations:** Config overrides being lost when config from query transform is applied. [#75347](https://github.com/grafana/grafana/issues/75347), [@IbrahimCSAE](https://github.com/IbrahimCSAE) +- **LDAP:** FIX Enable users on successfull login . [#75192](https://github.com/grafana/grafana/issues/75192), [@gamab](https://github.com/gamab) +- **Auditing and UsageInsights:** FIX Loki configuration to use proxy env variables. (Enterprise) + + # 9.5.13 (2023-10-11) diff --git a/Dockerfile b/Dockerfile index 3e558c6c6ce91..ec439e8b9b082 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ ARG BASE_IMAGE=alpine:3.18.3 ARG JS_IMAGE=node:20-alpine3.18 ARG JS_PLATFORM=linux/amd64 -ARG GO_IMAGE=golang:1.20.10-alpine3.18 +ARG GO_IMAGE=golang:1.21.3-alpine3.18 ARG GO_SRC=go-builder ARG JS_SRC=js-builder @@ -48,6 +48,9 @@ WORKDIR /tmp/grafana COPY go.* ./ COPY .bingo .bingo +# Include vendored dependencies +COPY pkg/util/xorm/go.* pkg/util/xorm/ + RUN go mod download RUN if [[ "$BINGO" = "true" ]]; then \ go install github.com/bwplotka/bingo@latest && \ diff --git a/Makefile b/Makefile index d26b3b4a1a2c8..9d209f0ec1f28 100644 --- a/Makefile +++ b/Makefile @@ -184,8 +184,8 @@ test-go-integration: ## Run integration tests for backend with flags. test-go-integration-alertmanager: ## Run integration tests for the remote alertmanager (config taken from the mimir_backend block). @echo "test remote alertmanager integration tests" $(GO) clean -testcache - AM_URL=http://localhost:8080 AM_TENANT_ID=test AM_PASSWORD=test \ - $(GO) test -count=1 -run "^TestIntegrationRemoteAlertmanager" -covermode=atomic -timeout=5m ./pkg/services/ngalert/notifier/... + AM_URL=http://localhost:8080 AM_TENANT_ID=test \ + $(GO) test -count=1 -run "^TestIntegrationRemoteAlertmanager" -covermode=atomic -timeout=5m ./pkg/services/ngalert/... .PHONY: test-go-integration-postgres test-go-integration-postgres: devenv-postgres ## Run integration tests for postgres backend with flags. @@ -261,7 +261,7 @@ build-docker-full-ubuntu: ## Build Docker image based on Ubuntu for development. --build-arg COMMIT_SHA=$$(git rev-parse HEAD) \ --build-arg BUILD_BRANCH=$$(git rev-parse --abbrev-ref HEAD) \ --build-arg BASE_IMAGE=ubuntu:22.04 \ - --build-arg GO_IMAGE=golang:1.20.10 \ + --build-arg GO_IMAGE=golang:1.21.3 \ --tag grafana/grafana$(TAG_SUFFIX):dev-ubuntu \ $(DOCKER_BUILD_ARGS) @@ -308,7 +308,6 @@ protobuf: ## Compile protobuf definitions bash pkg/plugins/backendplugin/pluginextensionv2/generate.sh bash pkg/plugins/backendplugin/secretsmanagerplugin/generate.sh bash pkg/services/store/entity/generate.sh - bash pkg/infra/grn/generate.sh clean: ## Clean up intermediate build artifacts. @echo "cleaning" diff --git a/README.md b/README.md index 25b3aad7fbee8..f111b8c58cbaf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -![Grafana](docs/logo-horizontal.png) +![Grafana Logo (Light)](docs/logo-horizontal.png#gh-light-mode-only) +![Grafana Logo (Dark)](docs/logo-horizontal-dark.png#gh-dark-mode-only) The open-source platform for monitoring and observability diff --git a/babel.config.json b/babel.config.json index 28e9f48eeed54..b7e1723c6268d 100644 --- a/babel.config.json +++ b/babel.config.json @@ -6,9 +6,7 @@ "@babel/preset-env", { "bugfixes": true, - "browserslistEnv": "dev", - "useBuiltIns": "entry", - "corejs": "3.10" + "browserslistEnv": "dev" } ], [ diff --git a/conf/defaults.ini b/conf/defaults.ini index d452b9e4d9cd6..17554ffbb0354 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -10,6 +10,7 @@ app_mode = development instance_name = ${HOSTNAME} # force migration will run migrations that might cause dataloss +# Deprecated, use clean_upgrade option in [unified_alerting.upgrade] instead. force_migration = false #################################### Paths ############################### @@ -382,7 +383,7 @@ angular_support_enabled = true csrf_always_check = false # Comma-separated list of plugins ids that won't be loaded inside the frontend sandbox -disable_frontend_sandbox_for_plugins = +disable_frontend_sandbox_for_plugins = grafana-incident-app [security.encryption] # Defines the time-to-live (TTL) for decrypted data encryption keys stored in memory (cache). @@ -565,6 +566,17 @@ azure_auth_enabled = false # Use email lookup in addition to the unique ID provided by the IdP oauth_allow_insecure_email_lookup = false +# Set to true to include id of identity as a response header +id_response_header_enabled = false + +# Prefix used for the id response header, X-Grafana-Identity-Id +id_response_header_prefix = X-Grafana + +# List of identity namespaces to add id response headers for, separated by space. +# Available namespaces are user, api-key and service-account. +# The header value will encode the namespace ("user:", "api-key:", "service-account:") +id_response_header_namespaces = user api-key service-account + #################################### Anonymous Auth ###################### [auth.anonymous] # enable anonymous access @@ -592,6 +604,7 @@ scopes = user:email,read:org auth_url = https://github.com/login/oauth/authorize token_url = https://github.com/login/oauth/access_token api_url = https://api.github.com/user +signout_redirect_url = allowed_domains = team_ids = allowed_organizations = @@ -619,6 +632,7 @@ scopes = openid email profile auth_url = https://gitlab.com/oauth/authorize token_url = https://gitlab.com/oauth/token api_url = https://gitlab.com/api/v4 +signout_redirect_url = allowed_domains = allowed_groups = role_attribute_path = @@ -645,6 +659,7 @@ scopes = openid email profile auth_url = https://accounts.google.com/o/oauth2/v2/auth token_url = https://oauth2.googleapis.com/token api_url = https://openidconnect.googleapis.com/v1/userinfo +signout_redirect_url = allowed_domains = hosted_domain = allowed_groups = @@ -695,6 +710,7 @@ client_secret = scopes = openid email profile auth_url = https://login.microsoftonline.com//oauth2/v2.0/authorize token_url = https://login.microsoftonline.com//oauth2/v2.0/token +signout_redirect_url = allowed_domains = allowed_groups = allowed_organizations = @@ -722,6 +738,7 @@ scopes = openid profile email groups auth_url = https://.okta.com/oauth2/v1/authorize token_url = https://.okta.com/oauth2/v1/token api_url = https://.okta.com/oauth2/v1/userinfo +signout_redirect_url = allowed_domains = allowed_groups = role_attribute_path = @@ -758,6 +775,7 @@ team_ids_attribute_path = auth_url = token_url = api_url = +signout_redirect_url = teams_url = allowed_domains = allowed_groups = @@ -808,6 +826,7 @@ auto_sign_up = false url_login = false allow_assign_grafana_admin = false skip_org_role_sync = false +signout_redirect_url = #################################### Auth LDAP ########################### [auth.ldap] @@ -1128,8 +1147,8 @@ execute_alerts = true # The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. evaluation_timeout = 30s -# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence. -max_attempts = 3 +# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is 1. +max_attempts = 1 # Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence. # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. @@ -1220,6 +1239,13 @@ loki_basic_auth_password = # ex. # mylabelkey = mylabelvalue +[unified_alerting.upgrade] +# If set to true when upgrading from legacy alerting to Unified Alerting, grafana will first delete all existing +# Unified Alerting resources, thus re-upgrading all organizations from scratch. If false or unset, organizations that +# have previously upgraded will not lose their existing Unified Alerting data when switching between legacy and +# Unified Alerting. Should be kept false when not needed as it may cause unintended data-loss if left enabled. +clean_upgrade = false + # NOTE: this configuration options are not used yet. [remote.alertmanager] @@ -1507,6 +1533,10 @@ public_key_retrieval_on_startup = false disable_plugins = # Auth token for plugin installations and removal in managed instances install_token = +# Comma separated list of plugin ids for which angular deprecation UI should be disabled +hide_angular_deprecation = +# Comma separated list of plugin ids for which environment variables should be forwarded. Used only when feature flag pluginsSkipHostEnvVars is enabled. +forward_host_env_vars = #################################### Grafana Live ########################################## [live] @@ -1562,6 +1592,10 @@ rendering_verbose_logging = # Default is false. This can be useful to enable (true) when troubleshooting. rendering_dumpio = +# Instruct headless browser instance whether to register metrics for the duration of every rendering step. Default is false. +# This can be useful to enable (true) when optimizing the rendering mode settings to improve the plugin performance or when troubleshooting. +rendering_timing_metrics = + # Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found # here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character. rendering_args = diff --git a/conf/sample.ini b/conf/sample.ini index 6b556b8144fe7..868b5fc62d0eb 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -10,6 +10,7 @@ ;instance_name = ${HOSTNAME} # force migration will run migrations that might cause dataloss +# Deprecated, use clean_upgrade option in [unified_alerting.upgrade] instead. ;force_migration = false #################################### Paths #################################### @@ -554,6 +555,17 @@ # Use email lookup in addition to the unique ID provided by the IdP ;oauth_allow_insecure_email_lookup = false +# Set to true to include id of identity as a response header +;id_response_header_enabled = false + +# Prefix used for the id response header, X-Grafana-Identity-Id +;id_response_header_prefix = X-Grafana + +# List of identity namespaces to add id response headers for, separated by space. +# Available namespaces are user, api-key and service-account. +# The header value will encode the namespace ("user:", "api-key:", "service-account:") +;id_response_header_namespaces = user api-key service-account + #################################### Anonymous Auth ###################### [auth.anonymous] # enable anonymous access @@ -581,6 +593,7 @@ ;auth_url = https://github.com/login/oauth/authorize ;token_url = https://github.com/login/oauth/access_token ;api_url = https://api.github.com/user +;signout_redirect_url = ;allowed_domains = ;team_ids = ;allowed_organizations = @@ -602,6 +615,7 @@ ;auth_url = https://gitlab.com/oauth/authorize ;token_url = https://gitlab.com/oauth/token ;api_url = https://gitlab.com/api/v4 +;signout_redirect_url = ;allowed_domains = ;allowed_groups = ;role_attribute_path = @@ -627,6 +641,7 @@ ;auth_url = https://accounts.google.com/o/oauth2/v2/auth ;token_url = https://oauth2.googleapis.com/token ;api_url = https://openidconnect.googleapis.com/v1/userinfo +;signout_redirect_url = ;allowed_domains = ;hosted_domain = ;allowed_groups = @@ -661,6 +676,7 @@ ;scopes = openid email profile ;auth_url = https://login.microsoftonline.com//oauth2/v2.0/authorize ;token_url = https://login.microsoftonline.com//oauth2/v2.0/token +;signout_redirect_url = ;allowed_domains = ;allowed_groups = ;allowed_organizations = @@ -682,6 +698,7 @@ ;auth_url = https://.okta.com/oauth2/v1/authorize ;token_url = https://.okta.com/oauth2/v1/token ;api_url = https://.okta.com/oauth2/v1/userinfo +;signout_redirect_url = ;allowed_domains = ;allowed_groups = ;role_attribute_path = @@ -708,6 +725,7 @@ ;auth_url = https://foo.bar/login/oauth/authorize ;token_url = https://foo.bar/login/oauth/access_token ;api_url = https://foo.bar/user +;signout_redirect_url = ;teams_url = ;allowed_domains = ;team_ids = @@ -1076,8 +1094,8 @@ # The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. ;evaluation_timeout = 30s -# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. This option has a legacy version in the `[alerting]` section that takes precedence. -;max_attempts = 3 +# Number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is 1. +;max_attempts = 1 # Minimum interval to enforce between rule evaluations. Rules will be adjusted if they are less than this value or if they are not multiple of the scheduler interval (10s). Higher values can help with resource management as we'll schedule fewer evaluations over time. This option has a legacy version in the `[alerting]` section that takes precedence. # The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. @@ -1138,6 +1156,13 @@ # Any number of label key-value-pairs can be provided. ; mylabelkey = mylabelvalue +[unified_alerting.upgrade] +# If set to true when upgrading from legacy alerting to Unified Alerting, grafana will first delete all existing +# Unified Alerting resources, thus re-upgrading all organizations from scratch. If false or unset, organizations that +# have previously upgraded will not lose their existing Unified Alerting data when switching between legacy and +# Unified Alerting. Should be kept false when not needed as it may cause unintended data-loss if left enabled. +;clean_upgrade = false + #################################### Alerting ############################ [alerting] # Disable legacy alerting engine & UI features diff --git a/contribute/backend/style-guide.md b/contribute/backend/style-guide.md index 08d1eb8ff99d3..17a063d3dc521 100644 --- a/contribute/backend/style-guide.md +++ b/contribute/backend/style-guide.md @@ -66,25 +66,23 @@ Use [`t.Cleanup`](https://golang.org/pkg/testing/#T.Cleanup) to clean up resourc ### Mock -Optionally, we use [`mock.Mock`](https://github.com/stretchr/testify#mock-package) package to generate mocks. This is +Optionally, we use [`mock.Mock`](https://github.com/stretchr/testify#mock-package) package to write mocks. This is useful when you expect different behaviours of the same function. #### Tips -- Use `Once()` or `Times(n)` to make this mock only works `n` times. -- Use `mockedClass.AssertExpectations(t)` to guarantee that the mock is called the times asked. - - If any mock set is not called or its expects more calls, the test fails. +- Use `Once()` or `Times(n)` to make a method call work `n` times. +- Use `mockedClass.AssertExpectations(t)` to guarantee that methods are called the times asked. + - If any method is not called the expected amount of times, the test fails. - You can pass `mock.Anything` as argument if you don't care about the argument passed. -- Use `mockedClass.AssertNotCalled(t, "FunctionName")` to assert that this test is not called. +- Use `mockedClass.AssertNotCalled(t, "MethodName")` to assert that a method was not called. #### Example -This is an example to easily create a mock of an interface. - Given this interface: ```go -func MyInterface interface { +type MyInterface interface { Get(ctx context.Context, id string) (Object, error) } ``` @@ -92,39 +90,38 @@ func MyInterface interface { Mock implementation should be like this: ```go -import +import "github.com/stretchr/testify/mock" -func MockImplementation struct { +type MockImplementation struct { mock.Mock } -func (m *MockImplementation) Get(ctx context.Context, id string) error { +func (m *MockImplementation) Get(ctx context.Context, id string) (Object, error) { args := m.Called(ctx, id) // Pass all arguments in order here return args.Get(0).(Object), args.Error(1) } ``` -And use it as the following way: +And use it in the following way: ```go - objectToReturn := Object{Message: "abc"} errToReturn := errors.New("my error") myMock := &MockImplementation{} defer myMock.AssertExpectations(t) -myMock.On("Get", mock.Anything, "id1").Return(objectToReturn, errToReturn).Once() -myMock.On("Get", mock.Anything, "id2").Return(Object{}, nil).Once() +myMock.On("Get", mock.Anything, "id1").Return(Object{}, errToReturn).Once() +myMock.On("Get", mock.Anything, "id2").Return(objectToReturn, nil).Once() anyService := NewService(myMock) -resp, err := anyService.Call("id1") -assert.Equal(t, resp.Message, objectToReturn.Message) +resp, err := anyService.Call("id1") assert.Error(t, err, errToReturn) resp, err = anyService.Call("id2") assert.Nil(t, err) +assert.Equal(t, resp.Message, objectToReturn.Message) ``` #### Mockery diff --git a/contribute/deprecation-policy.md b/contribute/deprecation-policy.md new file mode 100644 index 0000000000000..a49016588a147 --- /dev/null +++ b/contribute/deprecation-policy.md @@ -0,0 +1,31 @@ +# Deprecation policy + +We do our best to limit breaking changes and the deprecation of features to major releases. We always do our best **not** to introduce breaking changes in order to make upgrading Grafana as easy and reliable as possible. However, at times we have to introduce a breaking change by changing behavior or by removing a feature. + +To minimize the negative effects of removing a feature we require a deprecation plan that includes: + +- Determine usage levels of the feature. +- Find alternative solutions and possible migration paths. +- Announce deprecation of the feature. +- Migrate users if possible +- Give users time to adjust to the deprecation. +- Disable the feature by default. +- Remove the feature from the code base. + +Depending on the size and importance of the feature this can be a design doc or an issue. We want this to be written communication for all parties so we know it's intentional and that did a reasonable attempt to avoid breaking changes unless needed. The size of the feature also means different notice times between Depreciation and disabling as well as disabling and removal. The actual duration will depend on releases of Grafana and the table below should be used as a guide. + +Grafana employees can find more details in our internal docs. + +## Grace period between announcement and disabling feature by default + +| Size | Duration | Example | +| ------ | ---------- | ---------------------------------------------------------------- | +| Large | 1-2 years | Classic alerting, scripted dashboards, AngularJS | +| Medium | 6 months | Supported Database for Grafana's backend | +| Small | 1-3 months | Refresh OAuth access_token automatically using the refresh_token | + +## Announced deprecations. + +| Name | Annoucement Date | Disabling date | Removal Date | Description | Status | +| ------------------------------------------------------------------------ | ---------------- | -------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------- | ------- | +| [Support for Mysql 5.7](https://github.com/grafana/grafana/issues/68446) | 2023-05-15 | October 2023 | | MySQL 5.7 is being deprecated in October 2023 and Grafana's policy is to test against the officially supported version. | Planned | diff --git a/contribute/internationalization.md b/contribute/internationalization.md index 726fb7b4b102c..243db35efe21a 100644 --- a/contribute/internationalization.md +++ b/contribute/internationalization.md @@ -189,6 +189,23 @@ Once extracted with `yarn i18n:extract` you will need to manually edit the [Engl } ``` +## Feedback + +**Please note:** This is only for proofreaders with permissions to Grafana OSS project on Crowdin. + +To provide feedback on translations, sign into Crowdin and follow these steps: + +1. Open the Grafana OSS project in Crowdin. +2. In the left-hand menu, click on the 'Dashboard' menu item. +3. A list of available languages appears under the 'Translations' section. Click on the one you want to comment on. +4. There is a table with the file structure in it: +
+ `grafana/main > public > locales > 'language denomination' > grafana.json` +
+ Click on the `grafana.json` file. +5. In the left-hand section, click on the 'Search in file' input and search for the string that you want to comment on. You can search in English, as it is the default language, or in the language the string is translated to. +6. Once you have found the string, on the right hand side there is a 'Comments' section where you can send the feedback about the translation. Tag @Translated to be sure the team of linguists gets notified. + ## Documentation [Grafana's documentation](https://grafana.com/docs/grafana/latest/) is not yet open for translation and should be authored in American English only. diff --git a/contribute/merge-pull-request.md b/contribute/merge-pull-request.md index ac81ef130ce48..8350d98a8637e 100644 --- a/contribute/merge-pull-request.md +++ b/contribute/merge-pull-request.md @@ -115,25 +115,12 @@ In case the pull request introduces a breaking change you should document this. ``` -### Should the pull request be backported? +### Backporting Backporting is the process of copying the pull request into the version branch of one or multiple previous releases. -This should only be done for _critical bug fixes_ and involves the intervention of a Grafana Labs employee. -To make this decision explicit, there is a **Backport Check** that is re-evaluated automatically by adding/removing labels on the pull request. +This is a rare exception, should only be done for _critical bug fixes_, and involves the intervention of a Grafana Labs employee. -#### No backport - -If you don't want to backport you need to add a label named **no-backport** to the pull request. - -This should be the default! - -#### Backport - -If your pull request fixes a critical bug and needs to go into one or several existing release branches it should be backported. - -For a pull request to be backported, please add it to "Critical Bug Release" form so that the delivery team is aware that a release for a previous version needs to be made. -Once approved, the backporting process will continue from there. -In the meantime, set the `no-backport` label. +If your pull request fixes a critical bug and needs to be backported, add it to the "Critical Bug Release" form so the team can approve the backport and know that a release needs to be made. Specify the correct `backport vx.x` labels for the releases the fix needs to be backported to. Once approved, the backporting process will continue from there. #### Required labels diff --git a/crowdin.yml b/crowdin.yml index cdfc752c78ac7..1cdf69254dfa2 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,8 +1,8 @@ files: - source: /public/locales/en-US/grafana.json translation: /public/locales/%locale%/%original_file_name% + type: i18next_json pull_request_title: 'I18n: Crowdin sync' pull_request_labels: - area/internationalization - no-changelog - - no-backport diff --git a/cypress.config.js b/cypress.config.js index 856fb85f022ed..52263a9e4d00f 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -3,7 +3,6 @@ const fs = require('fs'); const path = require('path'); const benchmarkPlugin = require('./e2e/cypress/plugins/benchmark/index'); -const compareScreenshots = require('./e2e/cypress/plugins/compareScreenshots'); const readProvisions = require('./e2e/cypress/plugins/readProvisions'); const typescriptPreprocessor = require('./e2e/cypress/plugins/typescriptPreprocessor'); @@ -29,7 +28,6 @@ module.exports = defineConfig({ } on('task', { - compareScreenshots, readProvisions: (filePaths) => readProvisions({ CWD: process.cwd(), filePaths }), }); diff --git a/devenv/dev-dashboards/panel-dashlist/dashlist.json b/devenv/dev-dashboards/panel-dashlist/dashlist.json new file mode 100644 index 0000000000000..8db5b616acd76 --- /dev/null +++ b/devenv/dev-dashboards/panel-dashlist/dashlist.json @@ -0,0 +1,86 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "folderUID": "", + "includeVars": true, + "keepTime": false, + "maxItems": 10, + "query": "", + "showHeadings": true, + "showRecentlyViewed": true, + "showSearch": false, + "showStarred": false, + "tags": [] + }, + "pluginVersion": "10.3.0-pre", + "title": "Include time range and variables enabled", + "type": "dashlist" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": ["gdev", "panel-tests"], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "A", + "value": "A" + }, + "hide": 0, + "includeAll": false, + "multi": true, + "name": "server", + "query": "A,B,C,D", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "", + "title": "Panel Tests - DashList", + "uid": "a6801696-cc53-4196-b1f9-2403e3909185", + "version": 1, + "weekStart": "" +} diff --git a/devenv/dev-dashboards/panel-xychart/xychart-example.json b/devenv/dev-dashboards/panel-xychart/xychart-example.json new file mode 100644 index 0000000000000..cecdcb0e49d9f --- /dev/null +++ b/devenv/dev-dashboards/panel-xychart/xychart-example.json @@ -0,0 +1,1855 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "red", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points+lines" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 20, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [], + "seriesMapping": "auto", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "csvContent": "X,Y\n725.1,435.6\n734.1,497.2\n714.3,527.7\n683.5,548.7\n601.8,594.0\n598.5,621.7\n573.9,644.7\n525.7,695.7\n477.2,732.8\n411.8,755.3\n353.6,758.3\n422.6,736.5\n455.3,724.1\n479.2,699.2\n474.0,673.8\n434.5,662.1\n362.2,679.8\n311.2,698.8\n260.1,728.9\n213.4,771.1\n176.2,818.0\n211.2,742.6\n253.9,707.9\n309.9,668.8\n374.7,643.2\n322.8,629.9\n277.1,607.1\n237.0,616.8\n188.9,613.9\n143.0,594.1\n101.8,566.4\n178.1,590.2\n222.2,575.9\n187.9,549.1\n161.5,517.5\n128.6,506.8\n97.3,488.3\n62.4,436.0\n99.6,473.8\n138.3,477.0\n125.0,396.7\n95.6,359.2\n83.6,322.1\n81.0,289.7\n104.0,343.8\n129.3,358.4\n151.2,291.1\n124.0,242.6\n126.3,170.2\n133.7,212.8\n148.4,243.3\n167.9,262.7\n209.1,205.7\n230.1,150.3\n231.4,120.1\n316.0,120.1\n400.6,120.1\n485.2,120.1\n569.8,120.1\n569.3,166.4\n553.0,205.5\n489.2,265.7\n422.2,309.1\n353.7,343.1\n328.2,386.3\n321.6,432.6\n334.1,473.1\n357.6,500.3\n389.9,508.5\n418.8,479.9\n447.9,413.3\n480.0,379.0\n521.6,354.2\n583.9,351.6\n549.7,357.7\n571.6,376.0\n517.1,380.8\n550.3,393.2\n504.3,402.3\n489.5,425.8\n527.5,425.8\n472.7,457.2\n447.1,523.8\n538.6,435.7\n598.4,403.7\n697.8,349.1\n645.3,390.4\n712.3,373.8\n586.0,424.1\n526.9,463.3\n469.5,538.0\n540.6,477.5\n531.2,528.4\n598.6,460.1\n594.5,509.0\n651.2,460.1\n649.9,502.6\n699.4,446.1\n707.6,477.1\n722.0,442.9", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "CNC/Routing \"Etch-A-Sketch\"", + "type": "xychart" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "red", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Weight Male" + }, + "properties": [ + { + "id": "custom.axisLabel", + "value": "Weight" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Height Male" + }, + "properties": [ + { + "id": "custom.axisLabel", + "value": "Height" + } + ] + } + ] + }, + "gridPos": { + "h": 20, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 4, + "options": { + "dims": { + "exclude": [], + "frame": 0, + "x": "A-series" + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [ + { + "name": "Male", + "pointColor": { + "fixed": "#5795f200" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Height Male", + "y": "Weight Male" + }, + { + "name": "Female", + "pointColor": { + "fixed": "#ff983000" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Height Female", + "y": "Weight Female" + } + ], + "seriesMapping": "manual", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "csvFileName": "weight_height.csv", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_file" + } + ], + "title": "Height vs Weight Samples", + "transformations": [ + { + "id": "partitionByValues", + "options": { + "fields": [ + "Gender" + ] + } + } + ], + "type": "xychart" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "red", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "lines" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "x^2" + }, + "properties": [ + { + "id": "custom.lineStyle", + "value": { + "dash": [ + 10, + 15 + ], + "fill": "dash" + } + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "cos(x)" + }, + "properties": [ + { + "id": "custom.axisLabel", + "value": "y" + } + ] + } + ] + }, + "gridPos": { + "h": 17, + "w": 9, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "dims": { + "frame": 0 + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [ + { + "name": "cos(x)", + "pointColor": { + "fixed": "green" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "x", + "y": "cos(x)" + }, + { + "name": "x^2", + "pointColor": { + "fixed": "orange" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "x2", + "y": "x^2" + }, + { + "name": "sqrt(x)", + "pointColor": { + "fixed": "blue" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "x3", + "y": "sqrt(x)" + }, + { + "name": "-sqrt(x)", + "pointColor": { + "fixed": "purple" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "x4", + "y": "-sqrt(x)" + } + ], + "seriesMapping": "manual", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "alias": "", + "csvContent": "x,cos(x)\n-7.5,3.4663531783502584\n-7.45,3.9308257356494076\n-7.4,4.385473275743903\n-7.35,4.829159416559378\n-7.3,5.260775173811053\n-7.25,5.679241732886949\n-7.2,6.083513145322545\n-7.15,6.472578943127236\n-7.1,6.845466664428066\n-7.05,7.201244284117942\n-7,7.539022543433046\n-6.95,7.857957172636611\n-6.9,8.157251001253568\n-6.85,8.436155950581597\n-6.8,8.693974903498253\n-6.75,8.930063446890767\n-6.7,9.143831482353194\n-6.65,9.334744701125118\n-6.6,9.502325919585296\n-6.55,9.64615627196218\n-6.5,9.765876257280235\n-6.45,9.861186637925126\n-6.4,9.931849187581927\n-6.35,9.97768728667684\n-6.3,9.998586363834152\n-6.25,9.994494182244994\n-6.2,9.965420970232175\n-6.15,9.91143939568469\n-6.1,9.832684384425844\n-6.05,9.729352782968974\n-6,9.601702866503661\n-5.95,9.450053693342275\n-5.9,9.27478430744036\n-5.85,9.076332790984132\n-5.8,8.85519516941319\n-5.75,8.611924171615208\n-5.7,8.347127848391597\n-5.65,8.061468052647157\n-5.6,7.755658785102496\n-5.55,7.430464409664099\n-5.5,7.0866977429126\n-5.45,6.725218022484659\n-5.4,6.346928759426347\n-5.35,5.952775479886061\n-5.3,5.543743361791607\n-5.25,5.120854772418407\n-5.2,4.685166713003771\n-5.15,4.237768176794282\n-5.1,3.7797774271298024\n-5.05,3.3123392023675367\n-5,2.8366218546322624\n-4.95,2.353814429544512\n-4.9,1.8651236942257576\n-4.85,1.371771121009073\n-4.8,0.874989834394464\n-4.75,0.37602152887976553\n-4.7,-0.1238866346289056\n-4.65,-0.6234851460699166\n-4.6,-1.1215252693505486\n-4.55,-1.616762163536865\n-4.5,-2.107957994307797\n-4.45,-2.593885027896261\n-4.4,-3.0733286997841933\n-4.35,-3.5450906504813195\n-4.3,-4.007991720799755\n-4.25,-4.460874899137928\n-4.2,-4.902608213406994\n-4.15,-5.332087560371543\n-4.1,-5.748239465332691\n-4.05,-6.150023765255744\n-4,-6.536436208636119\n-3.95,-6.906510965605075\n-3.9,-7.259323042001402\n-3.85,-7.593990591375079\n-3.8,-7.909677119144169\n-3.75,-8.205593573395607\n-3.7,-8.48100031710408\n-3.65,-8.73520897683938\n-3.6,-8.96758416334147\n-3.55,-9.177545059662759\n-3.5,-9.364566872907963\n-3.45,-9.528182145943047\n-3.4,-9.66798192579461\n-3.35,-9.78361678581934\n-3.3,-9.87479769908865\n-3.25,-9.941296760805463\n-3.2,-9.982947757947532\n-3.15,-9.99964658471342\n-3.1,-9.991351502732794\n-3.05,-9.958083245390611\n-3,-9.899924966004454\n-2.95,-9.81702202998454\n-2.9,-9.709581651495906\n-2.85,-9.577872375530903\n-2.8,-9.42222340668658\n-2.75,-9.243023786324635\n-2.7,-9.040721420170613\n-2.65,-8.815821958782859\n-2.6,-8.568887533689473\n-2.55,-8.30053535235222\n-2.5,-8.011436155469337\n-2.45,-7.702312540473074\n-2.4,-7.373937155412454\n-2.35,-7.027130767735539\n-2.3,-6.66276021279824\n-2.25,-6.281736227227391\n-2.2,-5.885011172553458\n-2.15,-5.473576654802709\n-2.1,-5.048461045998575\n-2.05,-4.610726913767127\n-2,-4.161468365471424\n-1.95,-3.7018083135128688\n-1.9,-3.2328956686350336\n-1.85,-2.7559024682451296\n-1.8,-2.272020946930871\n-1.75,-1.7824605564949207\n-1.7,-1.2884449429552465\n-1.65,-0.7912088880673386\n-1.6,-0.29199522301288816\n-1.55,0.20794827803092428\n-1.5,0.7073720166770291\n-1.45,1.2050276936736661\n-1.4,1.6996714290024104\n-1.35,2.1900668709304147\n-1.3,2.6749882862458736\n-1.25,3.1532236239526865\n-1.2,3.623577544766736\n-1.15,4.084874408841574\n-1.1,4.5359612142557735\n-1.05,4.97571047891727\n-1,5.403023058681398\n-0.95,5.8168308946388345\n-0.9,6.216099682706644\n-0.85,6.599831458849822\n-0.8,6.967067093471654\n-0.75,7.316888688738209\n-0.7,7.648421872844885\n-0.65,7.960837985490558\n-0.6,8.253356149096783\n-0.55,8.525245220595057\n-0.5,8.775825618903728\n-0.45,9.004471023526769\n-0.4,9.210609940028851\n-0.35,9.393727128473788\n-0.3,9.55336489125606\n-0.25,9.689124217106448\n-0.2,9.800665778412416\n-0.15,9.887710779360422\n-0.1,9.950041652780257\n-0.05,9.987502603949663\n0,10\n0.05,9.987502603949663\n0.1,9.950041652780257\n0.15,9.887710779360422\n0.2,9.800665778412416\n0.25,9.689124217106448\n0.3,9.55336489125606\n0.35,9.393727128473788\n0.4,9.210609940028851\n0.45,9.004471023526769\n0.5,8.775825618903728\n0.55,8.525245220595057\n0.6,8.253356149096783\n0.65,7.960837985490558\n0.7,7.648421872844885\n0.75,7.316888688738209\n0.8,6.967067093471654\n0.85,6.599831458849822\n0.9,6.216099682706644\n0.95,5.8168308946388345\n1,5.403023058681398\n1.05,4.97571047891727\n1.1,4.5359612142557735\n1.15,4.084874408841574\n1.2,3.623577544766736\n1.25,3.1532236239526865\n1.3,2.6749882862458736\n1.35,2.1900668709304147\n1.4,1.6996714290024104\n1.45,1.2050276936736661\n1.5,0.7073720166770291\n1.55,0.20794827803092428\n1.6,-0.29199522301288816\n1.65,-0.7912088880673386\n1.7,-1.2884449429552465\n1.75,-1.7824605564949207\n1.8,-2.272020946930871\n1.85,-2.7559024682451296\n1.9,-3.2328956686350336\n1.95,-3.7018083135128688\n2,-4.161468365471424\n2.05,-4.610726913767127\n2.1,-5.048461045998575\n2.15,-5.473576654802709\n2.2,-5.885011172553458\n2.25,-6.281736227227391\n2.3,-6.66276021279824\n2.35,-7.027130767735539\n2.4,-7.373937155412454\n2.45,-7.702312540473074\n2.5,-8.011436155469337\n2.55,-8.30053535235222\n2.6,-8.568887533689473\n2.65,-8.815821958782859\n2.7,-9.040721420170613\n2.75,-9.243023786324635\n2.8,-9.42222340668658\n2.85,-9.577872375530903\n2.9,-9.709581651495906\n2.95,-9.81702202998454\n3,-9.899924966004454\n3.05,-9.958083245390611\n3.1,-9.991351502732794\n3.15,-9.99964658471342\n3.2,-9.982947757947532\n3.25,-9.941296760805463\n3.3,-9.87479769908865\n3.35,-9.78361678581934\n3.4,-9.66798192579461\n3.45,-9.528182145943047\n3.5,-9.364566872907963\n3.55,-9.177545059662759\n3.6,-8.96758416334147\n3.65,-8.73520897683938\n3.7,-8.48100031710408\n3.75,-8.205593573395607\n3.8,-7.909677119144169\n3.85,-7.593990591375079\n3.9,-7.259323042001402\n3.95,-6.906510965605075\n4,-6.536436208636119\n4.05,-6.150023765255744\n4.1,-5.748239465332691\n4.15,-5.332087560371543\n4.2,-4.902608213406994\n4.25,-4.460874899137928\n4.3,-4.007991720799755\n4.35,-3.5450906504813195\n4.4,-3.0733286997841933\n4.45,-2.593885027896261\n4.5,-2.107957994307797\n4.55,-1.616762163536865\n4.6,-1.1215252693505486\n4.65,-0.6234851460699166\n4.7,-0.1238866346289056\n4.75,0.37602152887976553\n4.8,0.874989834394464\n4.85,1.371771121009073\n4.9,1.8651236942257576\n4.95,2.353814429544512\n5,2.8366218546322624\n5.05,3.3123392023675367\n5.1,3.7797774271298024\n5.15,4.237768176794282\n5.2,4.685166713003771\n5.25,5.120854772418407\n5.3,5.543743361791607\n5.35,5.952775479886061\n5.4,6.346928759426347\n5.45,6.725218022484659\n5.5,7.0866977429126\n5.55,7.430464409664099\n5.6,7.755658785102496\n5.65,8.061468052647157\n5.7,8.347127848391597\n5.75,8.611924171615208\n5.8,8.85519516941319\n5.85,9.076332790984132\n5.9,9.27478430744036\n5.95,9.450053693342275\n6,9.601702866503661\n6.05,9.729352782968974\n6.1,9.832684384425844\n6.15,9.91143939568469\n6.2,9.965420970232175\n6.25,9.994494182244994\n6.3,9.998586363834152\n6.35,9.97768728667684\n6.4,9.931849187581927\n6.45,9.861186637925126\n6.5,9.765876257280235\n6.55,9.64615627196218\n6.6,9.502325919585296\n6.65,9.334744701125118\n6.7,9.143831482353194\n6.75,8.930063446890767\n6.8,8.693974903498253\n6.85,8.436155950581597\n6.9,8.157251001253568\n6.95,7.857957172636611\n7,7.539022543433046\n7.05,7.201244284117942\n7.1,6.845466664428066\n7.15,6.472578943127236\n7.2,6.083513145322545\n7.25,5.679241732886949\n7.3,5.260775173811053\n7.35,4.829159416559378\n7.4,4.385473275743903\n7.45,3.9308257356494076", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + }, + { + "csvContent": "x2,x^2\n-7.5,56.25\n-7.45,55.502500000000005\n-7.4,54.760000000000005\n-7.35,54.022499999999994\n-7.3,53.29\n-7.25,52.5625\n-7.2,51.84\n-7.15,51.1225\n-7.1,50.41\n-7.05,49.7025\n-7,49\n-6.95,48.3025\n-6.9,47.61000000000001\n-6.85,46.92249999999999\n-6.8,46.239999999999995\n-6.75,45.5625\n-6.7,44.89\n-6.65,44.222500000000004\n-6.6,43.559999999999995\n-6.55,42.902499999999996\n-6.5,42.25\n-6.45,41.6025\n-6.4,40.96000000000001\n-6.35,40.3225\n-6.3,39.69\n-6.25,39.0625\n-6.2,38.440000000000005\n-6.15,37.822500000000005\n-6.1,37.209999999999994\n-6.05,36.6025\n-6,36\n-5.95,35.4025\n-5.9,34.81\n-5.85,34.2225\n-5.8,33.64\n-5.75,33.0625\n-5.7,32.49\n-5.65,31.922500000000003\n-5.6,31.359999999999996\n-5.55,30.8025\n-5.5,30.25\n-5.45,29.7025\n-5.4,29.160000000000004\n-5.35,28.622499999999995\n-5.3,28.09\n-5.25,27.5625\n-5.2,27.040000000000003\n-5.15,26.522500000000004\n-5.1,26.009999999999998\n-5.05,25.502499999999998\n-5,25\n-4.95,24.5025\n-4.9,24.010000000000005\n-4.85,23.522499999999997\n-4.8,23.04\n-4.75,22.5625\n-4.7,22.090000000000003\n-4.65,21.622500000000002\n-4.6,21.159999999999997\n-4.55,20.702499999999997\n-4.5,20.25\n-4.45,19.802500000000002\n-4.4,19.360000000000003\n-4.35,18.922499999999996\n-4.3,18.49\n-4.25,18.0625\n-4.2,17.64\n-4.15,17.222500000000004\n-4.1,16.81\n-4.05,16.4025\n-4,16\n-3.95,15.602500000000001\n-3.9,15.209999999999999\n-3.85,14.822500000000002\n-3.8,14.44\n-3.75,14.0625\n-3.7,13.690000000000001\n-3.65,13.3225\n-3.6,12.96\n-3.55,12.6025\n-3.5,12.25\n-3.45,11.902500000000002\n-3.4,11.559999999999999\n-3.35,11.2225\n-3.3,10.889999999999999\n-3.25,10.5625\n-3.2,10.240000000000002\n-3.15,9.9225\n-3.1,9.610000000000001\n-3.05,9.302499999999998\n-3,9\n-2.95,8.7025\n-2.9,8.41\n-2.85,8.1225\n-2.8,7.839999999999999\n-2.75,7.5625\n-2.7,7.290000000000001\n-2.65,7.0225\n-2.6,6.760000000000001\n-2.55,6.5024999999999995\n-2.5,6.25\n-2.45,6.002500000000001\n-2.4,5.76\n-2.35,5.522500000000001\n-2.3,5.289999999999999\n-2.25,5.0625\n-2.2,4.840000000000001\n-2.15,4.6225\n-2.1,4.41\n-2.05,4.2025\n-2,4\n-1.95,3.8024999999999998\n-1.9,3.61\n-1.85,3.4225000000000003\n-1.8,3.24\n-1.75,3.0625\n-1.7,2.8899999999999997\n-1.65,2.7224999999999997\n-1.6,2.5600000000000005\n-1.55,2.4025000000000003\n-1.5,2.25\n-1.45,2.1025\n-1.4,1.9599999999999997\n-1.35,1.8225000000000002\n-1.3,1.6900000000000002\n-1.25,1.5625\n-1.2,1.44\n-1.15,1.3224999999999998\n-1.1,1.2100000000000002\n-1.05,1.1025\n-1,1\n-0.95,0.9025\n-0.9,0.81\n-0.85,0.7224999999999999\n-0.8,0.6400000000000001\n-0.75,0.5625\n-0.7,0.48999999999999994\n-0.65,0.42250000000000004\n-0.6,0.36\n-0.55,0.30250000000000005\n-0.5,0.25\n-0.45,0.2025\n-0.4,0.16000000000000003\n-0.35,0.12249999999999998\n-0.3,0.09\n-0.25,0.0625\n-0.2,0.04000000000000001\n-0.15,0.0225\n-0.1,0.010000000000000002\n-0.05,0.0025000000000000005\n0,0\n0.05,0.0025000000000000005\n0.1,0.010000000000000002\n0.15,0.0225\n0.2,0.04000000000000001\n0.25,0.0625\n0.3,0.09\n0.35,0.12249999999999998\n0.4,0.16000000000000003\n0.45,0.2025\n0.5,0.25\n0.55,0.30250000000000005\n0.6,0.36\n0.65,0.42250000000000004\n0.7,0.48999999999999994\n0.75,0.5625\n0.8,0.6400000000000001\n0.85,0.7224999999999999\n0.9,0.81\n0.95,0.9025\n1,1\n1.05,1.1025\n1.1,1.2100000000000002\n1.15,1.3224999999999998\n1.2,1.44\n1.25,1.5625\n1.3,1.6900000000000002\n1.35,1.8225000000000002\n1.4,1.9599999999999997\n1.45,2.1025\n1.5,2.25\n1.55,2.4025000000000003\n1.6,2.5600000000000005\n1.65,2.7224999999999997\n1.7,2.8899999999999997\n1.75,3.0625\n1.8,3.24\n1.85,3.4225000000000003\n1.9,3.61\n1.95,3.8024999999999998\n2,4\n2.05,4.2025\n2.1,4.41\n2.15,4.6225\n2.2,4.840000000000001\n2.25,5.0625\n2.3,5.289999999999999\n2.35,5.522500000000001\n2.4,5.76\n2.45,6.002500000000001\n2.5,6.25\n2.55,6.5024999999999995\n2.6,6.760000000000001\n2.65,7.0225\n2.7,7.290000000000001\n2.75,7.5625\n2.8,7.839999999999999\n2.85,8.1225\n2.9,8.41\n2.95,8.7025\n3,9\n3.05,9.302499999999998\n3.1,9.610000000000001\n3.15,9.9225\n3.2,10.240000000000002\n3.25,10.5625\n3.3,10.889999999999999\n3.35,11.2225\n3.4,11.559999999999999\n3.45,11.902500000000002\n3.5,12.25\n3.55,12.6025\n3.6,12.96\n3.65,13.3225\n3.7,13.690000000000001\n3.75,14.0625\n3.8,14.44\n3.85,14.822500000000002\n3.9,15.209999999999999\n3.95,15.602500000000001\n4,16\n4.05,16.4025\n4.1,16.81\n4.15,17.222500000000004\n4.2,17.64\n4.25,18.0625\n4.3,18.49\n4.35,18.922499999999996\n4.4,19.360000000000003\n4.45,19.802500000000002\n4.5,20.25\n4.55,20.702499999999997\n4.6,21.159999999999997\n4.65,21.622500000000002\n4.7,22.090000000000003\n4.75,22.5625\n4.8,23.04\n4.85,23.522499999999997\n4.9,24.010000000000005\n4.95,24.5025\n5,25\n5.05,25.502499999999998\n5.1,26.009999999999998\n5.15,26.522500000000004\n5.2,27.040000000000003\n5.25,27.5625\n5.3,28.09\n5.35,28.622499999999995\n5.4,29.160000000000004\n5.45,29.7025\n5.5,30.25\n5.55,30.8025\n5.6,31.359999999999996\n5.65,31.922500000000003\n5.7,32.49\n5.75,33.0625\n5.8,33.64\n5.85,34.2225\n5.9,34.81\n5.95,35.4025\n6,36\n6.05,36.6025\n6.1,37.209999999999994\n6.15,37.822500000000005\n6.2,38.440000000000005\n6.25,39.0625\n6.3,39.69\n6.35,40.3225\n6.4,40.96000000000001\n6.45,41.6025\n6.5,42.25\n6.55,42.902499999999996\n6.6,43.559999999999995\n6.65,44.222500000000004\n6.7,44.89\n6.75,45.5625\n6.8,46.239999999999995\n6.85,46.92249999999999\n6.9,47.61000000000001\n6.95,48.3025\n7,49\n7.05,49.7025\n7.1,50.41\n7.15,51.1225\n7.2,51.84\n7.25,52.5625\n7.3,53.29\n7.35,54.022499999999994\n7.4,54.760000000000005\n7.45,55.502500000000005", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "B", + "scenarioId": "csv_content" + }, + { + "csvContent": "x3,sqrt(x)\n0,0\n0.05,2.23606797749979\n0.1,3.1622776601683795\n0.15,3.872983346207417\n0.2,4.47213595499958\n0.25,5\n0.3,5.47722557505166\n0.35,5.916079783099616\n0.4,6.324555320336759\n0.45,6.708203932499369\n0.5,7.0710678118654755\n0.55,7.416198487095663\n0.6,7.745966692414834\n0.65,8.062257748298551\n0.7,8.366600265340756\n0.75,8.660254037844386\n0.8,8.94427190999916\n0.85,9.219544457292887\n0.9,9.486832980505138\n0.95,9.746794344808963\n1,10\n1.05,10.2469507659596\n1.1,10.488088481701517\n1.15,10.723805294763608\n1.2,10.95445115010332\n1.25,11.180339887498949\n1.3,11.401754250991381\n1.35,11.618950038622252\n1.4,11.832159566199232\n1.45,12.041594578792296\n1.5,12.24744871391589\n1.55,12.449899597988733\n1.6,12.649110640673518\n1.65,12.84523257866513\n1.7,13.038404810405297\n1.75,13.228756555322953\n1.8,13.416407864998739\n1.85,13.601470508735442\n1.9,13.784048752090222\n1.95,13.96424004376894\n2,14.142135623730951\n2.05,14.317821063276352\n2.1,14.49137674618944\n2.15,14.66287829861518\n2.2,14.832396974191326\n2.25,15\n2.3,15.1657508881031\n2.35,15.329709716755893\n2.4,15.491933384829668\n2.45,15.652475842498529\n2.5,15.811388300841898\n2.55,15.968719422671311\n2.6,16.124515496597102\n2.65,16.278820596099706\n2.7,16.431676725154986\n2.75,16.583123951776997\n2.8,16.73320053068151\n2.85,16.881943016134134\n2.9,17.0293863659264\n2.95,17.175564037317667\n3,17.32050807568877\n3.05,17.46424919657298\n3.1,17.60681686165901\n3.15,17.74823934929885\n3.2,17.88854381999832\n3.25,18.027756377319946\n3.3,18.16590212458495\n3.35,18.303005217723125\n3.4,18.439088914585774\n3.45,18.57417562100671\n3.5,18.708286933869708\n3.55,18.84144368141677\n3.6,18.973665961010276\n3.65,19.1049731745428\n3.7,19.235384061671347\n3.75,19.364916731037084\n3.8,19.493588689617926\n3.85,19.621416870348586\n3.9,19.748417658131498\n3.95,19.87460691435179\n4,20\n4.05,20.124611797498105\n4.1,20.248456731316583\n4.15,20.37154878746336\n4.2,20.4939015319192\n4.25,20.615528128088304\n4.3,20.73644135332772\n4.35,20.85665361461421\n4.4,20.976176963403034\n4.45,21.095023109728984\n4.5,21.213203435596423\n4.55,21.330729007701542\n4.6,21.447610589527216\n4.65,21.563858652847827\n4.7,21.6794833886788\n4.75,21.79449471770337\n4.8,21.90890230020664\n4.85,22.022715545545243\n4.9,22.135943621178654\n4.95,22.24859546128699\n5,22.360679774997898\n5.05,22.47220505424423\n5.1,22.58317958127243\n5.15,22.693611435820436\n5.2,22.803508501982762\n5.25,22.9128784747792\n5.3,23.021728866442675\n5.35,23.130067012440755\n5.4,23.237900077244504\n5.45,23.345235059857504\n5.5,23.45207879911715\n5.55,23.55843797877949\n5.6,23.664319132398465\n5.65,23.769728648009426\n5.7,23.874672772626646\n5.75,23.979157616563597\n5.8,24.08318915758459\n5.85,24.186773244895647\n5.9,24.289915602982237\n5.95,24.392621835300936\n6,24.49489742783178\n6.05,24.596747752497684\n6.1,24.698178070456937\n6.15,24.79919353527449\n6.2,24.899799195977465\n6.25,25\n6.3,25.099800796022265\n6.35,25.199206336708304\n6.4,25.298221281347036\n6.45,25.39685019840059\n6.5,25.495097567963924\n6.55,25.592967784139454\n6.6,25.69046515733026\n6.65,25.787593916455258\n6.7,25.88435821108957\n6.75,25.98076211353316\n6.8,26.076809620810593\n6.85,26.1725046566048\n6.9,26.267851073127396\n6.95,26.362852652928133\n7,26.457513110645905\n7.05,26.551836094703507\n7.1,26.645825188948457\n7.15,26.739483914241873\n7.2,26.832815729997478\n7.25,26.92582403567252\n7.3,27.018512172212592\n7.35,27.11088342345192\n7.4,27.202941017470884\n7.45,27.294688127912362", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "C", + "scenarioId": "csv_content" + }, + { + "csvContent": "x4,-sqrt(x)\n0,0\n0.05,-2.23606797749979\n0.1,-3.1622776601683795\n0.15,-3.872983346207417\n0.2,-4.47213595499958\n0.25,-5\n0.3,-5.47722557505166\n0.35,-5.916079783099616\n0.4,-6.324555320336759\n0.45,-6.708203932499369\n0.5,-7.0710678118654755\n0.55,-7.416198487095663\n0.6,-7.745966692414834\n0.65,-8.062257748298551\n0.7,-8.366600265340756\n0.75,-8.660254037844386\n0.8,-8.94427190999916\n0.85,-9.219544457292887\n0.9,-9.486832980505138\n0.95,-9.746794344808963\n1,-10\n1.05,-10.2469507659596\n1.1,-10.488088481701517\n1.15,-10.723805294763608\n1.2,-10.95445115010332\n1.25,-11.180339887498949\n1.3,-11.401754250991381\n1.35,-11.618950038622252\n1.4,-11.832159566199232\n1.45,-12.041594578792296\n1.5,-12.24744871391589\n1.55,-12.449899597988733\n1.6,-12.649110640673518\n1.65,-12.84523257866513\n1.7,-13.038404810405297\n1.75,-13.228756555322953\n1.8,-13.416407864998739\n1.85,-13.601470508735442\n1.9,-13.784048752090222\n1.95,-13.96424004376894\n2,-14.142135623730951\n2.05,-14.317821063276352\n2.1,-14.49137674618944\n2.15,-14.66287829861518\n2.2,-14.832396974191326\n2.25,-15\n2.3,-15.1657508881031\n2.35,-15.329709716755893\n2.4,-15.491933384829668\n2.45,-15.652475842498529\n2.5,-15.811388300841898\n2.55,-15.968719422671311\n2.6,-16.124515496597102\n2.65,-16.278820596099706\n2.7,-16.431676725154986\n2.75,-16.583123951776997\n2.8,-16.73320053068151\n2.85,-16.881943016134134\n2.9,-17.0293863659264\n2.95,-17.175564037317667\n3,-17.32050807568877\n3.05,-17.46424919657298\n3.1,-17.60681686165901\n3.15,-17.74823934929885\n3.2,-17.88854381999832\n3.25,-18.027756377319946\n3.3,-18.16590212458495\n3.35,-18.303005217723125\n3.4,-18.439088914585774\n3.45,-18.57417562100671\n3.5,-18.708286933869708\n3.55,-18.84144368141677\n3.6,-18.973665961010276\n3.65,-19.1049731745428\n3.7,-19.235384061671347\n3.75,-19.364916731037084\n3.8,-19.493588689617926\n3.85,-19.621416870348586\n3.9,-19.748417658131498\n3.95,-19.87460691435179\n4,-20\n4.05,-20.124611797498105\n4.1,-20.248456731316583\n4.15,-20.37154878746336\n4.2,-20.4939015319192\n4.25,-20.615528128088304\n4.3,-20.73644135332772\n4.35,-20.85665361461421\n4.4,-20.976176963403034\n4.45,-21.095023109728984\n4.5,-21.213203435596423\n4.55,-21.330729007701542\n4.6,-21.447610589527216\n4.65,-21.563858652847827\n4.7,-21.6794833886788\n4.75,-21.79449471770337\n4.8,-21.90890230020664\n4.85,-22.022715545545243\n4.9,-22.135943621178654\n4.95,-22.24859546128699\n5,-22.360679774997898\n5.05,-22.47220505424423\n5.1,-22.58317958127243\n5.15,-22.693611435820436\n5.2,-22.803508501982762\n5.25,-22.9128784747792\n5.3,-23.021728866442675\n5.35,-23.130067012440755\n5.4,-23.237900077244504\n5.45,-23.345235059857504\n5.5,-23.45207879911715\n5.55,-23.55843797877949\n5.6,-23.664319132398465\n5.65,-23.769728648009426\n5.7,-23.874672772626646\n5.75,-23.979157616563597\n5.8,-24.08318915758459\n5.85,-24.186773244895647\n5.9,-24.289915602982237\n5.95,-24.392621835300936\n6,-24.49489742783178\n6.05,-24.596747752497684\n6.1,-24.698178070456937\n6.15,-24.79919353527449\n6.2,-24.899799195977465\n6.25,-25\n6.3,-25.099800796022265\n6.35,-25.199206336708304\n6.4,-25.298221281347036\n6.45,-25.39685019840059\n6.5,-25.495097567963924\n6.55,-25.592967784139454\n6.6,-25.69046515733026\n6.65,-25.787593916455258\n6.7,-25.88435821108957\n6.75,-25.98076211353316\n6.8,-26.076809620810593\n6.85,-26.1725046566048\n6.9,-26.267851073127396\n6.95,-26.362852652928133\n7,-26.457513110645905\n7.05,-26.551836094703507\n7.1,-26.645825188948457\n7.15,-26.739483914241873\n7.2,-26.832815729997478\n7.25,-26.92582403567252\n7.3,-27.018512172212592\n7.35,-27.11088342345192\n7.4,-27.202941017470884\n7.45,-27.294688127912362", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "D", + "scenarioId": "csv_content" + } + ], + "title": "Function Plots", + "type": "xychart" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 21, + "y": 0 + }, + "id": 10, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "---\n### XYChart\n\n- Multi-dimensional, non-timeseries data (scientific, financial, engineering)\n- Scatter plots, bubble charts, function graphs, and etch-a-sketch!\n", + "mode": "markdown" + }, + "pluginVersion": "10.3.0-pre", + "type": "text" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "fixedColor": "red", + "mode": "fixed" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 15, + "w": 9, + "x": 12, + "y": 17 + }, + "id": 5, + "options": { + "dims": { + "frame": 0 + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [ + { + "name": "Price", + "pointColor": { + "fixed": "#fade2a40" + }, + "pointSize": { + "field": "Price", + "fixed": 5, + "max": 50, + "min": 1 + }, + "x": "Lat", + "y": "Lng" + } + ], + "seriesMapping": "manual", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "csvFileName": "flight_info_by_state.csv", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_file" + } + ], + "title": "Bubble Charts", + "type": "xychart" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Miles_per_Gallon USA" + }, + "properties": [ + { + "id": "custom.axisLabel", + "value": "Miles_per_Gallon" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Horsepower USA" + }, + "properties": [ + { + "id": "custom.axisLabel", + "value": "Horsepower" + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 6, + "x": 0, + "y": 20 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [ + { + "name": "USA", + "pointColor": { + "fixed": "#f2495c80" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Horsepower USA", + "y": "Miles_per_Gallon USA" + }, + { + "name": "Europe", + "pointColor": { + "fixed": "#5795f280" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Horsepower Europe", + "y": "Miles_per_Gallon Europe" + }, + { + "name": "Japan", + "pointColor": { + "fixed": "#ff983080" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Horsepower Japan", + "y": "Miles_per_Gallon Japan" + } + ], + "seriesMapping": "manual", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "csvFileName": "automobiles.csv", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_file" + } + ], + "title": "MPG vs HP (by Country)", + "transformations": [ + { + "id": "partitionByValues", + "options": { + "fields": [ + "Origin" + ] + } + } + ], + "type": "xychart" + }, + { + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineWidth": 1, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Miles_per_Gallon USA" + }, + "properties": [ + { + "id": "custom.axisLabel", + "value": "Miles_per_Gallon" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Acceleration USA" + }, + "properties": [ + { + "id": "custom.axisLabel", + "value": "Acceleration" + } + ] + } + ] + }, + "gridPos": { + "h": 12, + "w": 6, + "x": 6, + "y": 20 + }, + "id": 8, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [ + { + "name": "USA", + "pointColor": { + "fixed": "#f2495c80" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Acceleration USA", + "y": "Miles_per_Gallon USA" + }, + { + "name": "Europe", + "pointColor": { + "fixed": "#5795f280" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Acceleration Europe", + "y": "Miles_per_Gallon Europe" + }, + { + "name": "Japan", + "pointColor": { + "fixed": "#ff983080" + }, + "pointSize": { + "fixed": 5, + "max": 20, + "min": 1 + }, + "x": "Acceleration Japan", + "y": "Miles_per_Gallon Japan" + } + ], + "seriesMapping": "manual", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "csvFileName": "automobiles.csv", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_file" + } + ], + "title": "MPG vs Acceleration (by Country)", + "transformations": [ + { + "id": "partitionByValues", + "options": { + "fields": [ + "Origin" + ] + } + } + ], + "type": "xychart" + }, + { + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 12, + "x": 0, + "y": 32 + }, + "id": 11, + "options": { + "dims": { + "exclude": [ + "co TLM0100" + ], + "x": "humidity TLM0100" + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [ + { + "pointColor": {}, + "x": "humidity", + "y": "temperature" + } + ], + "seriesMapping": "manual", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "grafana", + "uid": "grafana" + }, + "queryType": "snapshot", + "refId": "A", + "snapshot": [ + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.4860747509084685, + 0.4790778553981873, + 0.4597786615711249, + 0.4478751241705323, + 0.44020548182152397, + 0.4569020188814074, + 0.4655250429581913, + 0.4819032762634117, + 0.491365303224968, + 0.5092239049148886 + ], + [ + 35.084960222673146, + 35.089101898649055, + 35.130020139289115, + 35.10251705413486, + 35.08184755996438, + 35.04582600108574, + 35.09077388700681, + 35.04096375315356, + 35.05647864027338, + 35.091800720894916 + ], + [ + 71.2187151336704, + 71.24617135003214, + 71.21726829714834, + 71.26528218716341, + 71.26084702358875, + 71.24054378677393, + 71.27884802991244, + 71.29783163616926, + 71.33230999794793, + 71.34975514559837 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0100" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0100" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0100" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "meta": { + "executedQueryString": "import \"influxdata/influxdb/sample\"\nimport \"influxdata/influxdb/schema\"\n\nsample.data(set: \"airSensor\")\n |> limit(n: 10)\n |> group(columns: [\"sensor_id\"])\n |> schema.fieldsAsCols()\n", + "typeVersion": [ + 0, + 0 + ] + }, + "refId": "A" + } + }, + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.4964171323208575, + 0.48257922637952133, + 0.46567087322576145, + 0.4467650568596856, + 0.4417772514767169, + 0.4341379534638706, + 0.439345038257859, + 0.43452737707188627, + 0.42417500678639164, + 0.40704613738954887 + ], + [ + 34.92662088456207, + 34.91464944732493, + 34.95985887959429, + 34.929238294894844, + 34.954103486412336, + 34.98895514808448, + 35.03476240219413, + 35.028863365125844, + 35.03717014192905, + 35.00775919996651 + ], + [ + 71.83521495327129, + 71.83370684393908, + 71.83712160725877, + 71.88299650060345, + 71.90526594972503, + 71.8631768515712, + 71.85577028152356, + 71.89245169322045, + 71.93606971457449, + 71.96164771829956 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0101" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0101" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0101" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "refId": "A" + } + }, + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.4870365157212326, + 0.5032215395360725, + 0.5035259485542879, + 0.4841798164121083, + 0.483812619615984, + 0.4882993499867786, + 0.4719009580435705, + 0.4700689455810135, + 0.48112413053169706, + 0.4691106107162724 + ], + [ + 34.86359615237462, + 34.84629630959152, + 34.81771460191974, + 34.854640808896036, + 34.86699022367547, + 34.864319179513096, + 34.86915527122888, + 34.89889649251399, + 34.86576388906259, + 34.88622805723735 + ], + [ + 72.03972207916735, + 72.05566134520713, + 72.08473708469143, + 72.07306942754916, + 72.0427409958616, + 72.04536459775873, + 72.09400368933838, + 72.14293243585941, + 72.18840859469728, + 72.15524663568557 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0102" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0102" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0102" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "refId": "A" + } + }, + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.3979338437168368, + 0.4117117830425588, + 0.4000376537804249, + 0.40114553332960723, + 0.3909759394807085, + 0.38213452854680874, + 0.37339826793170855, + 0.3624713623472977, + 0.35640734768856297, + 0.35690557816119645 + ], + [ + 35.16192242281515, + 35.19891757080395, + 35.23754373785834, + 35.25270355198698, + 35.29525947947623, + 35.272026086051184, + 35.275233467451635, + 35.23834593104291, + 35.25233833634368, + 35.22053598631417 + ], + [ + 71.29169927438586, + 71.32114142326272, + 71.33632903748085, + 71.3064635464553, + 71.26436580075855, + 71.30431517798449, + 71.28861822950174, + 71.26778760430453, + 71.23481860950403, + 71.23084180913762 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0103" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0103" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0103" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "refId": "A" + } + }, + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.5129015632374951, + 0.552968955740271, + 0.5690444135565038, + 0.6050221760178951, + 0.5943904374498042, + 0.6153588301241533, + 0.6164375823908576, + 0.6059635952981327, + 0.6470283318343141, + 0.6861075098169984 + ], + [ + 35.75385592664215, + 35.753218714107504, + 35.72547059379115, + 35.74553237372676, + 35.73378268235891, + 35.747560005048086, + 35.769867599816735, + 35.73929899563808, + 35.705317880681875, + 35.65611547721327 + ], + [ + 73.64806558624832, + 73.65728412124716, + 73.68805520135102, + 73.65185281162863, + 73.63499402146681, + 73.68359308763364, + 73.64682180062367, + 73.63298265031713, + 73.59096788790947, + 73.6381949597034 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0200" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0200" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0200" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "refId": "A" + } + }, + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.5082489903097206, + 0.525490999229553, + 0.5300688563597754, + 0.5351282770519872, + 0.533437724470923, + 0.5164188260958164, + 0.5134188770545406, + 0.4949993424337248, + 0.4960387472164697, + 0.5046934441184395 + ], + [ + 35.24972613768055, + 35.238916979727335, + 35.28758958750148, + 35.26413172906637, + 35.2875488141577, + 35.32420268624064, + 35.2932945023372, + 35.277959228995584, + 35.27901195680498, + 35.27056468599647 + ], + [ + 73.99618150289902, + 74.01973867729899, + 73.97488048626532, + 73.97027021897547, + 73.96055098802299, + 73.94544160099603, + 73.91010608315078, + 73.9594600253564, + 73.93323000030807, + 73.94265737589377 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0201" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0201" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0201" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "refId": "A" + } + }, + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.4843506884938821, + 0.48132272563110234, + 0.4738268718199932, + 0.4929629619836042, + 0.4730642763470896, + 0.4654986284178103, + 0.47939137148137106, + 0.4729232244284411, + 0.48941836624955776, + 0.49438537058971027 + ], + [ + 35.6843507637763, + 35.67052290561625, + 35.651191124511904, + 35.682694567957775, + 35.71754463951193, + 35.73271359197846, + 35.76201128140823, + 35.72031962293351, + 35.76508898680512, + 35.77376488207177 + ], + [ + 75.28536533620796, + 75.3203884403274, + 75.32915092826639, + 75.3260291876276, + 75.29613126188146, + 75.31098782530198, + 75.27434784939884, + 75.30929861509146, + 75.32818662869892, + 75.33650169518009 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0202" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0202" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0202" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "refId": "A" + } + }, + { + "data": { + "values": [ + [ + 1686898151000, + 1686898161000, + 1686898171000, + 1686898181000, + 1686898191000, + 1686898201000, + 1686898211000, + 1686898221000, + 1686898231000, + 1686898241000 + ], + [ + 0.39373421338928505, + 0.40929905142175416, + 0.39727569840202215, + 0.415834035946844, + 0.413865826090914, + 0.4271278288285897, + 0.435277474574255, + 0.4480042029285831, + 0.462641109361364, + 0.4566678920783633 + ], + [ + 35.86322585633077, + 35.88732568460068, + 35.87553827435961, + 35.84063967239316, + 35.813642046057005, + 35.8569165461967, + 35.80924651587166, + 35.80599199551315, + 35.75906423980926, + 35.79948361256034 + ], + [ + 74.78112365229704, + 74.73821283157658, + 74.73019922701285, + 74.73280967321202, + 74.74885460260536, + 74.70880911705714, + 74.73346687605624, + 74.77682413662681, + 74.80562351134131, + 74.82881664528719 + ] + ] + }, + "schema": { + "fields": [ + { + "config": {}, + "name": "_time", + "type": "time", + "typeInfo": { + "frame": "time.Time", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0203" + }, + "name": "co", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0203" + }, + "name": "humidity", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + }, + { + "config": {}, + "labels": { + "sensor_id": "TLM0203" + }, + "name": "temperature", + "type": "number", + "typeInfo": { + "frame": "float64", + "nullable": true + } + } + ], + "refId": "A" + } + } + ] + } + ], + "title": "Multi-series Temperature vs Humidity", + "type": "xychart" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [ + "gdev", + "panel-tests", + "xychat" + ], + "templating": { + "list": [] + }, + "time": { + "from": "2022-10-07T05:04:04.516Z", + "to": "2022-10-07T17:04:04.516Z" + }, + "timepicker": {}, + "timezone": "", + "title": "Panel Tests - XY Chart", + "uid": "YObbMr44k", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/devenv/dev-dashboards/transforms/regression-analysis.json b/devenv/dev-dashboards/transforms/regression-analysis.json new file mode 100644 index 0000000000000..03e9a376cad9f --- /dev/null +++ b/devenv/dev-dashboards/transforms/regression-analysis.json @@ -0,0 +1,1036 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": false, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 764, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "random_walk" + } + ], + "title": "Many points polynomial", + "transformations": [ + { + "id": "regression", + "options": { + "degree": 3, + "modelType": "polynomial", + "order": 3, + "precision": 100, + "resolution": 100, + "xFieldName": "time", + "yFieldName": "A-series" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 0 + }, + "id": 5, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "random_walk" + } + ], + "title": "Many points linear", + "transformations": [ + { + "id": "regression", + "options": { + "modelType": "linear", + "order": 3, + "precision": 100, + "resolution": 10, + "xFieldName": "time", + "yFieldName": "A-series" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 2, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.0-pre", + "targets": [ + { + "csvContent": "time, val\n2023-11-20 12:09:00, 1\n2023-11-20 12:09:02, 2\n2023-11-20 12:09:03, 3\n2023-11-20 12:09:04, 4\n2023-11-20 12:09:05, 5\n2023-11-20 12:09:06, 6\n2023-11-20 12:09:07, 2\n2023-11-20 12:09:08, 3\n2023-11-20 12:09:09, 4\n2023-11-20 12:09:10, 1\n2023-11-20 12:09:11, 2\n2023-11-20 12:09:12, 3\n2023-11-20 12:09:13, 4", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "Few points", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "time" + } + ], + "fields": {} + } + }, + { + "id": "regression", + "options": { + "degree": 3, + "modelType": "polynomial", + "order": 3, + "precision": 100, + "xFieldName": "time", + "yFieldName": "val" + } + }, + { + "id": "regression", + "options": { + "modelType": "linear", + "xFieldName": "time", + "yFieldName": "val" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 4, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "csvContent": "time, val\n2023-11-20 12:09:00, 1\n2023-11-20 12:09:02, 2\n2023-11-20 12:09:03, 3\n2023-11-20 12:09:04, 4\n2023-11-20 12:09:05, null\n2023-11-20 12:09:06, 6\n2023-11-20 12:09:07, 2\n2023-11-20 12:09:08, null\n2023-11-20 12:09:09, 4\n2023-11-20 12:09:10, 1\n2023-11-20 12:09:11, 2\n2023-11-20 12:09:12, 3\n2023-11-20 12:09:13, 4", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "Data with nulls", + "transformations": [ + { + "id": "convertFieldType", + "options": { + "conversions": [ + { + "destinationType": "time", + "targetField": "time" + } + ], + "fields": {} + } + }, + { + "id": "regression", + "options": { + "degree": 3, + "modelType": "polynomial", + "order": 3, + "precision": 100, + "resolution": 100, + "xFieldName": "time", + "yFieldName": "val" + } + }, + { + "id": "regression", + "options": { + "modelType": "linear", + "xFieldName": "time", + "yFieldName": "val" + } + } + ], + "type": "timeseries" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "y predicted linear regression" + }, + "properties": [ + { + "id": "custom.show", + "value": "lines" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "y predicted polynomial regression" + }, + "properties": [ + { + "id": "custom.show", + "value": "lines" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 16 + }, + "id": 3, + "options": { + "dims": { + "frame": 0 + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [], + "seriesMapping": "auto", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "targets": [ + { + "csvContent": "x,y\n1,4\n2,1\n3,2\n4,-2\n5,6\n3,2\n1,7\n3,9\n6,3\n5,-3\n2,-2\n7,15", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "XY Chart", + "transformations": [ + { + "id": "regression", + "options": { + "modelType": "linear", + "resolution": 1, + "xFieldName": "x", + "yFieldName": "y" + } + }, + { + "id": "regression", + "options": { + "modelType": "polynomial", + "order": 3, + "resolution": 100, + "xFieldName": "x", + "yFieldName": "y" + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "x.*", + "renamePattern": "x" + } + }, + { + "id": "joinByField", + "options": { + "byField": "x", + "mode": "outer" + } + }, + { + "id": "sortBy", + "options": { + "fields": {}, + "sort": [ + { + "field": "x" + } + ] + } + } + ], + "type": "xychart" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 16 + }, + "id": 6, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.0-pre", + "title": "stat panel", + "transformations": [ + { + "id": "regression", + "options": { + "degree": 3, + "modelType": "polynomial", + "order": 3, + "xFieldName": "time", + "yFieldName": "A-series" + } + }, + { + "id": "regression", + "options": { + "modelType": "linear", + "xFieldName": "time", + "yFieldName": "A-series" + } + } + ], + "type": "stat" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "val predicted polynomial regression" + }, + "properties": [ + { + "id": "custom.showPoints", + "value": "never" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "val predicted linear regression" + }, + "properties": [ + { + "id": "custom.showPoints", + "value": "never" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 24 + }, + "id": 7, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.0-pre", + "targets": [ + { + "csvContent": "x, val\n6,2\n8,1\n10,5\n15,1\n22,10\n", + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + } + ], + "title": "Trend panel", + "transformations": [ + { + "id": "regression", + "options": { + "modelType": "polynomial", + "order": 3, + "xFieldName": "x", + "yFieldName": "val" + } + }, + { + "id": "regression", + "options": { + "modelType": "linear", + "xFieldName": "x", + "yFieldName": "val" + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "x.*", + "renamePattern": "x" + } + }, + { + "id": "joinByField", + "options": { + "byField": "x", + "mode": "outer" + } + } + ], + "type": "trend" + }, + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "pointSize": { + "fixed": 5 + }, + "scaleDistribution": { + "type": "linear" + }, + "show": "points" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "baz predicted polynomial regression" + }, + "properties": [ + { + "id": "custom.show", + "value": "lines" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "baz predicted linear regression" + }, + "properties": [ + { + "id": "custom.show", + "value": "lines" + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 24 + }, + "id": 8, + "options": { + "dims": { + "exclude": [], + "frame": 0, + "x": "foo" + }, + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "series": [ + { + "pointColor": {}, + "pointSize": { + "field": "baz", + "fixed": 50.5, + "max": 100, + "min": 1 + }, + "x": "foo", + "y": "foo" + } + ], + "seriesMapping": "auto", + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "10.3.0-pre", + "targets": [ + { + "datasource": { + "type": "grafana-testdata-datasource", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "usa", + "usa": { + "mode": "values-as-rows" + } + } + ], + "title": "XY Chart", + "transformations": [ + { + "id": "regression", + "options": { + "degree": 5, + "modelType": "polynomial", + "order": 3, + "xFieldName": "foo", + "yFieldName": "baz" + } + }, + { + "id": "regression", + "options": { + "modelType": "linear", + "xFieldName": "foo", + "yFieldName": "baz" + } + }, + { + "id": "joinByField", + "options": { + "byField": "foo", + "mode": "outer" + } + } + ], + "type": "xychart" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [ + "gdev", + "transform" + ], + "templating": { + "list": [] + }, + "time": { + "from": "2023-11-20T12:09:00.000Z", + "to": "2023-11-20T12:09:13.000Z" + }, + "timepicker": {}, + "timezone": "", + "title": "Transforms - Regression analysis", + "uid": "d2d2bb99-42e4-44b8-b93e-3ad1aae31c6b", + "version": 39, + "weekStart": "" +} \ No newline at end of file diff --git a/devenv/docker/blocks/auth/authentik/README.md b/devenv/docker/blocks/auth/authentik/README.md index 9fdee3b8c9376..7c02d38bb8d5f 100644 --- a/devenv/docker/blocks/auth/authentik/README.md +++ b/devenv/docker/blocks/auth/authentik/README.md @@ -85,8 +85,6 @@ auth_url = http://localhost:9000/application/o/authorize/ token_url = http://localhost:9000/application/o/token/ api_url = http://localhost:9000/application/o/userinfo/ role_attribute_path = contains(groups[*], 'admin') && 'Admin' || contains(groups[*], 'editor') && 'Editor' || 'Viewer' - -[auth] signout_redirect_url = http://localhost:9000/application/o/grafana-oidc/end-session/ ``` diff --git a/devenv/docker/blocks/auth/authentik/docker-compose.yaml b/devenv/docker/blocks/auth/authentik/docker-compose.yaml index 6d16b4e7a36be..997652afd9325 100644 --- a/devenv/docker/blocks/auth/authentik/docker-compose.yaml +++ b/devenv/docker/blocks/auth/authentik/docker-compose.yaml @@ -1,5 +1,5 @@ authentikdb: - image: docker.io/library/postgres:12-alpine + image: docker.io/library/postgres:16-alpine restart: unless-stopped container_name: authentikdb environment: @@ -39,7 +39,7 @@ - "authentik:authentik" authentik: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.1} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.4} restart: unless-stopped container_name: authentik command: server @@ -66,7 +66,7 @@ - "authentikredis:authentikredis" authentik-worker: - image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.5.1} + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.10.4} restart: unless-stopped container_name: authentik-worker command: worker diff --git a/devenv/docker/blocks/auth/jwt_proxy/docker-compose.yaml b/devenv/docker/blocks/auth/jwt_proxy/docker-compose.yaml index cc18a38126c8e..618a096cd1c09 100644 --- a/devenv/docker/blocks/auth/jwt_proxy/docker-compose.yaml +++ b/devenv/docker/blocks/auth/jwt_proxy/docker-compose.yaml @@ -1,5 +1,5 @@ oauthkeycloakdb: - image: docker.io/library/postgres:12-alpine + image: docker.io/library/postgres:16-alpine container_name: oauthkeycloakdb environment: POSTGRES_DB: keycloak @@ -10,7 +10,7 @@ restart: unless-stopped oauthkeycloak: - image: quay.io/keycloak/keycloak:21.1 + image: quay.io/keycloak/keycloak:23.0 container_name: oauthkeycloak command: start-dev environment: diff --git a/devenv/docker/blocks/auth/oauth/docker-compose.yaml b/devenv/docker/blocks/auth/oauth/docker-compose.yaml index 4efaa56d11463..ba88c5d9e8f02 100644 --- a/devenv/docker/blocks/auth/oauth/docker-compose.yaml +++ b/devenv/docker/blocks/auth/oauth/docker-compose.yaml @@ -1,5 +1,5 @@ oauthkeycloakdb: - image: docker.io/library/postgres:12-alpine + image: docker.io/library/postgres:16-alpine container_name: oauthkeycloakdb environment: POSTGRES_DB: keycloak @@ -10,7 +10,7 @@ restart: unless-stopped oauthkeycloak: - image: quay.io/keycloak/keycloak:22.0 + image: quay.io/keycloak/keycloak:23.0 container_name: oauthkeycloak command: start-dev environment: diff --git a/devenv/docker/blocks/auth/oauth/readme.md b/devenv/docker/blocks/auth/oauth/readme.md index be52927393797..cd59c21a846ca 100644 --- a/devenv/docker/blocks/auth/oauth/readme.md +++ b/devenv/docker/blocks/auth/oauth/readme.md @@ -10,9 +10,6 @@ make devenv sources="auth/oauth" Here is the conf you need to add to your configuration file (conf/custom.ini): ```ini -[auth] -signout_redirect_url = http://localhost:8087/realms/grafana/protocol/openid-connect/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Flogin - [auth.generic_oauth] enabled = true name = Keycloak-OAuth @@ -28,6 +25,7 @@ auth_url = http://localhost:8087/realms/grafana/protocol/openid-connect/auth token_url = http://localhost:8087/realms/grafana/protocol/openid-connect/token role_attribute_path = contains(roles[*], 'grafanaadmin') && 'GrafanaAdmin' || contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer' allow_assign_grafana_admin = true +signout_redirect_url = http://localhost:8087/realms/grafana/protocol/openid-connect/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Flogin ``` ## Devenv setup jwt auth diff --git a/devenv/docker/blocks/elastic/data/data.js b/devenv/docker/blocks/elastic/data/data.js index 908cc4ee044b9..eb3b8c3d6241d 100644 --- a/devenv/docker/blocks/elastic/data/data.js +++ b/devenv/docker/blocks/elastic/data/data.js @@ -149,7 +149,8 @@ function getRandomLogItem(counter, timestamp) { hostname: chooseRandomElement(['hostname1', 'hostname2', 'hostname3', 'hostname4', 'hostname5', 'hostname6']), value: counter, metric: chooseRandomElement(['cpu', 'memory', 'latency']), - description: "this is description" + description: "this is description", + slash: "Access to the path '\\\\tkasnpo\\KASNPO\\Files\\contacts.xml' is denied." }; } diff --git a/devenv/docker/blocks/loki/data/data.js b/devenv/docker/blocks/loki/data/data.js index f420e216f1a14..453d69a1f84dd 100644 --- a/devenv/docker/blocks/loki/data/data.js +++ b/devenv/docker/blocks/loki/data/data.js @@ -47,12 +47,12 @@ async function sleep(duration) { }); } -async function lokiSendLogLine(timestampNs, line, tags, nonIndexed = {}) { +async function lokiSendLogLine(timestampNs, line, tags, structuredMetadata = {}) { const data = { streams: [ { stream: tags, - values: [[timestampNs, line, nonIndexed]], + values: [[timestampNs, line, structuredMetadata]], }, ], }; @@ -68,6 +68,18 @@ function getSineValue(counter, loopLength) { return Math.sin((Math.PI * 2 * counter) / loopLength); } +function fakeTraceId() { + let traceId = ''; + const chars = 'abcdef0123456789'; + const idLength = 12; + let i = 0; + while (i < idLength) { + traceId += chars.charAt(Math.floor(Math.random() * chars.length)); + i += 1; + } + return traceId; +} + function getRandomLogItem(counter) { const randomText = `${Math.trunc(Math.random() * 1000 * 1000 * 1000)}`; const maybeAnsiText = Math.random() < 0.5 ? 'with ANSI \u001b[31mpart of the text\u001b[0m' : ''; @@ -176,8 +188,8 @@ async function sendOldLogs() { const timestampNs = `${timestampMs}${getRandomNanosecPart()}`; globalCounter += 1; const item = getRandomLogItem(globalCounter) - await lokiSendLogLine(timestampNs, JSON.stringify(item), {age:'old', place:'moon', ...sharedLabels}); - await lokiSendLogLine(timestampNs, logFmtLine(item), {age:'old', place:'luna', ...sharedLabels}); + await lokiSendLogLine(timestampNs, JSON.stringify(item), {age:'old', place:'moon', ...sharedLabels}, {structuredMetadataKey: 'value', traceId: fakeTraceId()}); + await lokiSendLogLine(timestampNs, logFmtLine(item), {age:'old', place:'luna', ...sharedLabels}, {structuredMetadataKey: 'value', traceId: fakeTraceId()}); }; } @@ -187,8 +199,8 @@ async function sendNewLogs() { const nowMs = new Date().getTime(); const timestampNs = `${nowMs}${getRandomNanosecPart()}`; const item = getRandomLogItem(globalCounter) - await lokiSendLogLine(timestampNs, JSON.stringify(item), {age:'new', place:'moon', ...sharedLabels}, {nonIndexed: 'value'}); - await lokiSendLogLine(timestampNs, logFmtLine(item), {age:'new', place:'luna', ...sharedLabels}, {nonIndexed: 'value'}); + await lokiSendLogLine(timestampNs, JSON.stringify(item), {age:'new', place:'moon', ...sharedLabels}, {structuredMetadataKey: 'value', traceId: fakeTraceId()}); + await lokiSendLogLine(timestampNs, logFmtLine(item), {age:'new', place:'luna', ...sharedLabels}, {structuredMetadataKey: 'value', traceId: fakeTraceId()}); const sleepDuration = 200 + Math.random() * 800; // between 0.2 and 1 seconds await sleep(sleepDuration); } diff --git a/devenv/docker/blocks/mimir_backend/nginx/nginx.conf.template b/devenv/docker/blocks/mimir_backend/nginx/nginx.conf.template index ba1125456439b..7ce374a378e27 100644 --- a/devenv/docker/blocks/mimir_backend/nginx/nginx.conf.template +++ b/devenv/docker/blocks/mimir_backend/nginx/nginx.conf.template @@ -5,9 +5,15 @@ events {} http { resolver 127.0.0.11 ipv6=off; + # Use basic auth user in `X-Scope-OrgID` if the header is not already set. + map $http_x_scope_orgid $add_x_scope_orgid { + default $http_x_scope_orgid; + "" $remote_user; + } + server { listen 8080; - proxy_set_header X-Scope-OrgID $http_x_scope_orgid; + proxy_set_header X-Scope-OrgID $add_x_scope_orgid; location / { auth_basic "Mimir Backend"; diff --git a/devenv/docker/blocks/tempo/tempo.yaml b/devenv/docker/blocks/tempo/tempo.yaml index 6e94ff11a8d6b..e8378e9b9a68c 100644 --- a/devenv/docker/blocks/tempo/tempo.yaml +++ b/devenv/docker/blocks/tempo/tempo.yaml @@ -52,3 +52,5 @@ storage: overrides: metrics_generator_processors: [local-blocks, service-graphs, span-metrics] + +stream_over_http_enabled: true diff --git a/devenv/jsonnet/dev-dashboards.libsonnet b/devenv/jsonnet/dev-dashboards.libsonnet index 959a28a7dadb9..1ef01464d10f9 100644 --- a/devenv/jsonnet/dev-dashboards.libsonnet +++ b/devenv/jsonnet/dev-dashboards.libsonnet @@ -149,6 +149,13 @@ local dashboard = grafana.dashboard; id: 0, } }, + dashboard.new('dashlist', import '../dev-dashboards/panel-dashlist/dashlist.json') + + resource.addMetadata('folder', 'dev-dashboards') + + { + spec+: { + id: 0, + } + }, dashboard.new('datadata-macros', import '../dev-dashboards/feature-templating/datadata-macros.json') + resource.addMetadata('folder', 'dev-dashboards') + { @@ -534,6 +541,13 @@ local dashboard = grafana.dashboard; id: 0, } }, + dashboard.new('regression-analysis', import '../dev-dashboards/transforms/regression-analysis.json') + + resource.addMetadata('folder', 'dev-dashboards') + + { + spec+: { + id: 0, + } + }, dashboard.new('relative_time_zone_support', import '../dev-dashboards/scenarios/relative_time_zone_support.json') + resource.addMetadata('folder', 'dev-dashboards') + { @@ -828,5 +842,12 @@ local dashboard = grafana.dashboard; id: 0, } }, + dashboard.new('xychart-example', import '../dev-dashboards/panel-xychart/xychart-example.json') + + resource.addMetadata('folder', 'dev-dashboards') + + { + spec+: { + id: 0, + } + }, ], } \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile index e1c0e26cb3a0c..38997200b0de9 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -10,7 +10,6 @@ include docs.mk .PHONY: sources/panels-visualizations/query-transform-data/transform-data/index.md sources/panels-visualizations/query-transform-data/transform-data/index.md: ## Generate the Transform Data page source. sources/panels-visualizations/query-transform-data/transform-data/index.md: - cd $(CURDIR)/.. - npx tsc ./scripts/docs/generate-transformations.ts - node ./scripts/docs/generate-transformations.js > $(CURDIR)/$@ + cd $(CURDIR)/.. && npx tsc ./scripts/docs/generate-transformations.ts && \ + node ./scripts/docs/generate-transformations.js > $(CURDIR)/$@ && \ npx prettier -w $(CURDIR)/$@ diff --git a/docs/docs.mk b/docs/docs.mk index c4ba766fb4f09..a08830d907c1b 100644 --- a/docs/docs.mk +++ b/docs/docs.mk @@ -34,11 +34,6 @@ endif # First project is considered the primary one used for doc-validator. PRIMARY_PROJECT := $(subst /,-,$(firstword $(subst :, ,$(firstword $(PROJECTS))))) -# Name for the container. -ifeq ($(origin DOCS_CONTAINER), undefined) -export DOCS_CONTAINER := $(PRIMARY_PROJECT)-docs -endif - # Host port to publish container port to. ifeq ($(origin DOCS_HOST_PORT), undefined) export DOCS_HOST_PORT := 3002 diff --git a/docs/logo-horizontal-dark.png b/docs/logo-horizontal-dark.png new file mode 100644 index 0000000000000..0ab465dd77e65 Binary files /dev/null and b/docs/logo-horizontal-dark.png differ diff --git a/docs/make-docs b/docs/make-docs index 94683de344c87..25176a37f0519 100755 --- a/docs/make-docs +++ b/docs/make-docs @@ -5,107 +5,154 @@ # Updates should conform to the guidelines in https://keepachangelog.com/en/1.1.0/. # [Semantic versioning](https://semver.org/) is used to help the reader identify the significance of changes. # Changes are relevant to this script and the support docs.mk GNU Make interface. +# +# ## 5.1.2 (2023-11-08) +# +# ### Added +# +# - Hide manual_mount warning messages from non-debug output. +# Set the DEBUG environment variable to see all hidden messages. +# +# ## 5.1.1 (2023-10-30) +# +# ### Added +# +# - Support for Datadog and Oracle data source plugins repositories. +# +# ## 5.1.0 (2023-10-20) +# +# ### Added +# +# - Support for the plugins monorepo. +# +# ## 5.0.0 (2023-10-18) +# +# ### Added +# +# - Improved support for website repository. +# +# Mount more content and provide some feedback to users that the build can take time. +# +# - Ability to enter the `grafana/docs-base` container with a shell using the `ENTER` environment variable. +# +# ### Fixed +# +# - Correct key combination for interrupting the process. +# +# Keyboards use capital letters so this more accurately reflects the exact key combination users are expected to press. +# +# ### Removed +# +# - Imperfect implementation of container name. +# +# Facilitates running `make vale` and `make docs` at once. +# Container names are convenient for recognition in `docker ps` but the current implementation has more downsides than upsides. +# +# - Forced platform specification now that multiple architecture images exist. +# +# Significantly speeds up build times on larger repositories. +# # ## 4.2.2 (2023-10-05) # - Added support for Jira data source and MongoDB data source plugins repositories. - +# # ## 4.2.1 (2023-09-13) # ## Fixed - +# # - Improved consistency of the webserver request loop by polling the Hugo port rather than the proxy port. - +# # ## 4.2.0 (2023-09-01) - +# # ### Added - +# # - Retry the initial webserver request up to ten times to allow for the process to start. # If it is still failing after ten seconds, an error message is logged. - +# # ## 4.1.1 (2023-07-20) - +# # ### Fixed - +# # - Replaced use of `realpath` with POSIX compatible alternative to determine default value for REPOS_PATH. - +# # ## 4.1.0 (2023-06-16) - +# # ### Added - +# # - Mounts of `layouts` and `config` directories for the `website` project. # Ensures that local changes to mounts or shortcodes are reflected in the development server. - +# # ### Fixed - +# # - Version inference for versioned docs pages. # Pages in versioned projects now have the `versioned: true` front matter set to ensure that "version" in $.Page.Scratch is set on builds. - +# # ## 4.0.0 (2023-06-06) - +# # ### Removed - +# # - `doc-validator/%` target. # The behavior of the target was not as described. # Instead, to limit `doc-validator` to only specific files, refer to https://grafana.com/docs/writers-toolkit/writing-guide/tooling-and-workflows/validate-technical-documentation/#run-on-specific-files. - +# # ## 3.0.0 (2023-05-18) - +# # ### Fixed - +# # - Compatibility with the updated Make targets in the `website` repository. # `docs` now runs this script itself, `server-docs` builds the site with the `docs` Hugo environment. - +# # ## 2.0.0 (2023-05-18) - +# # ### Added - +# # - Support for the grafana-cloud/frontend-observability/faro-web-sdk project. # - Use of `doc-validator` v2.0.x which includes breaking changes to command line options. - +# # ### Fixed - +# # - Source grafana-cloud project from website repository. - +# # ### Added - +# # - Support for running the Vale linter with `make vale`. - +# # ## 1.2.1 (2023-05-05) - +# # ### Fixed - +# # - Use `latest` tag of `grafana/vale` image by default instead of hardcoded older version. # - Fix mounting multiple projects broken by the changes in 1.0.1 - +# # ## 1.2.0 (2023-05-05) - +# # ### Added - +# # - Support for running the Vale linter with `make vale`. - +# # ### Fixed - +# # ## 1.1.0 (2023-05-05) - +# # ### Added - +# # - Rewrite error output so it can be followed by text editors. - +# # ### Fixed - +# # - Fix `docs-debug` container process port. - +# # ## 1.0.1 (2023-05-04) - +# # ### Fixed - +# # - Ensure complete section hierarchy so that all projects have a visible menu. - +# # ## 1.0.0 (2023-05-04) - +# # ### Added - +# # - Build multiple projects simultaneously if all projects are checked out locally. # - Run [`doc-validator`](https://github.com/grafana/technical-documentation/tree/main/tools/cmd/doc-validator) over projects. # - Redirect project root to mounted version. @@ -135,7 +182,6 @@ set -ef -readonly DOCS_CONTAINER="${DOCS_CONTAINER:-make-docs}" readonly DOCS_HOST_PORT="${DOCS_HOST_PORT:-3002}" readonly DOCS_IMAGE="${DOCS_IMAGE:-grafana/docs-base:latest}" @@ -217,8 +263,10 @@ SOURCES_grafana_cloud_frontend_observability_faro_web_sdk='faro-web-sdk' SOURCES_helm_charts_mimir_distributed='mimir' SOURCES_helm_charts_tempo_distributed='tempo' SOURCES_opentelemetry='opentelemetry-docs' +SOURCES_plugins_grafana_datadog_datasource='datadog-datasource' SOURCES_plugins_grafana_jira_datasource='jira-datasource' SOURCES_plugins_grafana_mongodb_datasource='mongodb-datasource' +SOURCES_plugins_grafana_oracle_datasource='oracle-datasource' SOURCES_plugins_grafana_splunk_datasource='splunk-datasource' VERSIONS_as_code='UNVERSIONED' @@ -229,6 +277,11 @@ VERSIONS_grafana_cloud_k6='UNVERSIONED' VERSIONS_grafana_cloud_data_configuration_integrations='UNVERSIONED' VERSIONS_grafana_cloud_frontend_observability_faro_web_sdk='UNVERSIONED' VERSIONS_opentelemetry='UNVERSIONED' +VERSIONS_plugins_grafana_datadog_datasource='latest' +VERSIONS_plugins_grafana_jira_datasource='latest' +VERSIONS_plugins_grafana_mongodb_datasource='latest' +VERSIONS_plugins_grafana_oracle_datasource='latest' +VERSIONS_plugins_grafana_splunk_datasource='latest' VERSIONS_technical_documentation='UNVERSIONED' VERSIONS_website='UNVERSIONED' VERSIONS_writers_toolkit='UNVERSIONED' @@ -237,8 +290,13 @@ PATHS_grafana_cloud='content/docs/grafana-cloud' PATHS_helm_charts_mimir_distributed='docs/sources/helm-charts/mimir-distributed' PATHS_helm_charts_tempo_distributed='docs/sources/helm-charts/tempo-distributed' PATHS_mimir='docs/sources/mimir' +PATHS_plugins_grafana_datadog_datasource='docs/sources' +PATHS_plugins_grafana_jira_datasource='docs/sources' +PATHS_plugins_grafana_mongodb_datasource='docs/sources' +PATHS_plugins_grafana_oracle_datasource='docs/sources' +PATHS_plugins_grafana_splunk_datasource='docs/sources' PATHS_tempo='docs/sources/tempo' -PATHS_website='content/docs' +PATHS_website='content' # identifier STR # Replace characters that are not valid in an identifier with underscores. @@ -253,6 +311,77 @@ aget() { eval echo '$'"$(identifier "$1")_$(identifier "$2")" } +# src returns the project source repository name for a project. +src() { + _project="$1" + + case "${_project}" in + plugins/*) + if [ -z "$(aget SOURCES "${_project}")" ]; then + echo plugins-private + else + aget SOURCES "${_project}" + fi + ;; + *) + if [ -z "$(aget SOURCES "${_project}")" ]; then + echo "${_project}" + else + aget SOURCES "${_project}" + fi + ;; + esac + + unset _project +} + +# path returns the relative path within the repository that contain the docs for a project. +path() { + _project="$1" + + case "${_project}" in + plugins/*) + if [ -z "$(aget PATHS "${_project}")" ]; then + echo "${_project}/docs/sources" + else + aget PATHS "${_project}" + fi + ;; + *) + if [ -z "$(aget PATHS "${_project}")" ]; then + echo "docs/sources" + else + aget PATHS "${_project}" + fi + esac + + unset _project +} + +# version returns the version for a project. Unversioned projects return the special value 'UNVERSIONED'. +version() { + _project="$1" + + case "${_project}" in + plugins/*) + if [ -z "$(aget VERSIONS "${_project}")" ]; then + echo "UNVERSIONED" + else + aget VERSIONS "${_project}" + fi + ;; + *) + if [ -z "$(aget VERSIONS "${_project}")" ]; then + echo latest + else + aget VERSIONS "${_project}" + fi + esac + + unset _project +} + + # new_proj populates a new project structure. new_proj() { _project="$1" @@ -263,31 +392,19 @@ new_proj() { # If version is not set, use the script mapping of project to default versions if it exists. # Fallback to 'latest'. if [ -z "${_version}" ]; then - if [ -z "$(aget VERSIONS "${_project}")" ]; then - _version=latest - else - _version="$(aget VERSIONS "${_project}")" - fi + _version="$(version "${_project}")" fi # If repo is not set, use the script mapping of project to repo name if it exists. # Fallback to using the project name. if [ -z "${_repo}" ]; then - if [ -z "$(aget SOURCES "${_project}")" ]; then - _repo="${_project}" - else - _repo="$(aget SOURCES "${_project}")" - fi + _repo="$(src "${_project}")" fi # If path is not set, use the script mapping of project to docs sources path if it exists. # Fallback to using 'docs/sources'. if [ -z "${_path}" ]; then - if [ -z "$(aget PATHS "${_project}")" ]; then - _path="docs/sources" - else - _path="$(aget PATHS "${_project}")" - fi + _path="$(path "${_project}")" fi echo "${_project}:${_version}:${_repo}:${_path}" @@ -336,7 +453,7 @@ $1 POSIX_HERESTRING if [ "${_project}" = 'website' ]; then - echo '/hugo/content/docs' + echo '/hugo/content' unset _project _version return @@ -481,7 +598,7 @@ POSIX_HERESTRING fi done echo - echo 'Press Ctrl+c to stop the server' + echo 'Press Ctrl+C to stop the server' unset i max req url return @@ -490,7 +607,7 @@ POSIX_HERESTRING echo errr 'The build was interrupted or a build error occurred, check the previous logs for possible causes.' - note 'You might need to use Ctrl+c to end the process.' + note 'You might need to use Ctrl+C to end the process.' unset i max req url } @@ -519,10 +636,12 @@ for arg in "$@"; do ${arg} POSIX_HERESTRING if [ "${_project}" = website ]; then + note "Please be patient, building the website can take some time." + _repo="$(repo_path website)" volumes="--volume=${_repo}/config:/hugo/config" - volumes="${volumes} --volume=${_repo}/layouts/partials:/hugo/layouts/partials" - volumes="${volumes} --volume=${_repo}/layouts/shortcodes:/hugo/layouts/shortcodes" + volumes="${volumes} --volume=${_repo}/layouts:/hugo/layouts" + volumes="${volumes} --volume=${_repo}/scripts:/hugo/scripts" fi unset _project _repo done @@ -540,7 +659,7 @@ POSIX_HERESTRING fi fi - debg "DEBG: Mounting '${_src}' at container path '${_dst}'" + debg "Mounting '${_src}' at container path '${_dst}'" if [ -z "${volumes}" ]; then volumes="--volume=${_src}:${_dst}" @@ -569,7 +688,6 @@ case "${image}" in "${PODMAN}" run \ --init \ --interactive \ - --name "${DOCS_CONTAINER}" \ --platform linux/amd64 \ --rm \ --tty \ @@ -586,7 +704,6 @@ case "${image}" in "${PODMAN}" run \ --init \ --interactive \ - --name "${DOCS_CONTAINER}" \ --platform linux/amd64 \ --rm \ --tty \ @@ -601,6 +718,12 @@ case "${image}" in tempfile="$(mktemp -t make-docs.XXX)" cat <"${tempfile}" #!/usr/bin/env bash + +tc() { + set \${*,,} + echo \${*^} +} + for redirect in ${redirects}; do IFS='^' read -r path ver <<<"\${redirect}" echo -e "---\\nredirectURL: \"\${path/\/hugo\/content/}\"\\ntype: redirect\\nversioned: true\\n---\\n" > "\${path/\${ver}/_index.md}" @@ -609,8 +732,12 @@ done for x in "${url_src_dst_vers}"; do IFS='^' read -r _ _ dst _ <<<"\${x}" + title="\${dst%/*}" + title="\$(tc \${title##*/})" while [[ -n "\${dst}" ]]; do - touch "\${dst}/_index.md" + if [[ ! -f "\${dst}/_index.md" ]]; then + echo -e "---title: \${title}\\n---\\n\\n# \${title}\\n\\n{{< section >}}" > "\${dst}/_index.md" + fi dst="\${dst%/*}" done done @@ -630,33 +757,38 @@ ${PODMAN} run \ --env=HUGO_REFLINKSERRORLEVEL=${HUGO_REFLINKSERRORLEVEL} \ --init \ --interactive \ - --name=${DOCS_CONTAINER} \ - --platform=linux/amd64 \ --publish=${DOCS_HOST_PORT}:3002 \ --publish=3003:3003 \ --rm \ --tty \ ${volumes} \ - ${DOCS_IMAGE} \ - /entrypoint + ${DOCS_IMAGE} EOF - await_build http://localhost:3003 & - if [ -n "${DEBUG}" ]; then - ${cmd} + if [ -n "${ENTER}" ]; then + ${cmd} /bin/bash + elif [ -n "${DEBUG}" ]; then + await_build http://localhost:3003 & + + debg "${cmd} /entrypoint" + ${cmd} /entrypoint else - ${cmd} 2>&1| sed \ - -e '/Web Server is available at http:\/\/localhost:3003\/ (bind address 0.0.0.0)/ d' \ - -e '/^hugo server/ d' \ - -e '/fatal: not a git repository (or any parent up to mount point \/)/ d' \ - -e '/Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)./ d' \ - -e "/Makefile:[0-9]*: warning: overriding recipe for target 'docs'/ d" \ - -e "/docs.mk:[0-9]*: warning: ignoring old recipe for target 'docs'/ d" \ - -e '/\/usr\/bin\/make -j 2 proxy hserver-docs HUGO_PORT=3003/ d' \ - -e '/website-proxy/ d' \ - -e '/rm -rf dist*/ d' \ - -e '/Press Ctrl+C to stop/ d' \ - -e '/make/ d' || echo + await_build http://localhost:3003 & + + ${cmd} /entrypoint 2>&1\ + | sed -u \ + -e '/Web Server is available at http:\/\/localhost:3003\/ (bind address 0.0.0.0)/ d' \ + -e '/^hugo server/ d' \ + -e '/fatal: not a git repository (or any parent up to mount point \/)/ d' \ + -e '/Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)./ d' \ + -e "/Makefile:[0-9]*: warning: overriding recipe for target 'docs'/ d" \ + -e "/docs.mk:[0-9]*: warning: ignoring old recipe for target 'docs'/ d" \ + -e '/\/usr\/bin\/make -j 2 proxy hserver-docs HUGO_PORT=3003/ d' \ + -e '/website-proxy/ d' \ + -e '/rm -rf dist*/ d' \ + -e '/Press Ctrl+C to stop/ d' \ + -e '/make/ d' \ + -e '/WARNING: The manual_mount source directory/ d' fi ;; esac diff --git a/docs/sources/_index.md b/docs/sources/_index.md index 0ea6107fb3546..46dcc4fa1380d 100644 --- a/docs/sources/_index.md +++ b/docs/sources/_index.md @@ -13,6 +13,8 @@ labels: products: - enterprise - oss +cascade: + TEMPO_VERSION: latest title: Grafana open source documentation --- diff --git a/docs/sources/administration/api-keys/index.md b/docs/sources/administration/api-keys/index.md index f2e1be18e751c..6ea118897244c 100644 --- a/docs/sources/administration/api-keys/index.md +++ b/docs/sources/administration/api-keys/index.md @@ -48,7 +48,7 @@ To follow these instructions, you need at least one of the following: To create an API, complete the following steps: 1. Sign in to Grafana. -1. Click **Administration** in the left-side menu and select **API Keys**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **API Keys**. 1. Click **Add API key**. 1. Enter a unique name for the key. 1. In the **Role** field, select one of the following access levels you want to assign to the key. @@ -101,7 +101,7 @@ For more information about permissions, refer to [Roles and permissions]({{< rel To migrate all API keys to service accounts, complete the following steps: -1. Sign in to Grafana, point to **Configuration** (the gear icon), and click **API Keys**. +1. Sign in to Grafana, point to **Administration**, **Users and access**, and click **API Keys**. 1. In the top of the page, find the section which says **Switch from API keys to service accounts** 1. Click **Migrate to service accounts now**. 1. A confirmation window will appear, asking to confirm the migration. Click **Yes, migrate now** if you are willing to continue. @@ -110,7 +110,7 @@ To migrate all API keys to service accounts, complete the following steps: To migrate a single API key to a service account, complete the following steps: 1. Sign in to Grafana. -1. Click **Administration** in the left-side menu and select **API Keys**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **API Keys**. 1. Find the API Key you want to migrate. 1. Click **Migrate to service account**. diff --git a/docs/sources/administration/correlations/_index.md b/docs/sources/administration/correlations/_index.md index 5bed6c17eeb94..6a8b332c5a8a3 100644 --- a/docs/sources/administration/correlations/_index.md +++ b/docs/sources/administration/correlations/_index.md @@ -28,7 +28,7 @@ Explore visualizations that currently support showing links based on correlation - [Logs Panel]({{< relref "./use-correlations-in-visualizations#correlations-in-logs-panel">}}) - [Table]({{< relref "./use-correlations-in-visualizations#correlations-in-table">}}) -You can configure correlations using the **Administration > Correlation** page in Grafana or with [provisioning]({{< relref "../provisioning" >}}). +You can configure correlations using [provisioning]({{< relref "../provisioning" >}}), the **Administration > Plugins and data > Correlations** page in Grafana or directly in [Explore]({{< relref "../../explore/correlations-editor-in-explore" >}}). {{% admonition type="note" %}} Correlations are available in Grafana 10.0+ as an opt-in beta feature. diff --git a/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md b/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md index 6d12a77921932..8dbca454cac50 100644 --- a/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md +++ b/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md @@ -16,7 +16,7 @@ Adding access to create correlations for [Viewers and Editors]({{< relref "../.. ## Add permissions to create correlations -1. Go to the Administration section in Grafana. -1. Open Users page. +1. Go to the **Administration** section in Grafana. +1. Under **Users and access**, open the **Users** page. 1. Select the user to be granted access to create correlations. 1. Add _Data sources writer_ role. diff --git a/docs/sources/administration/correlations/create-a-new-correlation/index.md b/docs/sources/administration/correlations/create-a-new-correlation/index.md index b458c59830e4b..225d6ca8e1c27 100644 --- a/docs/sources/administration/correlations/create-a-new-correlation/index.md +++ b/docs/sources/administration/correlations/create-a-new-correlation/index.md @@ -13,29 +13,14 @@ weight: 40 Make sure you have permission to add new correlations. Only users with write permissions to data sources can define new correlations. -## Create a correlation in Explore's Correlations Editor - -1. Go to Explore page. -1. Select a data source that you would like to be [the source data source]({{< relref "../../../administration/correlations/correlation-configuration#source-data-source-and-result-field" >}}) for a new correlation. -1. Run a query producing data in [a supported visualization]({{< relref "../../../administration/correlations#correlations" >}}). -1. Click "+ Add" button in the top toolbar and select "Add correlation" (you can also select "Correlations Editor" from the [Command Palette]({{< relref "../../../search#command-palette" >}})). -1. Explore is now in Correlations Editor mode indicated by a blue border and top bar. You can exit Correlations Editor using the Exit button in the top bar. -1. The visualization is enriched with links allowing to create new correlations. Links are attached to the data that you can use to build a new query: - - Logs: links are displayed next to field values inside log details for each log row - - Table: every table cell is a link -1. Click on a link to begin adding new correlation. Links are associated with a field that will be used as [a results field of a correlation]({{< relref "../../../administration/correlations/correlation-configuration" >}}). This means the correlation link will be created on the link you select once the correlation is saved. -1. Explore opens a split view. Use the right pane to setup [the target query source of the correlation]({{< relref "../../../administration/correlations/correlation-configuration#target-query" >}}). -1. Build target query using [variables syntax]({{< relref "../../../dashboards/variables/variable-syntax" >}}) with variables from the list provided at the top of the pane. The list contains sample values from the selected data row. -1. Provide optional label and description. Label is used as the name of the link inside the visualization. It can contain variables. -1. Click "Save" button in the top bar to save the correlation and exit Correlations Editor mode. -1. The link used to create the correlation will be replaced with a data link in each row. The variables will be dynamically replaced with values from a selected row. - -Please check [an example]({{< relref "../../../administration/correlations/use-correlations-editor-in-explore" >}}) to see how to create a sample correlation using test data source. +## Create a correlation in Explore's correlations editor + +To learn more, refer to Explore's [documentation]({{< relref "../../../explore/correlations-editor-in-explore" >}}) about building correlations in Explore. ## Create a correlation in Administration page -1. Go to the Administration section in Grafana. -1. Open Correlations page. +1. Go to the **Administration** section in Grafana. +1. Under **Plugins and data**, open the **Correlations** page. 1. Click the “Add” button in the top right corner. 1. Provide a **label** for the correlation. 1. Provide an optional **description**. diff --git a/docs/sources/administration/correlations/use-correlations-editor-in-explore/index.md b/docs/sources/administration/correlations/use-correlations-editor-in-explore/index.md deleted file mode 100644 index a8bdcfcdf52fe..0000000000000 --- a/docs/sources/administration/correlations/use-correlations-editor-in-explore/index.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -labels: - products: - - enterprise - - oss -title: Use Correlations Editor in Explore -weight: 70 ---- - -# Use Correlations Editor in Explore - -## Before you begin - -This example shows how to create a correlation using Correlations Editor in Explore. - -Correlations allow you to use results of one query to run a new query in any data source. In this example you will run a query that renders tabular data. The data will be used to run a different query that yields a graph result. - -Please make sure you have set up [a test data source]({{< relref "../../../datasources/testdata#testdata-data-source" >}}). - -## Create a new correlation - -1. Go to Explore. -1. Select `test data source`. -1. Click on "+ Add" dropdown and select "Add correlation" button. -1. Explore is now in Correlations Editor mode indicated by a blue border. -1. Select scenario: `CSV File`. -1. Select file: `population_by_state.csv`. -1. Note that each cell is a link that you can click on to start creating a new correlation. - - {{< figure src="/static/img/docs/correlations/screenshot-correlations-editor-source-10.2.png" max-width="600px" caption="Selecting the source of a correlation" >}} - -1. Create new correlation that attaches a data link in the `State` column: click on any cell in the `State` column, e.g. "California". -1. Explore opens in split view. Select the same data source you selected in the left pane. -1. The helper above the query editor contains all available variables you can use the target query. Variables contain all data fields (table columns) from the selected row. -1. Select Scenario: `CSV Metric Values`. -1. In the Query Editor's `String Input` field provide variables with population values for each year: `${1980},${2000},${2020}`. This will generate a graph using variable values. -1. In the Query Editor's `Alias` field, write `${State}` - - {{< figure src="/static/img/docs/correlations/screenshot-correlations-editor-target-10.2.png" max-width="600px" caption="Setting up the target of a correlation" >}} - -1. Run a query to see that it produces a graph using sample values from the variables. -1. Save the correlation using "Save" button in the top. - -## Test a newly created correlations - -1. Once the correlation is saved Explore will exit Correlations Editor automatically and re-rerun the query in the left pane. -1. Click on a state name. Note how values from the row are inserted into the query on the right and the graph changes using the values for each row. The query is rerun with updates values every time you click on a state name. - - {{< figure src="/static/img/docs/correlations/screenshot-correlations-example-link-10.2.png" max-width="600px" caption="Result of clicking on a data link" >}} - -You can apply the same steps to any data source. Correlations allow you to create links in visualizations to run dynamic queries based on selected data. In this example we used data returned by a query to build a new query generating different visualization using the same data source. However, you can create correlations between any data sources to create custom exploration flows. - -## Correlations in the logs panel - -Correlations links in the logs panel show slightly differently than the table panel. When you enter the Correlation Editor mode when looking at logs, you will need to expand a log line to see the button that serves as the correlation link. - -{{< figure src="/static/img/docs/correlations/screenshot-correlations-editor-logs-10.2.png" max-width="600px" caption="Logs panel in the Correlations Editor" >}} diff --git a/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md b/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md index 92d160a81a0ef..4c98948ee3a54 100644 --- a/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md +++ b/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md @@ -3,7 +3,7 @@ labels: products: - enterprise - oss -title: Use correlations in visualizations +title: 'Use correlations in visualizations' weight: 70 --- diff --git a/docs/sources/administration/correlations/use-variables-and-transformations/index.md b/docs/sources/administration/correlations/use-variables-and-transformations/index.md index 9c757b5f059d4..6bc3668f9d8d8 100644 --- a/docs/sources/administration/correlations/use-variables-and-transformations/index.md +++ b/docs/sources/administration/correlations/use-variables-and-transformations/index.md @@ -3,7 +3,7 @@ labels: products: - enterprise - oss -title: Use variables and transformations in a correlation +title: 'Use variables and transformations in a correlation' weight: 60 --- diff --git a/docs/sources/administration/enterprise-licensing/_index.md b/docs/sources/administration/enterprise-licensing/_index.md index 966e0889d7221..6dd8c9e2f70cc 100644 --- a/docs/sources/administration/enterprise-licensing/_index.md +++ b/docs/sources/administration/enterprise-licensing/_index.md @@ -45,6 +45,16 @@ To download your Grafana Enterprise license: ### Step 2. Add your license to a Grafana instance +You must install a Grafana Enterprise build to use the enterprise features, which you can [download](https://grafana.com/grafana/download?edition=enterprise). + +{{% admonition type="note" %}} + +If you already use Grafana OSS, you can replace it with the same version of Grafana Enterprise. +Ensure that you back up the configuration and database before proceeding. +For more information, refer to [Back up Grafana](https://grafana.com/docs/grafana//administration/back-up-grafana/). + +{{% /admonition %}} + There is more than one way to add the license to a Grafana instance: #### Upload the license file via the Grafana server administrator page @@ -52,7 +62,7 @@ There is more than one way to add the license to a Grafana instance: This is the preferred option for single instance installations of Grafana Enterprise. 1. Sign in as a Grafana server administrator. -1. Click **Administration > Stats and license** in the side navigation menu. +1. Click **Administration > General > Stats and license** in the side navigation menu. 1. Click **Upload a new token**. 1. Select your license file, and upload it. @@ -207,6 +217,8 @@ To determine the number of active users: 1. Click **Administration** in the side navigation menu. +1. Click **General**. + 1. Click **Stats and license**. 1. Review the utilization count on the **Utilization** panel. diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md index 6f6a35e5eea38..fa06cd3aa0287 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md @@ -112,6 +112,6 @@ In this task you configure Grafana Enterprise to validate the license with AWS i ### Task 4: Start or restart Grafana 1. To restart Grafana and activate your license, update the service running Grafana to use the latest revision of the task definition that you created. -1. After you update the service, navigate to your Grafana instance, sign in with Grafana Admin credentials, and navigate to **Administration > Stats and license** to validate that your license is active. +1. After you update the service, navigate to your Grafana instance, sign in with Grafana Admin credentials, and navigate to **Administration > General > Stats and license** to validate that your license is active. For more information about validating that your license is active, refer to [Grafana Enterprise license restrictions]({{< relref "../../#grafana-enterprise-license-restrictions" >}}). diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md index a63c1af461d80..49060c0989db5 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md @@ -123,7 +123,7 @@ To restart Grafana on a Kubernetes cluster, 1. Run the command `kubectl rollout restart deployment my-release`. -1. After you update the service, navigate to your Grafana instance, sign in with Grafana Admin credentials, and navigate to **Administration > Stats and license** to validate that your license is active. +1. After you update the service, navigate to your Grafana instance, sign in with Grafana Admin credentials, and navigate to **Administration > General > Stats and license** to validate that your license is active. For more information about restarting Grafana, refer to [Restart Grafana]({{< relref "../../../../setup-grafana/start-restart-grafana/" >}}). diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md index 74a1152a1a312..56ba176742d14 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md @@ -36,7 +36,7 @@ You can use AWS Marketplace to make the following modifications to your Grafana 1. Sign in to Grafana as a Server Administrator. -1. Click **Administration** in the side navigation menu, and then **Stats and license**. +1. Click **Administration** in the side navigation menu, **General**, and then **Stats and license**. 1. In the **Token** section under **Enterprise License**, click **Renew token**. diff --git a/docs/sources/administration/organization-management/index.md b/docs/sources/administration/organization-management/index.md index 0d93b93e5d6c4..a332c8110dbab 100644 --- a/docs/sources/administration/organization-management/index.md +++ b/docs/sources/administration/organization-management/index.md @@ -59,7 +59,7 @@ Complete this task when you want to view a list of existing organizations. **To view a list of organizations:** 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Organizations**. +1. Click **Administration** in the left-side menu, **General**, and then **Organizations**. ## Create an organization @@ -72,7 +72,7 @@ Create an organization when you want to isolate dashboards and other resources f **To create an organization:** 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Organizations**. +1. Click **Administration** in the left-side menu, **General**, and then **Organizations**. 1. Click **+ New org**. 1. Enter the name of the new organization and click **Create**. @@ -100,7 +100,7 @@ Deleting the organization also deletes all teams and dashboards associated the o **To delete an organization:** 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Organizations**. +1. Click **Administration** in the left-side menu, **General**, and then **Organizations**. 1. Click the red **X** next to the organization that you want to delete. 1. Click **Delete**. @@ -115,6 +115,6 @@ Edit an organization when you want to change its name. **To edit an organization:** 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Organizations**. +1. Click **Administration** in the left-side menu, **General**, and then **Organizations**. 1. Click the organization you want to edit. 1. Update the organization name and click **Update**. diff --git a/docs/sources/administration/organization-preferences/index.md b/docs/sources/administration/organization-preferences/index.md index 211deadfa1760..913f6ca8345f4 100644 --- a/docs/sources/administration/organization-preferences/index.md +++ b/docs/sources/administration/organization-preferences/index.md @@ -44,6 +44,7 @@ Grafana server administrators and organization administrators can change organiz Follow these instructions if you are a Grafana Server Admin. 1. Click **Administration** in the left-side menu. +1. Click **General**. 1. Click **Organizations**. 1. In the organization list, click the name of the organization that you want to change. 1. In **Name**, enter the new organization name. @@ -54,6 +55,7 @@ Follow these instructions if you are a Grafana Server Admin. If you are an Organization Admin, follow these steps: 1. Click **Administration** in the left-side menu. +1. Click **General**. 1. Click **Default preferences**. 1. In **Organization name**, enter the new name. 1. Click **Update organization name**. @@ -63,7 +65,7 @@ If you are an Organization Admin, follow these steps: Organization administrators and team administrators can change team names and email addresses. To change the team name or email, follow these steps: -1. Click **Administration** in the left-side menu and select **Team**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Team**. 1. In the team list, click the name of the team that you want to change. 1. Click the **Settings** tab. 1. In the Team details section, you can edit the following: @@ -112,6 +114,7 @@ To see what the current settings are, refer to [View server settings]({{< relref Organization administrators can change the UI theme for all users in an organization. 1. Click **Administration** in the left-side menu. +1. Click **General**. 1. Click **Default preferences**. 1. In the Preferences section, select the UI theme. 1. Click **Save**. @@ -120,7 +123,7 @@ Organization administrators can change the UI theme for all users in an organiza Organization and team administrators can change the UI theme for all users on a team. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click the team for which you want to change the UI theme. 1. Click the **Settings** tab. 1. In the Preferences section, select the UI theme. @@ -149,6 +152,7 @@ Grafana server administrators can choose a default timezone for all users on the Organization administrators can choose a default timezone for their organization. 1. Click **Administration** in the left-side menu. +1. Click **General**. 1. Click **Default preferences**. 1. Click to select an option in the **Timezone** list. **Default** is either the browser local timezone or the timezone selected at a higher level. 1. Click **Save**. @@ -157,7 +161,7 @@ Organization administrators can choose a default timezone for their organization Organization administrators and team administrators can choose a default timezone for all users on a team. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click the team for which you want to change the timezone. 1. Click the **Settings** tab. 1. Click to select an option in the **Timezone** list. **Default** is either the browser local timezone or the timezone selected at a higher level. @@ -209,6 +213,7 @@ Organization administrators can choose a default home dashboard for their organi 1. Navigate to the dashboard you want to set as the home dashboard. 1. Click the star next to the dashboard title to mark the dashboard as a favorite if it is not already. 1. Click **Administration** in the left-side menu. +1. Click **General**. 1. Click **Default preferences**. 1. In the **Home Dashboard** field, select the dashboard that you want to use for your home dashboard. Options include all starred dashboards. 1. Click **Save**. @@ -219,7 +224,7 @@ Organization administrators and Team Admins can set a default home dashboard for 1. Navigate to the dashboard you want to set as the home dashboard. 1. Click the star next to the dashboard title to mark the dashboard as a favorite if it is not already. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click the team for which you want to change the home dashboard. 1. Click the **Settings** tab. 1. In the **Home Dashboard** field, select the dashboard that you want to use for your home dashboard. Options include all starred dashboards. @@ -246,6 +251,7 @@ Grafana server administrators can change the default Grafana UI language for all Organization administrators can change the language for all users in an organization. 1. Click **Administration** in the left-side menu. +1. Click **General**. 1. Click **Default preferences**. 1. In the Preferences section, select an option in the **Language** dropdown. 1. Click **Save**. @@ -254,7 +260,7 @@ Organization administrators can change the language for all users in an organiza Organization and team administrators can set a default language for all users on a team. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click the team for which you want to change the language. 1. Click the **Settings** tab. 1. In the Preferences section, select an option in the **Language** dropdown. diff --git a/docs/sources/administration/plugin-management/index.md b/docs/sources/administration/plugin-management/index.md index bf84e299280d1..2fd0da044320b 100644 --- a/docs/sources/administration/plugin-management/index.md +++ b/docs/sources/administration/plugin-management/index.md @@ -85,13 +85,13 @@ Before following the steps below, make sure you are logged in as a Grafana admin -Administrators can find the Plugin catalog at **Administration > Plugins**. +Administrators can find the Plugin catalog at **Administration > Plugins and data > Plugins**. ### Browse plugins To browse for available plugins: -1. In Grafana, click **Administration > Plugins** in the side navigation menu to view installed plugins. +1. In Grafana, click **Administration > Plugins and data > Plugins** in the side navigation menu to view installed plugins. 1. Click the **All** filter to browse all available plugins. 1. Click the **Data sources**, **Panels**, or **Applications** buttons to filter by plugin type. @@ -99,7 +99,7 @@ To browse for available plugins: To install a plugin: -1. In Grafana, click **Administration > Plugins** in the side navigation menu to view installed plugins. +1. In Grafana, click **Administration > Plugins and data > Plugins** in the side navigation menu to view installed plugins. 1. Click the **All** filter to browse all available plugins. 1. Browse and find a plugin. 1. Click on the plugin logo. @@ -111,7 +111,7 @@ When the update is complete, you see a confirmation message that the installatio To update a plugin: -1. In Grafana, click **Administration > Plugins** in the side navigation menu to view installed plugins. +1. In Grafana, click **Administration > Plugins and data > Plugins** in the side navigation menu to view installed plugins. 1. Click on the plugin logo. 1. Click **Update**. @@ -121,7 +121,7 @@ When the update is complete, you see a confirmation message that the update was To uninstall a plugin: -1. In Grafana, click **Administration > Plugins** in the side navigation menu to view installed plugins. +1. In Grafana, click **Administration > Plugins and data > Plugins** in the side navigation menu to view installed plugins. 1. Click on the plugin logo. 1. Click **Uninstall**. diff --git a/docs/sources/administration/provisioning/index.md b/docs/sources/administration/provisioning/index.md index 1de8c823454ab..3a96f6e31117b 100644 --- a/docs/sources/administration/provisioning/index.md +++ b/docs/sources/administration/provisioning/index.md @@ -59,13 +59,14 @@ If you have a literal `$` in your value and want to avoid interpolation, `$$` ca Currently we do not provide any scripts/manifests for configuring Grafana. Rather than spending time learning and creating scripts/manifests for each tool, we think our time is better spent making Grafana easier to provision. Therefore, we heavily rely on the expertise of the community. -| Tool | Project | -| --------- | -------------------------------------------------------------------------------------------------------------- | -| Puppet | [https://forge.puppet.com/puppet/grafana](https://forge.puppet.com/puppet/grafana) | -| Ansible | [https://github.com/grafana/grafana-ansible-collection](https://github.com/grafana/grafana-ansible-collection) | -| Chef | [https://github.com/sous-chefs/chef-grafana](https://github.com/sous-chefs/chef-grafana) | -| Saltstack | [https://github.com/salt-formulas/salt-formula-grafana](https://github.com/salt-formulas/salt-formula-grafana) | -| Jsonnet | [https://github.com/grafana/grafonnet-lib/](https://github.com/grafana/grafonnet-lib/) | +| Tool | Project | +| --------- | ------------------------------------------------------------------------------------------------------------------------------- | +| Puppet | [https://forge.puppet.com/puppet/grafana](https://forge.puppet.com/puppet/grafana) | +| Ansible | [https://github.com/grafana/grafana-ansible-collection](https://github.com/grafana/grafana-ansible-collection) | +| Chef | [https://github.com/sous-chefs/chef-grafana](https://github.com/sous-chefs/chef-grafana) | +| Saltstack | [https://github.com/salt-formulas/salt-formula-grafana](https://github.com/salt-formulas/salt-formula-grafana) | +| Jsonnet | [https://github.com/grafana/grafonnet-lib/](https://github.com/grafana/grafonnet-lib/) | +| NixOS | [services.grafana.provision module](https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/monitoring/grafana.nix) | ## Data sources @@ -156,6 +157,8 @@ datasources: password: # Sets the basic authorization password. basicAuthPassword: + # Sets the version. Used to compare versions when + # updating. Ignored when creating a new data source. version: 1 # Allows users to edit data sources from the # Grafana UI. diff --git a/docs/sources/administration/roles-and-permissions/access-control/assign-rbac-roles/index.md b/docs/sources/administration/roles-and-permissions/access-control/assign-rbac-roles/index.md index a86cc311720be..5f442a00dfa60 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/assign-rbac-roles/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/assign-rbac-roles/index.md @@ -54,14 +54,14 @@ In both cases, the assignment applies only to the user, team or service account For more information about switching organizations, refer to [Switch organizations]({{< relref "../../../user-management/user-preferences/_index.md#switch-organizations" >}}). -3. In the left-side menu, click **Administration** and then **Users**, **Teams**, or **Service accounts**. +3. In the left-side menu, click **Administration**, **Users and access**, and then **Users**, **Teams**, or **Service accounts**. 4. In the **Role** column, select the fixed role that you want to assign to the user, team, or service account. 5. Click **Update**. **To assign a fixed role as a server administrator:** 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. 1. In the Organizations section, click **Change role**. 1. Select a role within an organization that you want to assign to the user. diff --git a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md index b6b79715c66b1..ed3aa9cd33c37 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md @@ -83,7 +83,7 @@ The following tables list permissions associated with basic and fixed roles. | `fixed:organization:reader` | `orgs:read`
`orgs.quotas:read` | Read an organization and its quotas. | | `fixed:organization:writer` | All permissions from `fixed:organization:reader` and
`orgs:write`
`orgs.preferences:read`
`orgs.preferences:write` | Read an organization, its quotas, or its preferences. Update organization properties, or its preferences. | | `fixed:plugins.app:reader` | `plugins.app:access` | Access application plugins (still enforcing the organization role). | -| `fixed:plugins:maintainer` | `plugins:install` | Install and uninstall plugins. | +| `fixed:plugins:maintainer` | `plugins:install` | Install and uninstall plugins. Needs to be assigned globally. | | `fixed:plugins:writer` | `plugins:write` | Enable and disable plugins and edit plugins' settings. | | `fixed:provisioning:writer` | `provisioning:reload` | Reload provisioning. | | `fixed:reports:reader` | `reports:read`
`reports:send`
`reports.settings:read` | Read all reports and shared report settings. | diff --git a/docs/sources/administration/service-accounts/index.md b/docs/sources/administration/service-accounts/index.md index 67d23b456ff66..b22b4b440d259 100644 --- a/docs/sources/administration/service-accounts/index.md +++ b/docs/sources/administration/service-accounts/index.md @@ -79,8 +79,9 @@ Note that the user who created a service account will also be able to read, upda ### To create a service account 1. Sign in to Grafana and click **Administration** in the left-side menu. +1. Click **Users and access**. 1. Click **Service accounts**. -1. Click **Add service account** . +1. Click **Add service account**. 1. Enter a **Display name**. 1. The display name must be unique as it determines the ID associated with the service account. - We recommend that you use a consistent naming convention when you name service accounts. A consistent naming convention can help you scale and maintain service accounts in the future. @@ -104,6 +105,7 @@ By default, service account tokens don't have an expiration date, meaning they w ### To add a token to a service account 1. Sign in to Grafana and click **Administration** in the left-side menu. +1. Click **Users and access**. 1. Click **Service accounts**. 1. Click the service account to which you want to add a token. 1. Click **Add service account token**. @@ -131,6 +133,7 @@ Since Grafana 10.2.0, the `No Basic Role` is available for organization users or ### To assign a role to a service account 1. Sign in to Grafana and click **Administration** in the left-side menu. +1. Click **Users and access**. 1. Click **Service accounts**. 1. Click the service account to which you want to assign a role. As an alternative, find the service account in the list view. 1. Assign a role using the role picker to update. @@ -154,6 +157,7 @@ You can assign on of the following permissions to a specific user or a team: ### To update team permissions for a service account 1. Sign in to Grafana and click **Administration** in the left-side menu. +1. Click **Users and access**. 1. Click **Service accounts**. 1. Click the service account for which you want to update team permissions a role. 1. In the Permissions section at the bottom, click **Add permission**. @@ -163,6 +167,7 @@ You can assign on of the following permissions to a specific user or a team: ### To update user permissions for a service account 1. Sign in to Grafana and click **Administration** in the left-side menu. +1. Click **Users and access**. 1. Click **Service accounts**. 1. Click the service account for which you want to update team permissions a role. 1. In the Permissions section at the bottom, click **Add permission**. diff --git a/docs/sources/administration/stats-and-license/index.md b/docs/sources/administration/stats-and-license/index.md index 52255d2e0215a..1643fd505cf5e 100644 --- a/docs/sources/administration/stats-and-license/index.md +++ b/docs/sources/administration/stats-and-license/index.md @@ -34,7 +34,7 @@ If you are a Grafana server administrator, use the Settings tab to view the sett ### View server settings 1. Log in to your Grafana server with an account that has the Grafana Admin flag set. -1. Click **Administration** in the left-side menu, and then **Settings**. +1. Click **Administration** in the left-side menu, **General**, and then **Settings**. ### Available settings @@ -51,7 +51,7 @@ If you are a Grafana server admin, then you can view useful statistics about you ### View server stats 1. Log in to your Grafana server with an account that has the Grafana Admin flag set. -1. Click **Administration** in the left-side menu, and then **Stats and license**. +1. Click **Administration** in the left-side menu, **General**, and then **Stats and license**. ### Available stats diff --git a/docs/sources/administration/team-management/index.md b/docs/sources/administration/team-management/index.md index 9ade42e25554e..747f55e1971bf 100644 --- a/docs/sources/administration/team-management/index.md +++ b/docs/sources/administration/team-management/index.md @@ -45,7 +45,7 @@ A user can belong to multiple teams. To create a team: 1. Sign in to Grafana as an organization administrator or team administrator. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click **New Team**. 1. Complete the fields and click **Create**. 1. Click **Add member**. @@ -59,7 +59,7 @@ Add a team member to an existing team whenever you want to provide access to tea To add a team member: 1. Sign in to Grafana as an organization administrator. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click the name of the team to which you want to add members, and click **Add member**. 1. Locate and select a user. 1. Choose if you want to add the user as a team Member or an Admin. @@ -72,7 +72,7 @@ Complete this task when you want to add or modify team member permissions. To grant team member permissions: 1. Sign in to Grafana as an organization administrator or a team administrator. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click the name of the team for which you want to add or modify team member permissions. 1. In the team member list, find and click the user that you want to change. You can use the search field to filter the list if necessary. 1. In the Permission column, select the new user permission level. @@ -84,7 +84,7 @@ You can remove a team member when you no longer want to apply team permissions t To remove a team member: 1. Sign in to Grafana as an organization administrator or team administrator. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click a team from which you want to remove a user. 1. Click the **X** next to the name of the user. @@ -95,7 +95,7 @@ Delete a team when you no longer need it. This action permanently deletes the te To delete a team: 1. Sign in to Grafana as an organization administrator. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. 1. Click the **X** next to the name of the team. 1. Click **Delete**. @@ -106,7 +106,7 @@ See the complete list of teams in your Grafana organization. To view a list of teams: 1. Sign in to Grafana as an organization administrator or a team administrator. -1. Click **Administration** in the left-side menu and select **Teams**. +1. Click **Administration** in the left-side menu, **Users and access**, and select **Teams**. The role you use to sign in to Grafana determines how you see team lists. diff --git a/docs/sources/administration/user-management/manage-org-users/index.md b/docs/sources/administration/user-management/manage-org-users/index.md index c01c8546679a1..85c8a8bb88235 100644 --- a/docs/sources/administration/user-management/manage-org-users/index.md +++ b/docs/sources/administration/user-management/manage-org-users/index.md @@ -38,7 +38,7 @@ You can see a list of users with accounts in your Grafana organization. If neces **To view a list of organization users**: 1. Sign in to Grafana as an organization administrator. -1. Navigate to **Administration > Users**. +1. Navigate to **Administration > Users and access > Users**. {{% admonition type="note" %}} If you have [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can also [view a global list of users]({{< relref "../server-user-management#view-a-list-of-users" >}}) in the Server Admin section of Grafana. @@ -59,7 +59,7 @@ Organization roles sync from the authentication provider on user sign-in. To pre **To change the organization role of a user**: 1. Sign in to Grafana as an organization administrator. -1. Navigate to **Administration > Users**. +1. Navigate to **Administration > Users and access > Users**. 1. Find the user account for which you want to change the role. If necessary, use the search field to filter the list. @@ -96,7 +96,7 @@ If you have [server administrator]({{< relref "../../roles-and-permissions/#graf > **Note**: It might be that you are currently in the proper organization and don't need to switch organizations. -1. Navigate to **Administration > Users**. +1. Navigate to **Administration > Users and access > Users**. 1. Click **Organization users**. 1. Click **Invite**. 1. Enter the following information: @@ -127,7 +127,7 @@ The **Pending Invites** button is only visible if there are unanswered invitatio **To manage a pending invitation**: 1. Sign in to Grafana as an organization administrator. -1. Navigate to **Administration > Users**. +1. Navigate to **Administration > Users and access > Users**. 1. Click **Pending Invites**. The **Pending Invites** button appears only when there are unaccepted invitations. @@ -149,7 +149,7 @@ This action does not remove the user account from the Grafana server. **To remove a user from an organization**: 1. Sign in to Grafana as an organization administrator. -1. Navigate to **Administration > Users**. +1. Navigate to **Administration > Users and access > Users**. 1. Find the user account that you want to remove from the organization. Use the search field to filter the list, if necessary. diff --git a/docs/sources/administration/user-management/server-user-management/_index.md b/docs/sources/administration/user-management/server-user-management/_index.md index 50a38bed56931..f5d14efcd25d4 100644 --- a/docs/sources/administration/user-management/server-user-management/_index.md +++ b/docs/sources/administration/user-management/server-user-management/_index.md @@ -39,7 +39,7 @@ You can see a list of users with accounts on your Grafana server. This action mi **To view a list of users**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. {{% admonition type="note" %}} If you have [organization administrator]({{< relref "../../roles-and-permissions/#organization-roles" >}}) permissions and _not_ [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can still [view of list of users in a given organization]({{< relref "../manage-org-users/#view-a-list-of-organization-users" >}}). @@ -56,7 +56,7 @@ View user details when you want to see login, and organizations and permissions **To view user details**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. A user account contains the following sections. @@ -88,7 +88,7 @@ Edit a user account when you want to modify user login credentials, or delete, d **To edit a user account**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. 1. Complete any of the following actions, as necessary. @@ -115,7 +115,7 @@ When you configure advanced authentication using Oauth, SAML, LDAP, or the Auth **To add a user**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click **New user**. 1. Complete the fields and click **Create user**. @@ -136,7 +136,7 @@ The force logout action can apply to one device that is logged in to Grafana, or - Ensure you have Grafana server administrator privileges 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. 1. Scroll down to the Sessions section. 1. Perform one of the following actions: diff --git a/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md b/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md index 1d8f5a70ac3d9..04ddd0dc4909e 100644 --- a/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md +++ b/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md @@ -31,7 +31,7 @@ You are required to specify an Admin role for each organization. The first user **To add a user to an organization**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. 1. In the Organizations section, click **Add user to organization**. 1. Select an organization and a role. @@ -57,7 +57,7 @@ Remove a user from an organization when they no longer require access to the das **To remove a user from an organization**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. 1. In the Organization section, click **Remove from organization** next to the organization from which you want to remove the user. 1. Click **Confirm removal**. diff --git a/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md b/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md index d02cc9c19a30a..c017f104bdd66 100644 --- a/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md +++ b/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md @@ -27,7 +27,7 @@ Server administrators are "super-admins" with full permissions to create, read, **To assign or remove Grafana administrator privileges**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. 1. In the Permissions section, next to Grafana Admin, click **Change**. 1. Click **Yes** or **No**, depending on whether or not you want this user to have the Grafana server administrator role. diff --git a/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md b/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md index 3a72c6b15b161..4569a5ac8f2c9 100644 --- a/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md +++ b/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md @@ -21,7 +21,7 @@ Update organization permissions when you want to enhance or restrict a user's ac **To change a user's organization permissions**: 1. Sign in to Grafana as a server administrator. -1. Click **Administration** in the left-side menu, and then **Users**. +1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. 1. Click a user. 1. In the Organizations section, click **Change role** for the role you want to change 1. Select another role. diff --git a/docs/sources/alerting/_index.md b/docs/sources/alerting/_index.md index af8d6df18d738..b51a15f8ddb0f 100644 --- a/docs/sources/alerting/_index.md +++ b/docs/sources/alerting/_index.md @@ -4,7 +4,7 @@ aliases: - ./unified-alerting/alerting/ - ./alerting/unified-alerting/ canonical: https://grafana.com/docs/grafana/latest/alerting/ -description: Intro to key benefits and features of Grafana Alerting +description: Learn about the key benefits and features of Grafana Alerting labels: products: - cloud diff --git a/docs/sources/alerting/alerting-rules/_index.md b/docs/sources/alerting/alerting-rules/_index.md index 750b7c7c4149f..ac9a03150f5a7 100644 --- a/docs/sources/alerting/alerting-rules/_index.md +++ b/docs/sources/alerting/alerting-rules/_index.md @@ -5,7 +5,7 @@ aliases: - unified-alerting/alerting-rules/ - ./create-alerts/ canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/ -description: Configure alerting +description: Configure the features and integrations you need to create and manage your alerts labels: products: - cloud diff --git a/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md b/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md index 1452d8774fdd3..c320b76bb37b1 100644 --- a/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md +++ b/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md @@ -2,7 +2,7 @@ aliases: - ../unified-alerting/alerting-rules/create-grafana-managed-rule/ canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-grafana-managed-rule/ -description: Configure Grafana-managed alert rules +description: Configure Grafana-managed alert rules to create alerts that can act on data from any of our supported data sources keywords: - grafana - alerting @@ -26,10 +26,18 @@ Grafana-managed rules are the most flexible alert rule type. They allow you to c Multiple alert instances can be created as a result of one alert rule (also known as a multi-dimensional alerting). -**Note:** +{{% admonition type="note" %}} +For Grafana Cloud, there are limits on how many Grafana-managed alert rules you can create. These are as follows: + +- Free: 100 alert rules +- Paid: 2000 alert rules + {{% /admonition %}} Grafana managed alert rules can only be edited or deleted by users with Edit permissions for the folder storing the rules. +If you delete an alerting resource created in the UI, you can no longer retrieve it. +To make a backup of your configuration and to be able to restore deleted alerting resources, create your alerting resources using file provisioning, Terraform, or the Alerting API. + Watch this video to learn more about creating alert rules: {{< vimeo 720001934 >}} In the following sections, we’ll guide you through the process of creating your Grafana-managed alert rules. @@ -84,7 +92,7 @@ To do this, you need to make sure that your alert rule is in the right evaluatio If you are creating a new evaluation group, specify the interval for the group. - All rules within the same group are evaluated sequentially over the same time interval. + All rules within the same group are evaluated concurrently over the same time interval. 1. Enter a pending period. @@ -202,7 +210,7 @@ Create alerts from any panel type. This means you can reuse the queries in the p 1. Navigate to a dashboard in the **Dashboards** section. 2. In the top right corner of the panel, click on the three dots (ellipses). -3. From the dropdown menu, select **More...** and then choose **Create alert**. +3. From the dropdown menu, select **More...** and then choose **New alert rule**. This will open the alert rule form, allowing you to configure and create your alert based on the current panel's query. diff --git a/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md b/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md index a31758d260451..77d206f8e61ea 100644 --- a/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md +++ b/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-recording-rule.md @@ -3,7 +3,7 @@ aliases: - ../unified-alerting/alerting-rules/create-cortex-loki-managed-recording-rule/ - ../unified-alerting/alerting-rules/create-mimir-loki-managed-recording-rule/ canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-mimir-loki-managed-recording-rule/ -description: Configure recording rules +description: Configure recording rules for an external Grafana Mimir or Loki instance keywords: - grafana - alerting diff --git a/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-rule.md b/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-rule.md index f92cb66cd5906..496f96728cadb 100644 --- a/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-rule.md +++ b/docs/sources/alerting/alerting-rules/create-mimir-loki-managed-rule.md @@ -4,7 +4,7 @@ aliases: - ../unified-alerting/alerting-rules/create-mimir-loki-managed-recording-rule/ - ../unified-alerting/alerting-rules/create-mimir-loki-managed-rule/ canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-mimir-loki-managed-rule/ -description: Configure data source-managed alert rules +description: Configure data source-managed alert rules alert for an external Grafana Mimir or Loki instance keywords: - grafana - alerting @@ -28,6 +28,9 @@ Create alert rules for an external Grafana Mimir or Loki instance that has ruler Alert rules for an external Grafana Mimir or Loki instance can be edited or deleted by users with Editor or Admin roles. +If you delete an alerting resource created in the UI, you can no longer retrieve it. +To make a backup of your configuration and to be able to restore deleted alerting resources, create your alerting resources using file provisioning, Terraform, or the Alerting API. + ## Before you begin - Verify that you have write permission to the Prometheus or Loki data source. Otherwise, you will not be able to create or update Grafana Mimir managed alert rules. diff --git a/docs/sources/alerting/alerting-rules/create-notification-policy.md b/docs/sources/alerting/alerting-rules/create-notification-policy.md index 38f478600e3b0..8e0d09b1e0123 100644 --- a/docs/sources/alerting/alerting-rules/create-notification-policy.md +++ b/docs/sources/alerting/alerting-rules/create-notification-policy.md @@ -4,7 +4,7 @@ aliases: - ../old-alerting/notifications/ - ../unified-alerting/notifications/ canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-notification-policy/ -description: Notification policies +description: Configure notification policies to determine how alerts are routed to contact points keywords: - grafana - alerting @@ -43,7 +43,7 @@ Before Grafana v8.2, the configuration of the embedded Alertmanager was shared a 1. In the left-side menu, click **Alerts & IRM** and then **Alerting**. 1. Click **Notification policies**. 1. From the **Choose Alertmanager** dropdown, select an external Alertmanager. By default, the **Grafana Alertmanager** is selected. -1. In the Root policy section, click **Edit**. +1. In the Default policy section, click **...** -> **Edit**. 1. In **Default contact point**, update the contact point to whom notifications should be sent for rules when alert rules do not match any specific policy. 1. In **Group by**, choose labels to group alerts by. If multiple alerts are matched for this policy, then they are grouped by these labels. A notification is sent per group. If the field is empty (default), then all notifications are sent in a single group. Use a special label `...` to group alerts by all labels (which effectively disables grouping). 1. In **Timing options**, select from the following options: @@ -75,13 +75,13 @@ To create a new notification policy, you need to follow its tree structure. New 1. Click **+ Add nested policy**, then add the details using information in [Add new specific policy](#add-new-nested-policy). 1. Click **Save policy** to save your changes. -## Edit specific policy +## Edit notification policies 1. In the left-side menu, click **Alerts & IRM**, and then **Alerting**. 1. Click **Notification policies**. -1. Find the policy you want to edit, then click **Edit**. +1. Find the policy you want to edit, then click **...** -> **Edit**. 1. Make any changes using instructions in [Add new specific policy](#add-new-nested-policy). -1. Click **Save policy**. +1. Save your changes. ## Searching for policies diff --git a/docs/sources/alerting/alerting-rules/manage-contact-points/_index.md b/docs/sources/alerting/alerting-rules/manage-contact-points/_index.md index c63df9fb4776a..186c487914b5a 100644 --- a/docs/sources/alerting/alerting-rules/manage-contact-points/_index.md +++ b/docs/sources/alerting/alerting-rules/manage-contact-points/_index.md @@ -8,7 +8,7 @@ aliases: - ../manage-notifications/manage-contact-points/ # /docs/grafana//alerting/manage-notifications/manage-contact-points/ - create-contact-point/ # /docs/grafana//alerting/alerting-rules/create-contact-point/ canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/ -description: How to manage your contact points +description: Configure contact points to define how your contacts are notified when an alert rule fires keywords: - grafana - alerting @@ -26,7 +26,7 @@ weight: 410 # Configure contact points -Use contact points to define how your contacts are notified when an alert rule fires. You can create, edit, delete, and test a contact point. +Use contact points to define how your contacts are notified when an alert rule fires. You can add, edit, delete, and test a contact point. ## Add a contact point @@ -35,13 +35,13 @@ Complete the following steps to add a contact point. 1. In the left-side menu, click **Alerts & IRM** and then **Alerting**. 1. Click **Contact points**. 1. From the **Choose Alertmanager** dropdown, select an Alertmanager. By default, **Grafana Alertmanager** is selected. -1. Click **+ Add contact point**. -1. In **Name**, enter a descriptive name for the contact point. +1. On the **Contact Points** tab, click **+ Add contact point**. +1. Enter a descriptive name for the contact point. 1. From **Integration**, select a type and fill out mandatory fields. For example, if you choose email, enter the email addresses. Or if you choose Slack, enter the Slack channel(s) and users who should be contacted. 1. Some contact point integrations, like email or webhook, have optional settings. In **Optional settings**, specify additional settings for the selected contact point integration. 1. In Notification settings, optionally select **Disable resolved message** if you do not want to be notified when an alert resolves. 1. To add another contact point integration, click **Add contact point integration** and repeat steps 6 through 8. -1. Click **Save contact point** to save your changes. +1. Save your changes. ## Edit a contact point @@ -49,8 +49,8 @@ Complete the following steps to edit a contact point. 1. In the left-side menu, click **Alerts & IRM** and then **Alerting**. 1. Click **Contact points** to view a list of existing contact points. -1. Find the contact point to edit, and then click **Edit** (pen icon). -1. Make any changes and click **Save contact point**. +1. On the **Contact Points** tab, find the contact point you want to edit, and then click **Edit**. +1. Update the contact point and save your changes. ## Delete a contact point @@ -58,11 +58,11 @@ Complete the following steps to delete a contact point. 1. In the left-side menu, click **Alerts & IRM** and then **Alerting**. 1. Click **Contact points** to view a list of existing contact points. -1. Find the contact point to delete, and then click **Delete** (trash icon). +1. On the **Contact Points** tab, find the contact point you want to delete, and then click **More** -> **Delete**. 1. In the confirmation dialog, click **Yes, delete**. {{% admonition type="note" %}} -You cannot delete contact points that are in use by a notification policy. You will have to either delete the notification policy or update it to use another contact point. +You cannot delete contact points that are in use by a notification policy. Either delete the notification policy or update it to use another contact point. {{% /admonition %}} ## Test a contact point @@ -71,7 +71,7 @@ Complete the following steps to test a contact point. 1. In the left-side menu, click **Alerts & IRM** and then **Alerting**. 1. Click **Contact points** to view a list of existing contact points. -1. Find the contact point to test, then click **Edit** (pen icon). You can also create a new contact point if needed. +1. On the **Contact Points** tab, find the contact point you want to test, then click **Edit**. You can also create a new contact point if needed. 1. Click **Test** to open the contact point testing modal. 1. Choose whether to send a predefined test notification or choose custom to add your own custom annotations and labels to include in the notification. 1. Click **Send test notification** to fire the alert. diff --git a/docs/sources/alerting/alerting-rules/manage-contact-points/configure-integrations.md b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/_index.md similarity index 55% rename from docs/sources/alerting/alerting-rules/manage-contact-points/configure-integrations.md rename to docs/sources/alerting/alerting-rules/manage-contact-points/integrations/_index.md index 03eb242ba2de5..dfd1efd3c6dd0 100644 --- a/docs/sources/alerting/alerting-rules/manage-contact-points/configure-integrations.md +++ b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/_index.md @@ -1,8 +1,8 @@ --- aliases: - alerting/manage-notifications/manage-contact-points/configure-integrations/ -canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/configure-integrations/ -description: Configure integrations +canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/integrations/ +description: Configure contact point integrations to select your preferred communication channels for receiving notifications of firing alerts. keywords: - Grafana - alerting @@ -15,13 +15,13 @@ labels: - cloud - enterprise - oss -title: Configure integrations +title: Configure contact point integrations weight: 100 --- -# Configure integrations +# Configure contact point integrations -Configure integrations in Grafana to select your preferred communication channel for receiving notifications when your alert rules are firing. Each integration has its own configuration options and setup process. In most cases, this involves providing an API key or a Webhook URL. +Configure contact point integrations in Grafana to select your preferred communication channel for receiving notifications when your alert rules are firing. Each integration has its own configuration options and setup process. In most cases, this involves providing an API key or a Webhook URL. Once configured, you can use integrations as part of your contact points to receive notifications whenever your alert changes its state. In this section, we'll cover the basic steps to configure your integrations, so you can start receiving real-time alerts and stay on top of your monitoring data. @@ -38,7 +38,7 @@ Once configured, you can use integrations as part of your contact points to rece | Line | `line` | | Microsoft Teams | `teams` | | Opsgenie | `opsgenie` | -| [Pagerduty](#pagerduty) | `pagerduty` | +| Pagerduty | `pagerduty` | | Prometheus Alertmanager | `prometheus-alertmanager` | | Pushover | `pushover` | | Sensu | `sensu` | @@ -48,28 +48,3 @@ Once configured, you can use integrations as part of your contact points to rece | Threema | `threema` | | VictorOps | `victorops` | | Webhook | `webhook` | - -### PagerDuty - -To set up PagerDuty, provide an integration key. - -| Setting | Description | -| --------------- | ------------------------------------------------------ | -| Integration Key | Integration key for PagerDuty | -| Severity | Level for dynamic notifications, default is `critical` | -| Custom Details | Additional details about the event | - -The `CustomDetails` field is an object containing arbitrary key-value pairs. The user-defined details are merged with the ones we use by default. - -Our default values for `CustomDetails` are: - -```go -{ - "firing": `{{ template "__text_alert_list" .Alerts.Firing }}`, - "resolved": `{{ template "__text_alert_list" .Alerts.Resolved }}`, - "num_firing": `{{ .Alerts.Firing | len }}`, - "num_resolved": `{{ .Alerts.Resolved | len }}`, -} -``` - -In case of duplicate keys, the user-defined details overwrite the default ones. diff --git a/docs/sources/alerting/alerting-rules/manage-contact-points/configure-oncall.md b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/configure-oncall.md similarity index 89% rename from docs/sources/alerting/alerting-rules/manage-contact-points/configure-oncall.md rename to docs/sources/alerting/alerting-rules/manage-contact-points/integrations/configure-oncall.md index 50f1e0b9fccaa..093e78b5cad2d 100644 --- a/docs/sources/alerting/alerting-rules/manage-contact-points/configure-oncall.md +++ b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/configure-oncall.md @@ -1,21 +1,24 @@ --- -canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/configure-oncall/ -description: Configure the Alerting - Grafana OnCall integration +canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/integrations/configure-oncall/ +description: Configure the Alerting - Grafana OnCall integration to connect alerts generated by Grafana Alerting with Grafana OnCall keywords: - grafana - alerting - oncall - integration +aliases: + - ../configure-oncall/ # /docs/grafana/latest/alerting/alerting-rules/manage-contact-points/configure-oncall/ labels: products: - cloud - enterprise - oss -title: Configure Grafana OnCall integration +menuTitle: Grafana OnCall +title: Configure Grafana OnCall for Alerting weight: 300 --- -## Grafana OnCall integration for Alerting +## Configure Grafana OnCall for Alerting Use the Grafana Alerting - Grafana OnCall integration to effortlessly connect alerts generated by Grafana Alerting with Grafana OnCall, where you can then route them according to defined escalation chains and schedules. diff --git a/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/pager-duty.md b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/pager-duty.md new file mode 100644 index 0000000000000..da79c613ebbe2 --- /dev/null +++ b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/pager-duty.md @@ -0,0 +1,41 @@ +--- +canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/integrations/pager-duty/ +description: Configure the PagerDuty integration for Alerting +keywords: + - grafana + - alerting + - pagerduty +labels: + products: + - cloud + - enterprise + - oss +menuTitle: PagerDuty +title: Configure PagerDuty for Alerting +weight: 400 +--- + +# Configure PagerDuty for Alerting + +To set up PagerDuty, provide an integration key. + +| Setting | Description | +| --------------- | ------------------------------------------------------ | +| Integration Key | Integration key for PagerDuty | +| Severity | Level for dynamic notifications, default is `critical` | +| Custom Details | Additional details about the event | + +The `CustomDetails` field is an object containing arbitrary key-value pairs. The user-defined details are merged with the ones we use by default. + +Our default values for `CustomDetails` are: + +```go +{ + "firing": `{{ template "__text_alert_list" .Alerts.Firing }}`, + "resolved": `{{ template "__text_alert_list" .Alerts.Resolved }}`, + "num_firing": `{{ .Alerts.Firing | len }}`, + "num_resolved": `{{ .Alerts.Resolved | len }}`, +} +``` + +In case of duplicate keys, the user-defined details overwrite the default ones. diff --git a/docs/sources/alerting/alerting-rules/manage-contact-points/webhook-notifier.md b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/webhook-notifier.md similarity index 96% rename from docs/sources/alerting/alerting-rules/manage-contact-points/webhook-notifier.md rename to docs/sources/alerting/alerting-rules/manage-contact-points/integrations/webhook-notifier.md index bb1f4b5ed6cee..77004bc92056f 100644 --- a/docs/sources/alerting/alerting-rules/manage-contact-points/webhook-notifier.md +++ b/docs/sources/alerting/alerting-rules/manage-contact-points/integrations/webhook-notifier.md @@ -3,8 +3,8 @@ aliases: - ../contact-points/notifiers/webhook-notifier/ - ../fundamentals/contact-points/webhook-notifier/ - alerting/manage-notifications/manage-contact-points/webhook-notifier/ -canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/webhook-notifier/ -description: Configure the webhook notifier for notifications +canonical: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/manage-contact-points/integrations/webhook-notifier/ +description: Configure the webhook notifier integration for Alerting keywords: - grafana - alerting @@ -16,11 +16,12 @@ labels: - cloud - enterprise - oss -title: Configure the webhook notifier +menuTitle: Webhook notifier +title: Configure the webhook notifier for Alerting weight: 200 --- -### Configure the webhook notifier +### Configure the webhook notifier for Alerting Example JSON body: diff --git a/docs/sources/alerting/difference-old-new.md b/docs/sources/alerting/difference-old-new.md index 1cd8aaf777380..779a6566c2f5a 100644 --- a/docs/sources/alerting/difference-old-new.md +++ b/docs/sources/alerting/difference-old-new.md @@ -4,7 +4,7 @@ _build: aliases: - ./unified-alerting/difference-old-new/ # /docs/grafana//alerting/unified-alerting/difference-old-new/ canonical: https://grafana.com/docs/grafana/latest/alerting/difference-old-new/ -description: Compare new unified alerting compared to legacy dashboard alerting +description: Learn about how Grafana Alerting compares to legacy alerting keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/_index.md b/docs/sources/alerting/fundamentals/_index.md index 5ed760bebd310..eb228673e6dee 100644 --- a/docs/sources/alerting/fundamentals/_index.md +++ b/docs/sources/alerting/fundamentals/_index.md @@ -3,7 +3,7 @@ aliases: - metrics/ - unified-alerting/fundamentals/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/ -description: Intro to the key concepts in Alerting and how it works +description: Learn about the fundamentals of Grafana Alerting as well as the key features it offers labels: products: - cloud diff --git a/docs/sources/alerting/fundamentals/alert-rules/_index.md b/docs/sources/alerting/fundamentals/alert-rules/_index.md index d5b0c84a11c65..ed350a9e98c41 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/_index.md +++ b/docs/sources/alerting/fundamentals/alert-rules/_index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/ -description: About Grafana alert rules +description: Learn about alert rules keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alert-rules/alert-instances.md b/docs/sources/alerting/fundamentals/alert-rules/alert-instances.md index 2960d8cfc9a82..f7a3793c1d476 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/alert-instances.md +++ b/docs/sources/alerting/fundamentals/alert-rules/alert-instances.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/alert-instances/ -description: Learn about Grafana alert instances +description: Learn about alert instances keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alert-rules/alert-rule-types.md b/docs/sources/alerting/fundamentals/alert-rules/alert-rule-types.md index d3139f78b2d63..dd25109c20d8c 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/alert-rule-types.md +++ b/docs/sources/alerting/fundamentals/alert-rules/alert-rule-types.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/alert-rule-types/ -description: Learn about the different alert rule types +description: Learn about the different alert rule types that Grafana Alerting supports keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alert-rules/message-templating.md b/docs/sources/alerting/fundamentals/alert-rules/message-templating.md index cad151fcd9cbf..b9aa80e72edd2 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/message-templating.md +++ b/docs/sources/alerting/fundamentals/alert-rules/message-templating.md @@ -4,7 +4,7 @@ aliases: - ../../message-templating/ - ../../unified-alerting/message-templating/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/message-templating/ -description: Notification templating +description: Learn about notification templating keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alert-rules/organising-alerts.md b/docs/sources/alerting/fundamentals/alert-rules/organising-alerts.md index 5e5244c593e55..7952929c8526c 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/organising-alerts.md +++ b/docs/sources/alerting/fundamentals/alert-rules/organising-alerts.md @@ -3,7 +3,7 @@ aliases: - ../unified-alerting/alerting-rules/edit-cortex-loki-namespace-group/ - ../unified-alerting/alerting-rules/edit-mimir-loki-namespace-group/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/organising-alerts/ -description: Namespaces, folders, and groups +description: Learn about organizing alerts using namespaces, folders, and groups keywords: - grafana - alerting @@ -29,6 +29,8 @@ A namespace contains one or more groups. The rules within a group are run sequen ### Groups -The rules within a group are run sequentially at a regular interval, meaning no rules will be evaluated at the same time and in order of appearance.. The default interval is one (1) minute. You can rename Grafana Mimir or Loki rule namespaces and groups, and edit group evaluation intervals. +The rules within a group are run sequentially at a regular interval, meaning no rules will be evaluated at the same time and in order of appearance. The default interval is one (1) minute. You can rename Grafana Mimir or Loki rule namespaces and groups, and edit group evaluation intervals. > **Note** If you want rules to be evaluated concurrently and with different intervals, consider storing them in different groups. + +> **Note** Grafana managed alert rules are evaluated concurrently instead of sequentially. diff --git a/docs/sources/alerting/fundamentals/alert-rules/queries-conditions/_index.md b/docs/sources/alerting/fundamentals/alert-rules/queries-conditions/_index.md index 43433d7689cb7..da79e4b978b59 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/queries-conditions/_index.md +++ b/docs/sources/alerting/fundamentals/alert-rules/queries-conditions/_index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/queries-conditions/ -description: Introduction to queries and conditions +description: Define queries to get the data you want to measure and conditions that need to be met before an alert rule fires keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alert-rules/recording-rules/_index.md b/docs/sources/alerting/fundamentals/alert-rules/recording-rules/_index.md index 0cf5bc7392e75..3065ca9408664 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/recording-rules/_index.md +++ b/docs/sources/alerting/fundamentals/alert-rules/recording-rules/_index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/recording-rules/ -description: Learn about recording rules +description: Create recording rules to pre-compute frequently needed or computationally expensive expressions and save the result as a new set of time series keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alert-rules/rule-evaluation/_index.md b/docs/sources/alerting/fundamentals/alert-rules/rule-evaluation/_index.md index 3d70a39a67c90..e27bdbbf79d8f 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/rule-evaluation/_index.md +++ b/docs/sources/alerting/fundamentals/alert-rules/rule-evaluation/_index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/rule-evaluation/ -description: Introduction to alert rule evaluation +description: Use alert rule evaluation to determine how frequently an alert rule should be evaluated and how quickly it should change its state keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alert-rules/state-and-health.md b/docs/sources/alerting/fundamentals/alert-rules/state-and-health.md index 0f66f3a832571..1c58bcb91665f 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/state-and-health.md +++ b/docs/sources/alerting/fundamentals/alert-rules/state-and-health.md @@ -2,7 +2,7 @@ aliases: - ../unified-alerting/alerting-rules/state-and-health/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alert-rules/state-and-health/ -description: State and Health of alerting rules +description: Learn about the state and health of alert rules to understand several key status indicators about your alerts keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/alertmanager.md b/docs/sources/alerting/fundamentals/alertmanager.md index f3a29067c3699..7d559f0ddd993 100644 --- a/docs/sources/alerting/fundamentals/alertmanager.md +++ b/docs/sources/alerting/fundamentals/alertmanager.md @@ -5,7 +5,7 @@ aliases: - ../unified-alerting/fundamentals/alertmanager/ - alerting/manage-notifications/alertmanager/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/alertmanager/ -description: Intro to the different Alertmanagers +description: Learn about Alertmanagers and the Alertmanager options for Grafana Alerting labels: products: - cloud diff --git a/docs/sources/alerting/fundamentals/annotation-label/_index.md b/docs/sources/alerting/fundamentals/annotation-label/_index.md index e689ea10d2f15..2dab64ebce3ef 100644 --- a/docs/sources/alerting/fundamentals/annotation-label/_index.md +++ b/docs/sources/alerting/fundamentals/annotation-label/_index.md @@ -3,7 +3,7 @@ aliases: - ../alerting-rules/alert-annotation-label/ - ../unified-alerting/alerting-rules/alert-annotation-label/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/annotation-label/ -description: Annotations and labels for alerting +description: Learn how to use annotations and labels to store key information about alerts keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/annotation-label/how-to-use-labels.md b/docs/sources/alerting/fundamentals/annotation-label/how-to-use-labels.md index 9a2011aff5463..241b047cbd214 100644 --- a/docs/sources/alerting/fundamentals/annotation-label/how-to-use-labels.md +++ b/docs/sources/alerting/fundamentals/annotation-label/how-to-use-labels.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/annotation-label/how-to-use-labels/ -description: Learn about labels and label matchers in alerting +description: Learn how to use labels to link alert rules to notification policies and silences keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/annotation-label/labels-and-label-matchers.md b/docs/sources/alerting/fundamentals/annotation-label/labels-and-label-matchers.md index 09c14d366618d..44f780fb17edb 100644 --- a/docs/sources/alerting/fundamentals/annotation-label/labels-and-label-matchers.md +++ b/docs/sources/alerting/fundamentals/annotation-label/labels-and-label-matchers.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/annotation-label/labels-and-label-matchers/ -description: Learn about labels and label matchers in alerting +description: Learn how to use label matchers to link alert rules to notification policies and silences keywords: - grafana - alerting @@ -50,3 +50,15 @@ then: - A label matcher defined as `id=~[0-9]+` matches this alert rule. - A label matcher defined as `baz!~[0-9]+` matches this alert rule. - Two label matchers defined as `foo=bar` and `id=~[0-9]+` match this alert rule. + +## Exclude labels + +You can also write label matchers to exclude labels. + +Here is an example that shows how to exclude the label `Team`. You can choose between any of the values below to exclude labels. + +| Label | Operator | Value | +| ------ | -------- | ----- | +| `team` | `=` | `""` | +| `team` | `!~` | `.+` | +| `team` | `=~` | `^$` | diff --git a/docs/sources/alerting/fundamentals/annotation-label/variables-label-annotation.md b/docs/sources/alerting/fundamentals/annotation-label/variables-label-annotation.md index 67434380fabc6..c51bf4f4cd7a3 100644 --- a/docs/sources/alerting/fundamentals/annotation-label/variables-label-annotation.md +++ b/docs/sources/alerting/fundamentals/annotation-label/variables-label-annotation.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/annotation-label/variables-label-annotation/ -description: Learn about templating of labels and annotations +description: Learn about how to template labels and annotations keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/contact-points/index.md b/docs/sources/alerting/fundamentals/contact-points/index.md index 3d90b43bcec95..5494a9b6c0a73 100644 --- a/docs/sources/alerting/fundamentals/contact-points/index.md +++ b/docs/sources/alerting/fundamentals/contact-points/index.md @@ -4,7 +4,7 @@ aliases: - /docs/grafana/latest/alerting/unified-alerting/contact-points/ - /docs/grafana/latest/alerting/fundamentals/contact-points/contact-point-types/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/contact-points/ -description: Create or edit contact point +description: Learn about contact points and the supported contact point integrations keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/data-source-alerting.md b/docs/sources/alerting/fundamentals/data-source-alerting.md index 3886845d004b2..e2c09e1cd4658 100644 --- a/docs/sources/alerting/fundamentals/data-source-alerting.md +++ b/docs/sources/alerting/fundamentals/data-source-alerting.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/data-source-alerting/ -description: Data sources in Grafana Alerting +description: Learn about the data sources supported by Grafana Alerting labels: products: - cloud diff --git a/docs/sources/alerting/fundamentals/evaluate-grafana-alerts.md b/docs/sources/alerting/fundamentals/evaluate-grafana-alerts.md index 84dccd52633ab..aeacd684b3c8c 100644 --- a/docs/sources/alerting/fundamentals/evaluate-grafana-alerts.md +++ b/docs/sources/alerting/fundamentals/evaluate-grafana-alerts.md @@ -3,7 +3,7 @@ aliases: - ../metrics/ - ../unified-alerting/fundamentals/evaluate-grafana-alerts/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/evaluate-grafana-alerts/ -description: How to alert on numeric data +description: Learn how how Grafana-managed alerts are evaluated by the backend engine as well as how Grafana handles alerting on numeric rather than time series data labels: products: - cloud diff --git a/docs/sources/alerting/fundamentals/high-availability/_index.md b/docs/sources/alerting/fundamentals/high-availability/_index.md index 126842bf18630..4e43fa4b21b31 100644 --- a/docs/sources/alerting/fundamentals/high-availability/_index.md +++ b/docs/sources/alerting/fundamentals/high-availability/_index.md @@ -3,7 +3,7 @@ aliases: - ../high-availability/ - ../unified-alerting/high-availability/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/high-availability/ -description: High availability +description: Learn about high availability in Grafana Alerting keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/notification-policies/_index.md b/docs/sources/alerting/fundamentals/notification-policies/_index.md index 2a32f951cfb99..56dc8e06bd304 100644 --- a/docs/sources/alerting/fundamentals/notification-policies/_index.md +++ b/docs/sources/alerting/fundamentals/notification-policies/_index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/notification-policies/ -description: Introduction to notifications Policies +description: Learn about how notification policies work keywords: - grafana - alerting diff --git a/docs/sources/alerting/fundamentals/notification-policies/notifications.md b/docs/sources/alerting/fundamentals/notification-policies/notifications.md index 1cd86f7020794..fd98ef3961b38 100644 --- a/docs/sources/alerting/fundamentals/notification-policies/notifications.md +++ b/docs/sources/alerting/fundamentals/notification-policies/notifications.md @@ -3,7 +3,7 @@ aliases: - ../notifications/ - alerting/manage-notifications/create-notification-policy/ canonical: https://grafana.com/docs/grafana/latest/alerting/fundamentals/notification-policies/notifications/ -description: Notification policies +description: Learn about how notification policies work and are structured keywords: - grafana - alerting diff --git a/docs/sources/alerting/manage-notifications/_index.md b/docs/sources/alerting/manage-notifications/_index.md index 65c38e9d652ac..31f9683375f08 100644 --- a/docs/sources/alerting/manage-notifications/_index.md +++ b/docs/sources/alerting/manage-notifications/_index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/ -description: Manage alert notifications +description: Manage your alerts by creating silences, mute timings, and more keywords: - grafana - alert diff --git a/docs/sources/alerting/manage-notifications/create-silence.md b/docs/sources/alerting/manage-notifications/create-silence.md index b824fe081c2be..3b0d544360ead 100644 --- a/docs/sources/alerting/manage-notifications/create-silence.md +++ b/docs/sources/alerting/manage-notifications/create-silence.md @@ -7,7 +7,7 @@ aliases: - ../unified-alerting/silences/ - ../silences/ canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/create-silence/ -description: Add silence alert notification +description: Create silences to stop notifications from getting created for a specified window of time keywords: - grafana - alerting diff --git a/docs/sources/alerting/manage-notifications/images-in-notifications.md b/docs/sources/alerting/manage-notifications/images-in-notifications.md index e1a66d0b87c7d..7155814c59c5d 100644 --- a/docs/sources/alerting/manage-notifications/images-in-notifications.md +++ b/docs/sources/alerting/manage-notifications/images-in-notifications.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/images-in-notifications/ -description: How to use images in notifications +description: Use images in notifications to help users better understand why alerts are firing or have been resolved keywords: - grafana - alerting diff --git a/docs/sources/alerting/manage-notifications/manage-contact-points.md b/docs/sources/alerting/manage-notifications/manage-contact-points.md new file mode 100644 index 0000000000000..bbfd98e4b1e29 --- /dev/null +++ b/docs/sources/alerting/manage-notifications/manage-contact-points.md @@ -0,0 +1,34 @@ +--- +canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/manage-contact-points/ +description: View, edit, copy, or delete your contact points and notification templates +keywords: + - grafana + - alerting + - contact points + - search + - export +labels: + products: + - cloud + - enterprise + - oss +title: Manage contact points +weight: 410 +--- + +# Manage contact points + +The Contact points list view lists all existing contact points and notification templates. + +On the **Contact Points** tab, you can: + +- Search for name and type of contact points and integrations +- View all existing contact points and integrations +- View how many notification policies each contact point is being used for and navigate directly to the linked notification policies +- View the status of notification deliveries +- Export individual contact points or all contact points in JSON, YAML, or Terraform format +- Delete contact points that are not in use by a notification policy + +On the **Notification templates** tab, you can: + +- View, edit, copy or delete existing notification templates diff --git a/docs/sources/alerting/manage-notifications/mute-timings.md b/docs/sources/alerting/manage-notifications/mute-timings.md index e21be431ec657..678ea5b7f2a60 100644 --- a/docs/sources/alerting/manage-notifications/mute-timings.md +++ b/docs/sources/alerting/manage-notifications/mute-timings.md @@ -3,7 +3,7 @@ aliases: - ../notifications/mute-timings/ - ../unified-alerting/notifications/mute-timings/ canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/mute-timings/ -description: Mute timings +description: Create mute timings to prevent alerts from firing during a specific and reoccurring period of time keywords: - grafana - alerting @@ -37,38 +37,38 @@ The following table highlights the key differences between mute timings and sile | Uses time interval definitions that can reoccur | Has a fixed start and end time | | Is created and then added to notification policies | Uses labels to match against an alert to determine whether to silence or not | -## Create a mute timing +## Add mute timings 1. In the left-side menu, click **Alerts & IRM**, and then **Alerting**. -1. Click **Notification policies**. +1. Click **Notification policies** and then the **Mute Timings** tab. 1. From the **Alertmanager** dropdown, select an external Alertmanager. By default, the **Grafana Alertmanager** is selected. -1. Scroll down to the Mute timings section. 1. Click **+ Add mute timing**. 1. Fill out the form to create a [time interval](#time-intervals) to match against for your mute timing. -1. Click **Submit** to create the mute timing. +1. Save your mute timing. ## Add mute timing to a notification policy 1. In the left-side menu, click **Alerts & IRM**, and then **Alerting**. -1. Click **Notification policies**. -1. Identify the notification policy you would like to add the mute timing to and click the **Edit** button for that policy. -1. In the Specific routing section, from the **Mute timings** dropdown, select the mute timings you would like to add to the route. -1. Click **Save policy**. +1. Click **Notification policies** and make sure you are on the **Notification Policies** tab. +1. Find the notification policy you would like to add the mute timing to and click **...** -> **Edit**. +1. From the **Mute timings** dropdown, choose the mute timings you would like to add to the policy. +1. Save your changes. ## Time intervals -A time interval is a definition for a moment in time. If an alert fires during this interval it will be suppressed. All fields are lists, and at least one list element must be satisfied to match the field. Fields also support ranges using `:` (ex: `monday:thursday`). The fields available for a time interval are: mute timing can contain multiple time intervals. A time interval is a specific duration when alerts are suppressed from firing. The duration typically consists of a specific time range along with days of a week, month, or year. - - All properties for the time interval are lists, and at least one list element must be satisfied to match the field. The fields support ranges using `:` (ex: `monday:thursday`). If you leave a field blank, it will match with any moment of time. +A time interval is a specific duration during which alerts are suppressed. The duration typically consists of a specific time range and the days of the week, month, or year. Supported time interval options are: - Time range: The time inclusive of the start and exclusive of the end time (in UTC if no location has been selected, otherwise local time). +- Location: Depending on the location you select, the time range is displayed in local time. - Days of the week: The day or range of days of the week. Example: `monday:thursday`. - Days of the month: The date 1-31 of a month. Negative values can also be used to represent days that begin at the end of the month. For example: `-1` for the last day of the month. - Months: The months of the year in either numerical or the full calendar month. For example: `1, may:august`. - Years: The year or years for the interval. For example: `2021:2024`. +All fields are lists; to match the field, at least one list element must be satisfied. Fields also support ranges using `:` (e.g., `monday:thursday`). + If a field is left blank, any moment of time will match the field. For an instant of time to match a complete time interval, all fields must match. A mute timing can contain multiple time intervals. If you want to specify an exact duration, specify all the options. For example, if you wanted to create a time interval for the first Monday of the month, for March, June, September, and December, between the hours of 12:00 and 24:00 UTC your time interval specification would be: diff --git a/docs/sources/alerting/manage-notifications/template-notifications/_index.md b/docs/sources/alerting/manage-notifications/template-notifications/_index.md index dffd7502fc98f..735f1b0c874f7 100644 --- a/docs/sources/alerting/manage-notifications/template-notifications/_index.md +++ b/docs/sources/alerting/manage-notifications/template-notifications/_index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/template-notifications/ -description: How to customize your notifications using templating +description: Customize your notifications using notification templates keywords: - grafana - alerting diff --git a/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md b/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md index 53a6f82d82282..947556e4e2324 100644 --- a/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md +++ b/docs/sources/alerting/manage-notifications/template-notifications/create-notification-templates.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/template-notifications/create-notification-templates/ -description: How to create notification templates +description: Create notification templates to sent to your contact points keywords: - grafana - alerting @@ -26,29 +26,28 @@ You can add one or more templates to your notification template. Your notification template name must be unique. You cannot have two templates with the same name in the same notification template or in different notification templates. Avoid defining templates with the same name as default templates, such as: `__subject`, `__text_values_list`, `__text_alert_list`, `default.title` and `default.message`. -In the Contact points tab, you can see a list of your notification templates. +To create a notification template, complete the following steps. -To create a template, complete the following steps. +1. Click **Alerts & IRM** -> **Contact points**. +1. Click the **Notification Templates** tab and then **+ Add notification template**. -1. Click **Add template**. +1. Enter a name for the notification template. -2. Choose a name for the notification template. +1. Write the content of the template in the content field. -3. Write the content of the template in the content field. - -4. Click **Save**. +1. Save your changes. `{{ define "email.subject" }}` and `{{ end }}` is automatically added to the start and end of the content: To create a notification template that contains more than one template: -1. Click **Add Template**. +1. Click **+ Add notification template**. 2. Enter a name for the notification template. 3. Write each template in the Content field, including `{{ define "name-of-template" }}` and `{{ end }}` at the start and end of each template. -4. Click **Save**. +4. Save your changes. ## Preview notification templates @@ -58,33 +57,33 @@ Preview how your notification templates will look before using them in your cont To preview your notification templates: -1. Navigate to **Alerts&IRM** -> **Alerting** -> **Contact points**. -1. Click **+Add template** or edit an existing template. +1. Navigate to **Alerts&IRM** -> **Alerting** -> **Contact points** -> **Notification Templates**. +1. Click **+ Add notification template** or edit an existing template. 1. Add or update your template content. - Default data is provided and you can add or edit alert data to it as well as alert instances. You can add alert data directly in the Payload data window itself or click **Choose alert instances** or **Add alert data**. + Default data is provided and you can add or edit alert data to it as well as alert instances. You can add alert data directly in the Payload data window itself or click **Select alert instances** or **Add custom alerts**. 1. [Optional] To add alert data from existing alert instances: - a. Click **Choose alert instances**. + a. Click **Select alert instances**. b. Hover over the alert instances to view more information on each alert instance. c. Click **Confirm** to add the alert instance(s) to the payload. -1. [Optional] To add alert data using the Alert data editor, click **Add alert data:** +1. [Optional] To add alert data using the Alert data editor, click **Add custom data:** a. Add annotations, custom labels and/or set a dashboard or a panel. b. Toggle Firing/resolved depending on whether you want to add firing or resolved alerts to your notification. - c. Click **Add alert data to payload**. + c. Click **Add alert data**. d. Click **Refresh preview** to see what your template content will look like and the corresponding payload data. If there are any errors in your template, they are displayed in the Preview and you can correct them before saving. -1. Click **Save.** +1. Save your changes. ## Template the subject of an email diff --git a/docs/sources/alerting/manage-notifications/template-notifications/reference.md b/docs/sources/alerting/manage-notifications/template-notifications/reference.md index dbf3d2a5cf3c0..16c26acc6d517 100644 --- a/docs/sources/alerting/manage-notifications/template-notifications/reference.md +++ b/docs/sources/alerting/manage-notifications/template-notifications/reference.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/template-notifications/reference/ -description: Reference for templating notifications +description: Learn about templating notifications options keywords: - grafana - alerting @@ -32,7 +32,7 @@ weight: 400 | GeneratorURL | `string` | A link to Grafana, or the Alertmanager if using an external Alertmanager | `{{ .GeneratorURL }}` | | SilenceURL | `string` | A link to silence the alert | `{{ .SilenceURL }}` | | DashboardURL | `string` | A link to the Grafana Dashboard if the alert has a Dashboard UID annotation | `{{ .DashboardURL }}` | -| PanelURL | `string` | A link to the panel if the alert has a Panel ID annotation | `{{ .PanelID }}` | +| PanelURL | `string` | A link to the panel if the alert has a Panel ID annotation | `{{ .PanelURL }}` | | Fingerprint | `string` | A unique string that identifies the alert | `{{ .Fingerprint }}` | | ValueString | `string` | A string that contains the labels and value of each reduced expression in the alert. | `{{ .ValueString }}` | diff --git a/docs/sources/alerting/manage-notifications/template-notifications/use-notification-templates.md b/docs/sources/alerting/manage-notifications/template-notifications/use-notification-templates.md index 5657e86ac8a5a..78f2293b43358 100644 --- a/docs/sources/alerting/manage-notifications/template-notifications/use-notification-templates.md +++ b/docs/sources/alerting/manage-notifications/template-notifications/use-notification-templates.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/template-notifications/use-notification-templates/ -description: Use notification templates in contact points +description: Use notification templates in contact points to customize your notifications keywords: - grafana - alerting diff --git a/docs/sources/alerting/manage-notifications/template-notifications/using-go-templating-language.md b/docs/sources/alerting/manage-notifications/template-notifications/using-go-templating-language.md index 590ab12089605..7919b32170e83 100644 --- a/docs/sources/alerting/manage-notifications/template-notifications/using-go-templating-language.md +++ b/docs/sources/alerting/manage-notifications/template-notifications/using-go-templating-language.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/template-notifications/using-go-templating-language/ -description: Use Go's templating language in notifications +description: Use Go's templating language to create your own notification templates keywords: - grafana - alerting diff --git a/docs/sources/alerting/manage-notifications/view-alert-rules.md b/docs/sources/alerting/manage-notifications/view-alert-rules.md index 7f5136505cf66..0306c707d9130 100644 --- a/docs/sources/alerting/manage-notifications/view-alert-rules.md +++ b/docs/sources/alerting/manage-notifications/view-alert-rules.md @@ -4,7 +4,7 @@ aliases: - ../view-alert-rules/ - rule-list/ canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/view-alert-rules/ -description: Manage alerting rules +description: View and filter by alert rules keywords: - grafana - alerting @@ -40,8 +40,8 @@ When managing large volumes of alerts, you can use extended alert rule search ca To view alerting details: -1. In the Grafana menu, click the **Alerting** (bell) icon to open the Alerting page. By default, the List view displays. -1. In **View as**, toggle between Grouped or State views by clicking the relevant option. See [Grouped view](#grouped-view) and [State view](#state-view) for more information. +1. Click **Alerts & IRM** -> **Alert rules**. By default, the List view displays. +1. In **View as**, toggle between Grouped, List, or State views by clicking the relevant option. See [Grouped view](#grouped-view) and [State view](#state-view) for more information. 1. Expand the rule row to view the rule labels, annotations, data sources the rule queries, and a list of alert instances resulting from this rule. {{< figure src="/static/img/docs/alerting/unified/rule-details-8-0.png" max-width="650px" caption="Alerting rule details" >}} @@ -50,9 +50,11 @@ From the Alert list page, you can also make copies of alert rules to help you re ## Export alert rules -Click **Export** to create and tune an alert rule in the UI, then export to YAML or JSON, and use in the provisioning API or files. You can also export an entire rule group to review or use. +Click the **Export rule group** icon next to each alert rule group to export to YAML, JSON, or Terraform. -**Note:** This is supported in both the UI and provisioning API. +Click **More** -> **Export all Grafana-managed rules** to export all Grafana-managed alert rules to YAML, JSON, or Terraform. + +Click **More** -> **Modify export** next to each individual alert rule within a group to edit provisioned alert rules and export a modified version. ## View query definitions for provisioned alerts diff --git a/docs/sources/alerting/manage-notifications/view-notification-errors.md b/docs/sources/alerting/manage-notifications/view-notification-errors.md index 4e9121aa454a7..9caf6d6e18605 100644 --- a/docs/sources/alerting/manage-notifications/view-notification-errors.md +++ b/docs/sources/alerting/manage-notifications/view-notification-errors.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/view-notification-errors/ -description: View notification errors to find out why they weren't sent or received +description: View notification errors and understand why they failed to be sent or were not received keywords: - grafana - alerting diff --git a/docs/sources/alerting/manage-notifications/view-state-health.md b/docs/sources/alerting/manage-notifications/view-state-health.md index b65a4c9e2b5a7..0ebed5afd1182 100644 --- a/docs/sources/alerting/manage-notifications/view-state-health.md +++ b/docs/sources/alerting/manage-notifications/view-state-health.md @@ -4,7 +4,7 @@ aliases: - ../unified-alerting/alerting-rules/state-and-health/ - ../view-state-health/ canonical: https://grafana.com/docs/grafana/latest/alerting/manage-notifications/view-state-health/ -description: State and Health of alerting rules +description: View the state and health of alert rules keywords: - grafana - alert rules @@ -77,6 +77,10 @@ When evaluation of an alerting rule produces state `NoData` or `Error`, Grafana | **alertname** | Either `DatasourceNoData` or `DatasourceError` depending on the state. | | **datasource_uid** | The UID of the data source that caused the state. | +{{% admonition type="note" %}} +You will need to set the No Data and Error Handling to `No Data` or `Error` in the alert rule as per this doc: https://grafana.com/docs/grafana/latest/alerting/alerting-rules/create-grafana-managed-rule/#configure-no-data-and-error-handling in order to generate the additional labels. +{{% /admonition %}} + You can handle these alerts the same way as regular alerts by adding a silence, route to a contact point, and so on. ## State history view diff --git a/docs/sources/alerting/monitor/_index.md b/docs/sources/alerting/monitor/_index.md index cbd9853387a9c..577910d5690b0 100644 --- a/docs/sources/alerting/monitor/_index.md +++ b/docs/sources/alerting/monitor/_index.md @@ -3,7 +3,7 @@ aliases: - ./meta-monitoring/ # /docs/grafana//alerting/meta-monitoring/ - ./set-up/meta-monitoring/ # /docs/grafana//alerting/set-up/meta-monitoring/ canonical: https://grafana.com/docs/grafana/latest/alerting/monitor/ -description: Meta monitoring +description: Monitor your alerting metrics to ensure you identify potential issues before they become critical. keywords: - grafana - alerting diff --git a/docs/sources/alerting/set-up/_index.md b/docs/sources/alerting/set-up/_index.md index 7418bba3ca694..761a2be32228b 100644 --- a/docs/sources/alerting/set-up/_index.md +++ b/docs/sources/alerting/set-up/_index.md @@ -2,7 +2,7 @@ aliases: - unified-alerting/set-up/ canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/ -description: How to configure alerting features and integrations +description: Set up or upgrade your implementation of Grafana Alerting labels: products: - oss diff --git a/docs/sources/alerting/set-up/configure-alert-state-history/index.md b/docs/sources/alerting/set-up/configure-alert-state-history/index.md index 5a1145531b33c..1f82d29778799 100644 --- a/docs/sources/alerting/set-up/configure-alert-state-history/index.md +++ b/docs/sources/alerting/set-up/configure-alert-state-history/index.md @@ -1,6 +1,6 @@ --- canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/configure-alert-state-history/ -description: Configure Alert State History +description: Configure alert state history to explore the behavior of your alert rules keywords: - grafana - alerting diff --git a/docs/sources/alerting/set-up/configure-alertmanager/index.md b/docs/sources/alerting/set-up/configure-alertmanager/index.md index c4c9e1fdd57d6..3b6d24a6d8a32 100644 --- a/docs/sources/alerting/set-up/configure-alertmanager/index.md +++ b/docs/sources/alerting/set-up/configure-alertmanager/index.md @@ -2,7 +2,7 @@ aliases: - ../configure-alertmanager/ canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/configure-alertmanager/ -description: Configure Alertmanager +description: Configure an Alertmanager to receive all of your alerts keywords: - grafana - alerting diff --git a/docs/sources/alerting/set-up/configure-high-availability/_index.md b/docs/sources/alerting/set-up/configure-high-availability/_index.md index 22bea808bdee3..d71926d9d9ae0 100644 --- a/docs/sources/alerting/set-up/configure-high-availability/_index.md +++ b/docs/sources/alerting/set-up/configure-high-availability/_index.md @@ -40,7 +40,7 @@ Since gossiping of notifications and silences uses both TCP and UDP port `9094`, 1. In your custom configuration file ($WORKING_DIR/conf/custom.ini), go to the `[unified_alerting]` section. 2. Set `[ha_peers]` to the number of hosts for each Grafana instance in the cluster (using a format of host:port), for example, `ha_peers=10.0.0.5:9094,10.0.0.6:9094,10.0.0.7:9094`. - You must have at least one (1) Grafana instance added to the [`[ha_peer]` section. + You must have at least one (1) Grafana instance added to the `ha_peers` section. 3. Set `[ha_listen_address]` to the instance IP address using a format of `host:port` (or the [Pod's](https://kubernetes.io/docs/concepts/workloads/pods/) IP in the case of using Kubernetes). By default, it is set to listen to all interfaces (`0.0.0.0`). 4. Set `[ha_peer_timeout]` in the `[unified_alerting]` section of the custom.ini to specify the time to wait for an instance to send a notification via the Alertmanager. The default value is 15s, but it may increase if Grafana servers are located in different geographic regions or if the network latency between them is high. diff --git a/docs/sources/alerting/set-up/migrating-alerts/_index.md b/docs/sources/alerting/set-up/migrating-alerts/_index.md index 819e97b9deeb3..376419ddf4050 100644 --- a/docs/sources/alerting/set-up/migrating-alerts/_index.md +++ b/docs/sources/alerting/set-up/migrating-alerts/_index.md @@ -2,7 +2,7 @@ aliases: - ../migrating-alerts/ # /docs/grafana//alerting/migrating-alerts/ canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/ -description: Upgrade Grafana alerts +description: Upgrade to Grafana Alerting labels: products: - enterprise @@ -23,7 +23,7 @@ Existing installations that do not use legacy alerting will have Grafana Alertin Likewise, existing installations that use legacy alerting will be automatically upgraded to Grafana Alerting unless you have opted out of Grafana Alerting before migration takes place. During the upgrade, legacy alerts are migrated to the new alerts type and no alerts or alerting data are lost. -Once the upgrade has taken place, you still have the option to roll back to legacy alerting. However, we do not recommend choosing this option. If you do choose to roll back, Grafana will restore your alerts to the alerts you had at the point in time when the upgrade took place. All new alerts and changes made exclusively in Grafana Alerting will be deleted. +Once the upgrade has taken place, you still have the option to roll back to legacy alerting. However, we do not recommend choosing this option. If you do choose to roll back, Grafana will restore your alerts to the alerts you had at the point in time when the upgrade took place. {{% admonition type="note" %}} Cloud customers, who do not want to upgrade to Grafana Alerting, should contact customer support. @@ -91,13 +91,9 @@ If you want to turn alerting back on, you can remove both flags to enable Grafan Once the upgrade has taken place, you still have the option to roll back to legacy alerting. If you choose to roll back, Grafana will restore your alerts to the alerts you had at the point in time when the upgrade took place. -All new alerts and changes made exclusively in Grafana Alerting will be deleted. - To roll back to legacy alerting, enter the following in your configuration: ```toml -force_migration = true - [alerting] enabled = true @@ -105,7 +101,14 @@ enabled = true enabled = false ``` -> **Note**: We do not recommend this option. If you choose to roll back, Grafana will restore your alerts to the alerts you had at the point in time when the upgrade took place. All new alerts and changes made exclusively in Grafana Alerting will be deleted. +> **Note**: The next time you upgrade to Grafana Alerting, Grafana will restore your Grafana Alerting alerts and configuration to those you had before rolling back. + +If, after rolling back, you wish to delete any existing Grafana Alerting configuration and upgrade your legacy alerting configuration again from scratch, you can enable the `clean_upgrade` option: + +```toml +[unified_alerting.upgrade] +clean_upgrade = true +``` ## Opt in diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting-deprecation.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting-deprecation.md index d598bb059d034..8c165e4b6b60d 100644 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting-deprecation.md +++ b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting-deprecation.md @@ -2,7 +2,7 @@ aliases: - alerting/legacy-alerting-deprecation/ canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting-deprecation/ -description: Legacy alerting deprecation notice +description: Learn about legacy alerting deprecation keywords: - grafana - alerting diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/_index.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/_index.md deleted file mode 100644 index 29f5d6bc07f7a..0000000000000 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/_index.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -aliases: - - /docs/grafana-cloud/alerts/ - - /docs/grafana-cloud/how-do-i/alerts/ - - /docs/grafana-cloud/legacy-alerting/ - - alerting/migrating-alerts/legacy-alerting/ -canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting/ -description: Legacy alerting -labels: - products: - - enterprise - - oss -title: Legacy alerting -weight: 110 ---- - -# Legacy alerting - -**Note:** - -Starting with Grafana v9.0.0, legacy alerting is deprecated. It is no longer actively maintained or supported by Grafana and will be removed in Grafana v11.0.0. - -You have two options to configure alerts within the Grafana Cloud GUI and a third option that enables you to set Grafana Cloud Alerts using the command line. - -- **Grafana alerts** are the same as in an on-prem instance of Grafana. - These alerts are created from a graph panel within a Grafana dashboard. - This is useful when you want to create a simple alert based on one metric from within a panel. - It also has a much simpler learning curve when you are getting started. -- **Grafana Cloud alerts - GUI** are an implementation of Prometheus-style rules that enable you to query your Grafana Cloud Metrics and then set up Prometheus Alertmanager-style alerts based on those rules. - This is useful when you want to create precise, PromQL-based rules or create alerts from across many metrics and logs being collected into your Grafana Cloud Metrics. - This form of alerting is much more powerful and configurable, but that comes with some complexity. -- **Grafana Cloud alerts - CLI** use mimirtool to create and upload the same types of Prometheus-style recording and alerting rules definitions to your Grafana Cloud Metrics instance. - Once created, you will also be able to view these rules from within the Grafana Cloud Alerting page in the GUI. -- **Synthetic Monitoring alerts** are built on Prometheus alerts, just like in Grafana Cloud alerting. - You can configure synthetic monitoring alerts separately using the UI in synthetic monitoring. - Another option to create alerts for synthetic monitoring checks is to simply use Grafana Cloud alerting. - -## Using Grafana alerts in Grafana Cloud - -Grafana alerts are dashboard panel-driven and can only be created using the Graph panel. -This style of alerting builds on top of the query defined for the graph visualization, so alerts and notifications are sent based on breaking some threshold in the associated panel. - -This also means that there is a one-to-one relationship between a Grafana alert and a graph panel. -So although Grafana alerts can be viewed centrally, they can only be managed directly from the panel that they’re tied to. -As a result, Grafana alerting is best suited for smaller setups, where there are only a few individuals or teams responsible for a small set of dashboards and where there are few dependencies between the dashboards. - -{{% admonition type="note" %}} -Most curated dashboards, such as those provided with an integration or with Synthetic Monitoring do not allow you to alert from panels. -This is to preserve the ability to upgrade these dashboards automatically when the integration or Synthetic Monitoring abilities are updated. -To create an editable copy that you can edit and alert from, click settings (the gear logo) within any dashboard and then click **Make Editable**. -The copy will not be upgraded when/if the curated dashboard receives an update. -This is one reason why Grafana Cloud Alerts may be considered a better option. -{{% /admonition %}} - -### What makes Grafana alerts unique? - -With Grafana alerts, alerts are limited to only graph panels within dashboards. -In addition: - -- Alerts can be edited by both Editor and Admin roles -- Alerts are visual, with an associated alerting threshold line -- Alerts work with many non-Prometheus data sources, including Graphite -- Alert notifications can be routed to many external notifier systems, directly from Grafana -- Alerts are directly associated with a dashboard -- Alerts can be tested - -## Using Grafana Cloud Alerts - -Because the metrics you collect and send to Grafana Cloud are centrally stored in one large time-series database, Grafana Cloud Metrics, you can query across these metrics using [PromQL](https://prometheus.io/docs/prometheus/latest/querying/basics/) and build alerts directly around those metrics rather than around a panel. -You can also query across any logs you have sent using Loki. - -Grafana Cloud Alerts are directly tied to metrics and log data. -They can be configured either through the UI or by uploading files containing Prometheus and Loki alert rules with mimirtool. - -Grafana Cloud Alerting's Prometheus-style alerts are built by querying directly from the data source itself. -Because these alerts are based on the data, they are not tied to a single panel. -This makes it possible to evaluate and centrally manage alerts across several different Prometheus and Loki data source instances. - -### What makes Grafana Cloud Alerts unique? - -With Grafana Cloud Alerts, alerts are not limited to coming from a graph panel. -In addition, you can: - -- Prevent alerts from being edited, except by users with accounts that are assigned Admin roles. -- Centrally manage and create alerts across many systems, teams, and dashboards. - Alerts are not bound to just one system, team, or dashboard. -- Create alerts for both metric _and_ log data, based on Prometheus and Loki, respectively. -- Silence and mute alerts in bulk, even using a schedule, using the Alertmanager. -- Route alert notifications to [many external notifier systems](https://prometheus.io/docs/operating/integrations/#alertmanager-webhook-receiver) using Alertmanager configurations -- Dedupe alert notifications automatically. - -### Grafana Cloud Alert configuration methods - -In a traditional on-prem environment, Prometheus-style alert configuration is done through the combination of defining a [Prometheus configuration file](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) and an [Alertmanager configuration file](https://prometheus.io/docs/alerting/latest/configuration/), which live close to the Prometheus server. -With Grafana Cloud, you can still use this setup as well as more flexible architectures. - -- You can use `mimirtool` to upload your configuration files to be hosted and evaluated entirely in Grafana Cloud. -- You can manage both alerting rules and Alertmanager configurations directly through the UI. - Configuration files are unnecessary with this setup. -- You can use both methods concurrently to manage the alerts. - For example, updates made using the `mimirtool` are automatically updated and visible within the Grafana Cloud Alerting interface in minutes. diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/_index.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/_index.md deleted file mode 100644 index 0e95ee1f3e4a8..0000000000000 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/_index.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -aliases: - - /docs/grafana-cloud/alerts/grafana-cloud-alerting/ - - /docs/grafana-cloud/how-do-i/grafana-cloud-alerting/ - - /docs/grafana-cloud/legacy-alerting/grafana-cloud-alerting/ -canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/ -description: Grafana Cloud Alerting -labels: - products: - - cloud -title: Grafana Cloud Alerting -weight: 100 ---- - -# Grafana Cloud Alerting - -Grafana Cloud Alerting allows you to create and manage all of your Prometheus-style alerting rules, for both Prometheus metrics and Loki log data. With this feature, you don't need to leave Grafana, upload or edit configuration files, or install additional tools. - -![Grafana Cloud Alerting](/static/img/docs/grafana-cloud/grafana-cloud-alerting.png) - -## Permissions - -All members of an organization that have alerts set up can view alerts in Grafana Cloud Alerting. This includes everyone with a Viewer, Editor, or Admin role. - -Users with the organization Admin role can also create, edit, or delete alerts. - -## Data sources - -Grafana Cloud Alerting supports rule management across multiple data sources, for both metrics and logs, across all of the stacks in your org. If you have more than one Prometheus or Loki data source, there will be a dropdown at the top for you to select the data source to configure rules. - -{{% admonition type="note" %}} -Pay attention to which data source you select. Cloud alerts are tied to a specific data source. For example, if you have a Loki data source selected you will not be able to create an alert based on a Prometheus data source. -![Cloud Alerting Data Source](/static/img/docs/grafana-cloud/grafana-cloud-alerting-data-source.png) -{{% /admonition %}} - -## Alerts and recording rules - -Prometheus supports two types of rules: - -- [Recording rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) - Recording rules allow you to execute expressions or queries, by saving them off as a stored rule instead. -- [Alerting rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) - Alerting rules allow you to define alert conditions and to route those notifications to an external service. An alert fires if metrics meet criteria defined in the alerting rule. - -Both of these rules are configurable from the Grafana Cloud Alerting interface and configured in the same way. - -## Alert states - -Alert states are identical to the standard format found in Prometheus rule configurations. In Grafana Cloud Alerting, each individual alert is highlighted by its state to more clearly distinguish between alerts. - -- **Firing -** Alerts that have been active for longer than the configured threshold. Alerts are highlighted in red and tagged with a red `firing` label. -- **Pending -** Alerts that have been active for less than the configured threshold. Alerts are highlighted in orange. -- **Inactive -** Alerts that are neither firing nor pending. Alerts are highlighted in green. - -## Notifications - -The **Notifications** tab is where you can view all current notifications and sort them by various states, receivers, and labels. - -![Grafana Cloud Alerting Notifications](/static/img/docs/grafana-cloud/grafana-cloud-alerting-notifications.png) - -## Limits - -There is a limit on how many rules can be created in a rule group. There is also a limit on how many rule groups can be created. - -You can create: - -- 20 rules per rule group -- 35 rule groups - -> It is possible to increase these limits. Please contact customer support for further information. - -If you exceed the limits, you will encounter an error similar to this: - -```bash -ERROR[0000] requests failed fields.msg="request failed with response body -per-user rules per rule group limit (limit: 20 actual: 22) exceeded\n" -status="400 Bad Request" -ERROR[0000] unable to load rule group error="failed request to the cortex api" -group=limit_rules_per_group namespace=test -``` - -To increase the number of rules or rule groups you can configure, contact support to upgrade your account. diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/alertmanager.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/alertmanager.md deleted file mode 100644 index 9346eb6dee90a..0000000000000 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/alertmanager.md +++ /dev/null @@ -1,61 +0,0 @@ ---- -aliases: - - /docs/grafana-cloud/alerts/grafana-cloud-alerting/alertmanager/ - - /docs/grafana-cloud/how-do-i/grafana-cloud-alerting/alertmanager/ - - /docs/grafana-cloud/legacy-alerting/grafana-cloud-alerting/alertmanager/ -canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/alertmanager/ -description: Alertmanager (legacy) -labels: - products: - - cloud - - enterprise - - oss -title: Alertmanager (legacy) -weight: 500 ---- - -# Alertmanager (legacy) - -Grafana Cloud Alerting allows you to edit and view configuration for your Alertmanager directly inside of Grafana. See the official [Alertmanager documentation](https://prometheus.io/docs/alerting/latest/configuration/) to learn how to configure. - -{{% admonition type="note" %}} -Only organization Admins can view or update Alertmanger configurations. -{{% /admonition %}} - -## Edit a config for Grafana Cloud Alerting - -1. In Grafana, hover your cursor over the **Grafana Cloud Alerting** icon and then click **Alertmanager**. -1. If you have more than one Alertmanager source, there will be a dropdown at the top for you to select the data source to edit configurations. -1. Currently active configuration for the Alertmanager will be displayed. Click the **Edit** button to enter edit mode and start making changes. Click "Save and finish editing" once done to persist your changes. -1. Alternatively, updates to the Alertmanager configurations made using the mimirtool will also sync and appear here. - -## Use the Grafana Labs-supplied SMTP option to configure email notifications - -Grafana Cloud users who do not have an SMTP server available for sending alert emails may use Grafana-Labs supplied SMTP relay (available at `smtprelay:2525`). - -1. In Grafana, hover your cursor over the **Grafana Cloud Alerting** icon and then click **Alertmanager**. -1. If you have more than one Alertmanager source, there will be a dropdown at the top for you to select the data source to edit configurations. -1. Find info box with heading **Send alert email notifications from Grafana Cloud** at the top -1. Enter desired email address into the **email address** field -1. Click **Update configuration** button. Alertmanager config will be updated with grafana SMTP relay settings and an "email" receiver that will send to the specified email address. - -{{% admonition type="note" %}} -Following these steps will overwrite any custom global SMTP settings that you might have. Default route configuration will send all notifications to the "email" receiver. If you have already customized routes, they will not be updated and you will have to configure "email" receiver on the appropriate route. -{{% /admonition %}} - -Use these settings in your Grafana Cloud Alerting YAML, if you do not find them already set. Most important is the `smtp_require_tls: false` line. If this is not set properly, alert emails will not be received. If you use mimirtool to configure alertmanager, by default this will be set to `true`, which will cause problems. - -```yaml -global: - smtp_from: noreply@grafana.net - smtp_smarthost: smtprelay:2525 - smtp_require_tls: false -``` - -## Troubleshooting Alertmanager failures - -Configuration errors can cause Alertmanager notification failures, e.g. a typo in an email address recipient or an expired token for a webhook. Grafana Cloud provisions a Loki datasource `grafanacloud--usage-insights` which can be used to display select notification errors with a query similar to the example below. The `instance_type` label of `alerts` is what selects the Grafana Cloud Alertmanager logs. - -```sql -{instance_type="alerts"} | logfmt | level="warn" -``` diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/create-edit-rules.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/create-edit-rules.md deleted file mode 100644 index ca30aa8652288..0000000000000 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/create-edit-rules.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -aliases: - - /docs/grafana-cloud/alerts/grafana-cloud-alerting/create-edit-rules/ - - /docs/grafana-cloud/how-do-i/grafana-cloud-alerting/create-edit-rules/ - - /docs/grafana-cloud/legacy-alerting/grafana-cloud-alerting/create-edit-rules/ -canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/create-edit-rules/ -description: Create and edit alert rules -labels: - products: - - cloud - - enterprise - - oss -title: Create and edit alert rules -weight: 200 ---- - -# Create and edit alert rules - -Creating alerts in Grafana Cloud differs from creating alerts directly with Prometheus or Loki. While the rule format is the same, everything is done in the Grafana Cloud Alerting interface, rather than with configuration files. - -{{% admonition type="note" %}} -Only organization Admins can create or edit alert rules. -{{% /admonition %}} - -## Create an alert rule - -1. In Grafana, hover your cursor over the **Grafana Cloud Alerting** icon and then click **Alerts and rules**. -1. If you have more than one Prometheus or Loki data source, there will be a dropdown at the top for you to select the data source to create or edit rules. -1. Click **Edit rules**. -1. Click **Add rule**. - -Grafana creates a new rule with placeholders. - -``` -alert: "" -expr: "" -``` - -Enter text according to regular Prometheus rule configuration guidelines: - -- [Recording rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) -- [Alerting rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) - -{{% admonition type="note" %}} -Grafana Cloud Alerting does not support comments. -{{% /admonition %}} - -When you are finished, click **Save**. You can then repeat the process to create more rules or click **Finish editing** to return to the rules list. - -## Edit an alert rule - -1. In Grafana, hover your cursor over the **Grafana Cloud Alerting** icon and then click **Alerts and rules**. -1. If you have more than one Prometheus or Loki data source, there will be a dropdown at the top for you to select the data source to create or edit rules. -1. Click **Edit rules**. -1. Scroll down to the rule that you want to edit and then click **Edit**. -1. Make any necessary changes to the rule text and then click **Save**. -1. Click **Finish editing** to return to the rules list. - -## Delete an alert rule - -1. In Grafana, hover your cursor over the **Grafana Cloud Alerting** icon and then click **Alerts and rules**. -1. If you have more than one Prometheus or Loki data source, there will be a dropdown at the top for you to select the data source to create or edit rules. -1. Click **Edit rules**. -1. Scroll down to the rule that you want to edit and then click **Delete**. -1. Click **Finish editing** to return to the rules list. diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/namespaces-and-groups.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/namespaces-and-groups.md deleted file mode 100644 index 0602b06995f60..0000000000000 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/namespaces-and-groups.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -aliases: - - /docs/grafana-cloud/alerts/grafana-cloud-alerting/namespaces-and-groups/ - - /docs/grafana-cloud/how-do-i/grafana-cloud-alerting/namespaces-and-groups/ - - /docs/grafana-cloud/legacy-alerting/grafana-cloud-alerting/namespaces-and-groups/ -canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/namespaces-and-groups/ -description: Namespaces and rule groups -labels: - products: - - cloud - - enterprise - - oss -title: Namespaces and rule groups -weight: 400 ---- - -# Namespaces and rule groups - -By default, all alerting and recording rules created in Grafana Cloud Alerting will default to a single namespace and a single rule group. - -## Managing namespaces - -While Grafana Cloud Alerting does support viewing multiple namespaces that have been added through the mimirtool, it is currently not possible to add new namespaces or to rename the existing ones. - -## Managing rule groups - -Rule groups can be managed directly within the Grafana Cloud Alerting interface or through the mimirtool, similar to managing namespaces. - -{{% admonition type="note" %}} -By default, Grafana Cloud limits the number of rule groups to 20, with a limit of up to 15 rules per group. If you wish to increase the default limits, please [open a support ticket](/profile/org#support) or reach out to your account manager. -{{% /admonition %}} - -### Create a new rule group: - -1. In Grafana, hover your cursor over the **Grafana Cloud Alerting** icon and then click **Alerts and rules**. -2. If you have more than one Prometheus or Loki data source, there will be a dropdown at the top for you to select the data source to create or edit rules. -3. Click **Create new rule group**. -4. Enter text to name your new rule group. -5. Enter text for the new rule in your new rule group, according to regular Prometheus rule configuration guidelines: - -- [Recording rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) -- [Alerting rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) - -6. When you are finished naming your new rule group and adding new rule details, click **Save**. - -{{% admonition type="note" %}} -In order to create a new rule group, you must also create a new rule for it. -{{% /admonition %}} - -### Update a rule group - -Existing rule groups can be renamed by selecting the **pencil** icon next to the rule group name. - -### Delete a rule group - -Rule groups will be automatically deleted once the all rules within a group are deleted. diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/silences.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/silences.md deleted file mode 100644 index 83a98d672c676..0000000000000 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/silences.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -aliases: - - /docs/grafana-cloud/alerts/grafana-cloud-alerting/silences/ - - /docs/grafana-cloud/how-do-i/grafana-cloud-alerting/silences/ - - /docs/grafana-cloud/legacy-alerting/grafana-cloud-alerting/silences/ -canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/silences/ -description: Silences -labels: - products: - - cloud - - enterprise - - oss -title: Silences -weight: 600 ---- - -# Silences - -Grafana Cloud Alerting allows you to manage silences for your alertmanager notifications directly inside of Grafana. This applies to alerting rules created for both Prometheus metrics and Loki logs. - -## Create a silence - -1. In Grafana, hover your cursor over the **Grafana Cloud Alerting** icon and then click **Silences**. -2. Click **New silence**. -3. Enter a date in **Start of silence** to indicate when the silence should go into effect. -4. Enter a date in **End of silence** to indicate when the silence should expire. -5. Enter one or more matchers by filling out the **Name** and **Value** fields. Matchers determine which rules the silence will apply to. -6. Enter the name of the owner in **Creator**. -7. Enter a **Comment**. -8. To view which rules will be affected by your silence, click **Preview alerts**. -9. Otherwise, when you are finished, click **Create** - -## Update an existing silence - -You can always update an existing silence by clicking the **Edit silence** button under the silence. - -It is also possible to expire a silence, on-demand, by clicking the **Expire silence** button under the silence. This will override the original scheduled expiration date of the silence. diff --git a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/view-filter-rules.md b/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/view-filter-rules.md deleted file mode 100644 index 999cee1f7ef16..0000000000000 --- a/docs/sources/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/view-filter-rules.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -aliases: - - /docs/grafana-cloud/alerts/grafana-cloud-alerting/view-filter-rules/ - - /docs/grafana-cloud/how-do-i/grafana-cloud-alerting/view-filter-alerts/ - - /docs/grafana-cloud/legacy-alerting/grafana-cloud-alerting/view-filter-rules/ -canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/migrating-alerts/legacy-alerting/grafana-cloud-alerting/view-filter-rules/ -description: View and filter alert rules -labels: - products: - - cloud - - enterprise - - oss -title: View and filter alert rules -weight: 300 ---- - -# View and filter alert rules - -Grafana Cloud Alerting displays a list of all recording and alerting rules assigned to a selected data source in the Alerts and rules tab. - -All members of an organization that have access to a particular data source can view the list of rules and filter or reorder their view. - -## View alert rules - -1. Hover your cursor over the **Grafana Cloud Alerting** icon (alarm bell with Prometheus logo) and then click **Alerts and rules**. -1. In the list at the top of the tab, select the data source for which you want to view rules. - -Grafana displays rules according to rule groups. If your instance has added namespaces and alert groups, then they will be ordered alphabetically. Otherwise, you will have one namespace called `default` and an alert group called `rules`. - -If an alert is firing, then click the down carrot arrow to see additional information. The Label and annotations section appears. - -## Filter your alert rule view - -You can control which alerts you see and in what order they appear several ways. Combine different filters to personalize your view so that you can quickly find the information that you need. - -- **Filter by alert state -** Click the toggles to show or hide alerts in different states. Turn off the toggle to hide alerts matching the state. -- **Filter by rule type -** Click the toggles to show or hide alerting rules or recording rules. -- **View options -** Click the toggle to show or hide the Prometheus annotations shown in the Labels and annotations section. -- **Rule sorting -** Click an option to sort alert rules within each rule group. - - **None -** No special sort is applied and sorts as if in a file, ordered according to the editing list order. - - **A-Z -** Sorts rules alphabetically according to the rule name. - - **Alert state -** Sorts rules according to the alert state (Firing, Pending, or Inactive). - -## View alert in Explore - -Click **View in Explore** or click the `expr` link to open the `expr` in [Explore][explore]. - -> **Note:** Only users with Admin or Editor roles in an organization can use the Explore feature unless the viewers can edit. - -{{% docs/reference %}} -[explore]: "/docs/grafana -> /docs/grafana//explore" -[explore]: "/docs/grafana-cloud/-> /docs/grafana//explore" -{{% /docs/reference %}} diff --git a/docs/sources/alerting/set-up/performance-limitations/index.md b/docs/sources/alerting/set-up/performance-limitations/index.md index 97e2fd52b5929..882174d4e6743 100644 --- a/docs/sources/alerting/set-up/performance-limitations/index.md +++ b/docs/sources/alerting/set-up/performance-limitations/index.md @@ -3,7 +3,7 @@ aliases: - alerting-limitations/ - alerting/performance-limitations/ canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/performance-limitations/ -description: Performance considerations and limitations +description: Learn about performance considerations and limitations keywords: - grafana - alerting diff --git a/docs/sources/alerting/set-up/provision-alerting-resources/_index.md b/docs/sources/alerting/set-up/provision-alerting-resources/_index.md index 8ca675a7c11d3..b64985632fdad 100644 --- a/docs/sources/alerting/set-up/provision-alerting-resources/_index.md +++ b/docs/sources/alerting/set-up/provision-alerting-resources/_index.md @@ -22,21 +22,25 @@ weight: 300 Alerting infrastructure is often complex, with many pieces of the pipeline that often live in different places. Scaling this across multiple teams and organizations is an especially challenging task. Grafana Alerting provisioning makes this process easier by enabling you to create, manage, and maintain your alerting data in a way that best suits your organization. -There are three options to choose from: +Provisioning for Grafana Alerting supports alert rules, contact points, notification policies, mute timings, and templates. -1. Use file provisioning to provision your Grafana Alerting resources, such as alert rules and contact points, through files on disk. +You cannot edit provisioned alerting resources in the Grafana UI in the same way as unprovisioned alerting resources. You can only edit provisioned contact points, notification policies, templates, and mute timings in the source where they were created. For example, if you provision your alerting resources using files from disk, you cannot edit the data in Terraform or from within Grafana. -1. Provision your alerting resources using the Alerting Provisioning HTTP API. +To modify provisioned alert rules, you can use the **Modify export** feature to edit and then export. - For more information on the Alerting Provisioning HTTP API, refer to [Alerting provisioning HTTP API][alerting_provisioning]. +Choose from the options below to provision your Grafana Alerting resources. + +1. Use file provisioning to provision your Grafana Alerting resources, such as alert rules and contact points, through files on disk. -1. {{% admonition type="note" %}} - If you are using Open Source, you can provision your alerting resources using [Terraform](https://www.terraform.io/). + {{% admonition type="note" %}} + File provisioning is not available in Grafana Cloud instances. {{% /admonition %}} -**Note:** +2. Use the Alerting Provisioning HTTP API. + + For more information on the Alerting Provisioning HTTP API, refer to [Alerting provisioning HTTP API][alerting_provisioning]. -Currently, provisioning for Grafana Alerting supports alert rules, contact points, notification policies, mute timings, and templates. Provisioned alerting resources using file provisioning or Terraform can only be edited in the source that created them and not from within Grafana or any other source. For example, if you provision your alerting resources using files from disk, you cannot edit the data in Terraform or from within Grafana. +3. Use [Terraform](https://www.terraform.io/). **Useful Links:** diff --git a/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md b/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md index b9ca09e094654..1ac14176febbb 100644 --- a/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md +++ b/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md @@ -652,7 +652,7 @@ muteTimes: - times: - start_time: '06:00' end_time: '23:59' - location: 'UTC' + location: 'UTC' weekdays: ['monday:wednesday', 'saturday', 'sunday'] months: ['1:3', 'may:august', 'december'] years: ['2020:2022', '2030'] diff --git a/docs/sources/alerting/set-up/provision-alerting-resources/view-provisioned-resources/index.md b/docs/sources/alerting/set-up/provision-alerting-resources/view-provisioned-resources/index.md index 2670bf68c1ca3..5edb960bffce4 100644 --- a/docs/sources/alerting/set-up/provision-alerting-resources/view-provisioned-resources/index.md +++ b/docs/sources/alerting/set-up/provision-alerting-resources/view-provisioned-resources/index.md @@ -2,7 +2,7 @@ aliases: - ../../provision-alerting-resources/view-provisioned-resources/ canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/provision-alerting-resources/view-provisioned-resources/ -description: View provisioned resources in Grafana +description: Manage provisioned alerting resources in Grafana keywords: - grafana - alerting @@ -13,14 +13,16 @@ labels: - cloud - enterprise - oss -menuTitle: View provisioned resources in Grafana -title: View provisioned alerting resources in Grafana +menuTitle: Manage provisioned resources in Grafana +title: Manage provisioned alerting resources in Grafana weight: 300 --- -# View provisioned alerting resources in Grafana +# Manage provisioned alerting resources in Grafana -Verify that your alerting resources were created in Grafana. +Verify that your alerting resources were created in Grafana, as well as edit or export your provisioned alerting resources. + +## View provisioned alerting resoureces To view your provisioned resources in Grafana, complete the following steps. @@ -30,6 +32,49 @@ To view your provisioned resources in Grafana, complete the following steps. Provisioned resources are labeled **Provisioned**, so that it is clear that they were not created manually. +## Export provisioned alerting resources + +Export your alerting resources, such as alert rules, contact points, and notification policies in JSON, YAML, or Terraform format. You can export all Grafana-managed alert rules, single folders, and single groups. + +To export provisioned alerting resources from the Grafana UI, complete the following steps. + +1. Click **Alerts & IRM** -> **Alert rules**. +1. To export all Grafana-managed rules, click **More v** -> **Export all Grafana-managed rules**. +1. To export a folder, change the **View as** to **List**. +1. Select the folder you want to export and click the **Export rules folder** icon. +1. To export a group, change the **View as** to **Grouped**. +1. Find the group you want to export and click the **Export rule group** icon. +1. Choose the format to export in. + + Note that formats JSON and YAML are suitable only for file provisioning. To get rule definition in provisioning API format, use the provisioning GET API. + +1. Click **Copy Code** or **Download**. +1. Choose **Copy Code** to go to an existing file and paste in the code. +1. Choose **Download** to download a file with the exported data. + +## Edit provisioned alert rules + +Use the **Modify export** mode for alert rules to edit provisioned alert rules and export a modified version. + +{{% admonition type="note" %}} This feature is for Grafana-managed alert rules only. It is available to Admin, Viewer, and Editor roles. {{% /admonition %}} + +To edit provisioned alerting alert rules from the Grafana UI, complete the following steps. + +1. Click **Alerts & IRM** -> **Alert rules**. +1. Locate the alert rule you want to edit and click **More** -> **Modify Export** to open the Alert Rule form. +1. From the Alert Rule form, edit the fields you want to change. +1. Click **Export** to export all alert rules within the group. + + You can only export groups of rules; not single rules. + The exported rule data appears in different formats - HTML, JSON, Terraform. + +1. Choose the format to export in. +1. Click **Copy Code** or **Download**. + + a. Choose **Copy Code** to go to an existing file and paste in the code. + + b. Choose **Download** to download a file with the exported data. + ## Edit API-provisioned alerting resources To enable editing of API-provisioned resources in the Grafana UI, add the `X-Disable-Provenance` header to the following requests in the API: diff --git a/docs/sources/dashboards/assess-dashboard-usage/index.md b/docs/sources/dashboards/assess-dashboard-usage/index.md index 005a021c2dc72..5f246daf1f24f 100644 --- a/docs/sources/dashboards/assess-dashboard-usage/index.md +++ b/docs/sources/dashboards/assess-dashboard-usage/index.md @@ -51,14 +51,14 @@ For every dashboard and data source, you can access usage information. To see dashboard usage information, click the dashboard insights icon in the header. -{{< figure src="/media/docs/grafana/dashboards/screenshot-dashboard-insights.png" max-width="400px" class="docs-image--no-shadow" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-dashboard-insights.png" max-width="400px" class="docs-image--no-shadow" alt="Dashboard insights icon" >}} Dashboard insights show the following information: - **Stats:** The number of daily queries and errors for the past 30 days. - **Users & activity:** The daily view count for the last 30 days; last activities on the dashboard and recent users (with a limit of 20). -{{< figure src="/static/img/docs/enterprise/dashboard_insights_stats.png" max-width="400px" class="docs-image--no-shadow" >}}{{< figure src="/static/img/docs/enterprise/dashboard_insights_users.png" max-width="400px" class="docs-image--no-shadow" >}} +{{< figure src="/static/img/docs/enterprise/dashboard_insights_stats.png" max-width="400px" class="docs-image--no-shadow" alt="Stats tab" >}}{{< figure src="/static/img/docs/enterprise/dashboard_insights_users.png" max-width="400px" class="docs-image--no-shadow" alt="Users and activity tab" >}} {{% admonition type="note" %}} @@ -81,7 +81,7 @@ To find data source insights: 1. Click a data source. 1. Click the **Insights** tab. -{{< figure src="/media/docs/grafana/dashboards/screenshot-data-source-insights-9.5.png" max-width="650px" class="docs-image--no-shadow" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-data-source-insights-9.5.png" max-width="650px" class="docs-image--no-shadow" alt="Insights tab for a data source" >}} ## Presence indicator @@ -89,7 +89,7 @@ When you are signed in and looking at a dashboard, you can know who is looking a When there are more active users on a dashboard than can fit within the presence indicator, click the **+X** icon. Doing so opens [dashboard insights](#dashboard-and-data-source-insights), which contains more details about recent user activity. -{{< figure src="/static/img/docs/enterprise/presence_indicators.png" max-width="400px" class="docs-image--no-shadow" >}} +{{< figure src="/static/img/docs/enterprise/presence_indicators.png" max-width="400px" class="docs-image--no-shadow" alt="Presence indicator icons" >}} To change _recent_ to something other than the past 10 minutes, edit the [configuration][] file: @@ -123,7 +123,7 @@ You can sort the dashboards by: - Views total - Views 30 days (most and least) -{{< figure src="/media/docs/grafana/dashboards/screenshot-dashboard-sort-9.5.png" max-width="650px" class="docs-image--no-shadow" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-dashboard-sort-9.5.png" max-width="650px" class="docs-image--no-shadow" alt="Open list of dashboard sort options" >}} ## Visualize usage insights data diff --git a/docs/sources/dashboards/build-dashboards/annotate-visualizations/index.md b/docs/sources/dashboards/build-dashboards/annotate-visualizations/index.md index 6eedd05a43e9e..ba85dfa3b3410 100644 --- a/docs/sources/dashboards/build-dashboards/annotate-visualizations/index.md +++ b/docs/sources/dashboards/build-dashboards/annotate-visualizations/index.md @@ -21,7 +21,7 @@ weight: 600 Annotations provide a way to mark points on a visualization with rich events. They are visualized as vertical lines and icons on all graph panels. When you hover over an annotation, you can get event description and event tags. The text field can include links to other systems with more detail. -{{< figure src="/static/img/docs/v46/annotations.png" max-width="800px" >}} +{{< figure src="/static/img/docs/v46/annotations.png" max-width="800px" alt="Annotated visualization with annotation context menu open" >}} You can annotate visualizations in three ways: @@ -148,21 +148,21 @@ Grafana v8.1 and later versions also support typeahead of existing tags, provide For example, create an annotation query name `outages` and specify a tag `outage`. This query will show all annotations (from any dashboard or via API) with the `outage` tag. If multiple tags are defined in an annotation query, then Grafana will only show annotations matching all the tags. To modify the behavior, enable `Match any`, and Grafana will show annotations that contain any one of the tags you provided. -{{< figure src="/media/docs/grafana/dashboards/screenshot-annotations-typeahead-support-10.0.png" max-width="600px" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-annotations-typeahead-support-10.0.png" max-width="600px" alt="Annotation query options" >}} You can also use template variables in the tag query. This means if you have a dashboard showing stats for different services and a template variable that dictates which services to show, you can use the same template variable in your annotation query to only show annotations for those services. -{{< figure src="/media/docs/grafana/dashboards/screenshot-annotation-tag-filter-variable-10.0.png" max-width="600px" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-annotation-tag-filter-variable-10.0.png" max-width="600px" alt="Annotation query options with a template variable query tag" >}} ### Add time regions When adding or editing an annotation, you can define a repeating time region by setting **Query type** to **Time regions**. Then, define the **From** and **To** sections with the preferred days of the week and time. You also have the option to change the timezone, which is set to the dashboard's timezone, by default. -{{< figure src="/media/docs/grafana/dashboards/screenshot-annotation-timeregions-10-v2.png" max-width="600px" caption="Time regions business hours" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-annotation-timeregions-10-v2.png" max-width="600px" alt="Time regions options set to business hours" >}} The above configuration will produce the following result in the Time series panel: -{{< figure src="/media/docs/grafana/screenshot-grafana-10-0-timeseries-time-regions.png" max-width="600px" caption="Time series time regions business hours" >}} +{{< figure src="/media/docs/grafana/screenshot-grafana-10-0-timeseries-time-regions.png" max-width="600px" alt="Time series visualization with time regions business hours" >}} {{% docs/reference %}} [Annotations API]: "/docs/grafana/ -> /docs/grafana//developers/http_api/annotations" diff --git a/docs/sources/dashboards/build-dashboards/manage-dashboard-links/index.md b/docs/sources/dashboards/build-dashboards/manage-dashboard-links/index.md index 2ea8dafc0efb0..b47f847c8e1a2 100644 --- a/docs/sources/dashboards/build-dashboards/manage-dashboard-links/index.md +++ b/docs/sources/dashboards/build-dashboards/manage-dashboard-links/index.md @@ -119,7 +119,7 @@ Each panel can have its own set of links that are shown in the upper left of the Click the icon next to the panel title to see available panel links. -{{< figure src="/media/docs/grafana/screenshot-panel-links.png" width="200px" >}} +{{< figure src="/media/docs/grafana/screenshot-panel-links.png" width="200px" alt="List of panel links displayed" >}} ### Add a panel link diff --git a/docs/sources/dashboards/build-dashboards/manage-library-panels/index.md b/docs/sources/dashboards/build-dashboards/manage-library-panels/index.md index c713f27dba908..dbb0a8dc3e61b 100644 --- a/docs/sources/dashboards/build-dashboards/manage-library-panels/index.md +++ b/docs/sources/dashboards/build-dashboards/manage-library-panels/index.md @@ -30,7 +30,7 @@ When you create a library panel, the panel on the source dashboard is converted 1. Open a panel in edit mode. 1. In the panel display options, click the down arrow option to bring changes to the visualization. - {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-create-lib-panel-from-edit-9-5.png" class="docs-image--no-shadow" max-width= "800px" >}} + {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-create-lib-panel-from-edit-9-5.png" class="docs-image--no-shadow" max-width= "800px" alt="Library panels tab of the panel editor pane" >}} 1. Click **Library panels**, and then click **+ Create library panel** to open the create dialog. 1. In **Library panel name**, enter the name. 1. In **Save in folder**, select the folder to save the library panel. @@ -41,7 +41,7 @@ Once created, you can modify the library panel using any dashboard on which it a You can also create a library panel directly from the edit menu of any panel. -{{< figure src="/media/docs/grafana/panels-visualizations/screenshot-create-from-more-9-5.png" class="docs-image--no-shadow" max-width= "900px" >}} +{{< figure src="/media/docs/grafana/panels-visualizations/screenshot-create-from-more-9-5.png" class="docs-image--no-shadow" max-width= "900px" alt="Create library panel option in the panel menu" >}} ## Add a library panel to a dashboard @@ -77,7 +77,7 @@ You can view a list of available library panels and search for a library panel. 1. Click **Library panels**. You can see a list of previously defined library panels. - {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-library-panel-list-9-5.png" class="docs-image--no-shadow" max-width= "900px" >}} + {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-library-panel-list-9-5.png" class="docs-image--no-shadow" max-width= "900px" alt="Library panels page with list of library panels" >}} 1. Search for a specific library panel if you know its name. diff --git a/docs/sources/dashboards/create-reports/index.md b/docs/sources/dashboards/create-reports/index.md index 41eb93c931d27..fd7c95ebf98f3 100644 --- a/docs/sources/dashboards/create-reports/index.md +++ b/docs/sources/dashboards/create-reports/index.md @@ -26,10 +26,6 @@ Reporting enables you to automatically generate PDFs from any of your dashboards > If you have [Role-based access control][] enabled, for some actions you would need to have relevant permissions. > Refer to specific guides to understand what permissions are required. - - Any changes you make to a dashboard used in a report are reflected the next time the report is sent. For example, if you change the time range in the dashboard, then the time range in the report also changes, unless you've configured a custom time range. For information about recent improvements to the reporting UI, refer to [Grafana reporting: How we improved the UX in Grafana](https://grafana.com/blog/2022/06/29/grafana-reporting-how-we-improved-the-ux-in-grafana/). @@ -121,12 +117,12 @@ If the time zone is set differently between your Grafana server and its remote i > We're actively developing new report layout options. [Contact us](https://grafana.com/contact?about=grafana-enterprise&topic=design-process&value=reporting) to get involved in the design process. -| Layout | Orientation | Support | Description | Preview | -| ------ | ----------- | ------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -| Simple | Portrait | v6.4+ | Generates an A4 page in portrait mode with three panels per page. | {{< figure src="/static/img/docs/enterprise/reports_portrait_preview.png" max-width="500px" max-height="500px" class="docs-image--no-shadow" >}} | -| Simple | Landscape | v6.7+ | Generates an A4 page in landscape mode with a single panel per page. | {{< figure src="/static/img/docs/enterprise/reports_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" >}} | -| Grid | Portrait | v7.2+ | Generates an A4 page in portrait mode with panels arranged in the same way as at the original dashboard. | {{< figure src="/static/img/docs/enterprise/reports_grid_portrait_preview.png" max-width="500px" max-height="500px" class="docs-image--no-shadow" >}} | -| Grid | Landscape | v7.2+ | Generates an A4 page in landscape mode with panels arranged in the same way as in the original dashboard. | {{< figure src="/static/img/docs/enterprise/reports_grid_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" >}} | +| Layout | Orientation | Support | Description | Preview | +| ------ | ----------- | ------- | --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Simple | Portrait | v6.4+ | Generates an A4 page in portrait mode with three panels per page. | {{< figure src="/static/img/docs/enterprise/reports_portrait_preview.png" max-width="500px" max-height="500px" class="docs-image--no-shadow" alt="Simple layout in portrait" >}} | +| Simple | Landscape | v6.7+ | Generates an A4 page in landscape mode with a single panel per page. | {{< figure src="/static/img/docs/enterprise/reports_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" alt="Simple layout in landscape" >}} | +| Grid | Portrait | v7.2+ | Generates an A4 page in portrait mode with panels arranged in the same way as at the original dashboard. | {{< figure src="/static/img/docs/enterprise/reports_grid_portrait_preview.png" max-width="500px" max-height="500px" class="docs-image--no-shadow" alt="Grid layout in portrait" >}} | +| Grid | Landscape | v7.2+ | Generates an A4 page in landscape mode with panels arranged in the same way as in the original dashboard. | {{< figure src="/static/img/docs/enterprise/reports_grid_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" alt="Grid layout in landscape" >}} | ### CSV export diff --git a/docs/sources/dashboards/dashboard-public/index.md b/docs/sources/dashboards/dashboard-public/index.md index 5b4d9e6ed0abb..0f6c25cf752d5 100644 --- a/docs/sources/dashboards/dashboard-public/index.md +++ b/docs/sources/dashboards/dashboard-public/index.md @@ -138,6 +138,7 @@ guaranteed because plugin developers can override this functionality. The follow
  • ClickHouse
  • +
  • CloudWatch
  • Elasticsearch
  • Infinity
  • InfluxDB
  • @@ -165,7 +166,6 @@ guaranteed because plugin developers can override this functionality. The follow
      -
    • CloudWatch
    • Graphite
    @@ -236,16 +236,14 @@ guaranteed because plugin developers can override this functionality. The follow ## Limitations - Panels that use frontend data sources will fail to fetch data. -- Template variables are not currently supported, but support is planned in the future. +- Template variables are not supported. - Exemplars will be omitted from the panel. - Only annotations that query the `-- Grafana --` data source are supported. - Organization annotations are not supported. - Grafana Live and real-time event streams are not supported. -- Library panels are currently not supported, but support is planned in the future. +- Library panels are not supported. - Data sources using Reverse Proxy functionality are not supported. -We're excited to share this enhancement with you and we’d love your feedback! Please check out the [Github](https://github.com/grafana/grafana/discussions/49253) discussion and join the conversation. - ## Custom branding If you're a Grafana Enterprise customer, you can use custom branding to change the appearance of a public dashboard footer. For more information, refer to [Custom branding][]. diff --git a/docs/sources/dashboards/manage-dashboards/index.md b/docs/sources/dashboards/manage-dashboards/index.md index d99e1a006965e..02c2146658d51 100644 --- a/docs/sources/dashboards/manage-dashboards/index.md +++ b/docs/sources/dashboards/manage-dashboards/index.md @@ -131,16 +131,13 @@ A template variable of the type `Constant` is automatically hidden in the dashbo - Paste a [Grafana.com](https://grafana.com) dashboard URL - Paste dashboard JSON text directly into the text area - - The import process enables you to change the name of the dashboard, pick the data source you want the dashboard to use, and specify any metric prefixes (if the dashboard uses any). ### Discover dashboards on grafana.com Find dashboards for common server applications at [Grafana.com/dashboards](https://grafana.com/dashboards). -{{< figure src="/media/docs/grafana/dashboards/screenshot-gcom-dashboards.png" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-gcom-dashboards.png" alt="Preconfigured dashboards on grafana.com">}} ## Set up generative AI features for dashboards @@ -185,11 +182,11 @@ In the picture below we've enabled: - Points and 3-point radius to highlight where data points are actually present. - **Connect null values\* is set to **Always\*\*. -{{< figure src="/static/img/docs/troubleshooting/grafana_null_connected.png" max-width="1200px" >}} +{{< figure src="/static/img/docs/troubleshooting/grafana_null_connected.png" max-width="1200px" alt="Graph with null values connected" >}} In this graph, we set graph to show bars instead of lines and set the **No value** under **Standard options** to **0**. There is a very big difference in the visuals. -{{< figure src="/static/img/docs/troubleshooting/grafana_null_zero.png" max-width="1200px" >}} +{{< figure src="/static/img/docs/troubleshooting/grafana_null_zero.png" max-width="1200px" alt="Graph with null values not connected" >}} ### More examples diff --git a/docs/sources/dashboards/use-dashboards/index.md b/docs/sources/dashboards/use-dashboards/index.md index f77fc5ff75e27..bd1cc105d8162 100644 --- a/docs/sources/dashboards/use-dashboards/index.md +++ b/docs/sources/dashboards/use-dashboards/index.md @@ -32,7 +32,7 @@ The dashboard user interface provides a number of features that you can use to c The following image and descriptions highlight all dashboard features. -{{< figure src="/media/docs/grafana/dashboards/screenshot-dashboard-annotated-9-5-0.png" width="700px" >}} +{{< figure src="/media/docs/grafana/dashboards/screenshot-dashboard-annotated-9-5-0.png" width="700px" alt="An annotated image of a dashboard" >}} - (1) **Grafana home**: Click **Home** in the breadcrumb to be redirected to the home page configured in the Grafana instance. - (2) **Dashboard title**: When you click the dashboard title, you can search for dashboards contained in the current folder. diff --git a/docs/sources/dashboards/variables/_index.md b/docs/sources/dashboards/variables/_index.md index 2a394e985a26f..616b7c8457856 100644 --- a/docs/sources/dashboards/variables/_index.md +++ b/docs/sources/dashboards/variables/_index.md @@ -24,7 +24,8 @@ the value, using the dropdown at the top of the dashboard, your panel's metric q Variables allow you to create more interactive and dynamic dashboards. Instead of hard-coding things like server, application, and sensor names in your metric queries, you can use variables in their place. Variables are displayed as dropdown lists at the top of the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard. -{{< figure src="/static/img/docs/v50/variables_dashboard.png" >}} + +{{< figure src="/static/img/docs/v50/variables_dashboard.png" alt="Variable drop-down open and two values selected" >}} These can be especially useful for administrators who want to allow Grafana viewers to quickly adjust visualizations but do not want to give them full editing permissions. Grafana Viewers can use variables. diff --git a/docs/sources/datasources/mssql/query-editor/index.md b/docs/sources/datasources/mssql/query-editor/index.md index e43ca6d7e0f02..51622c2a0257e 100644 --- a/docs/sources/datasources/mssql/query-editor/index.md +++ b/docs/sources/datasources/mssql/query-editor/index.md @@ -120,6 +120,8 @@ To filter on more columns, click the plus (`+`) button to the right of the condi To remove a filter, click the `x` button next to that filter's dropdown. +After selecting a date type column, you can choose Macros from the operators list and select timeFilter which will add the $\_\_timeFilter macro to the query with the selected date column. + ### Group results To group results by column, toggle the **Group** switch at the top of the editor. diff --git a/docs/sources/datasources/mysql/_index.md b/docs/sources/datasources/mysql/_index.md index 985653e5f9b00..ae6e6eefdba55 100644 --- a/docs/sources/datasources/mysql/_index.md +++ b/docs/sources/datasources/mysql/_index.md @@ -201,10 +201,17 @@ Add further value columns by clicking the plus button and another column dropdow ### Filter data (WHERE) -To add a filter, flip the switch at the top of the editor. -Using the first dropdown, select if all the filters need to match (AND) or if only one of the filters needs to match (OR). +To add a filter, toggle the **Filter** switch at the top of the editor. +This reveals a **Filter by column value** section with two dropdown selectors. -To add more columns to filter on use the plus button. +Use the first dropdown to choose whether all of the filters need to match (`AND`), or if only one of the filters needs to match (`OR`). +Use the second dropdown to choose a filter. + +To filter on more columns, click the plus (`+`) button to the right of the condition dropdown. + +To remove a filter, click the `x` button next to that filter's dropdown. + +After selecting a date type column, you can choose Macros from the operators list and select timeFilter which will add the $\_\_timeFilter macro to the query with the selected date column. ### Group By diff --git a/docs/sources/datasources/postgres/_index.md b/docs/sources/datasources/postgres/_index.md index 53bc8b58173ea..a569158902533 100644 --- a/docs/sources/datasources/postgres/_index.md +++ b/docs/sources/datasources/postgres/_index.md @@ -114,10 +114,17 @@ Add further value columns by clicking the plus button and another column dropdow ### Filter data (WHERE) -To add a filter, flip the switch at the top of the editor. -Using the first dropdown, select if all the filters need to match (AND) or if only one of the filters needs to match (OR). +To add a filter, toggle the **Filter** switch at the top of the editor. +This reveals a **Filter by column value** section with two dropdown selectors. -To add more columns to filter on use the plus button. +Use the first dropdown to choose whether all of the filters need to match (`AND`), or if only one of the filters needs to match (`OR`). +Use the second dropdown to choose a filter. + +To filter on more columns, click the plus (`+`) button to the right of the condition dropdown. + +To remove a filter, click the `x` button next to that filter's dropdown. + +After selecting a date type column, you can choose Macros from the operators list and select timeFilter which will add the $\_\_timeFilter macro to the query with the selected date column. ### Group By diff --git a/docs/sources/datasources/prometheus/_index.md b/docs/sources/datasources/prometheus/_index.md index 5029e2f3cc03d..298320dd8aa94 100644 --- a/docs/sources/datasources/prometheus/_index.md +++ b/docs/sources/datasources/prometheus/_index.md @@ -28,7 +28,7 @@ For instructions on how to add a data source to Grafana, refer to the [administr Only users with the organization `administrator` role can add data sources and edit existing data sources. Administrators can also [configure the data source via YAML](#provision-the-data-source) with Grafana's provisioning system. -Once you've added the Prometheus data source, you can [configure it][configure-prometheus-data-source] so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards][build-dashboards], use [Explore][explore], and [annotate visualizations]({{< relref "./query-editor#apply-annotations" >}}). +Once you've added the Prometheus data source, you can [configure it][configure-prometheus-data-source] so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards][build-dashboards], use [Explore][explore], and [annotate visualizations][annotate visualizations]. The following guides will help you get started with the Prometheus data source: @@ -196,4 +196,8 @@ The Prometheus data source can be configured to disable recording rules under th [set-up-grafana-monitoring]: "/docs/grafana/ -> /docs/grafana//setup-grafana/set-up-grafana-monitoring" [set-up-grafana-monitoring]: "/docs/grafana-cloud/ -> /docs/grafana//setup-grafana/set-up-grafana-monitoring" + +[annotate visualizations]: "/docs/grafana/ -> /docs/grafana//dashboards/build-dashboards/annotate-visualizations" +[annotate visualizations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/dashboards/build-dashboards/annotate-visualizations" + {{% /docs/reference %}} diff --git a/docs/sources/datasources/tempo/configure-tempo-data-source.md b/docs/sources/datasources/tempo/configure-tempo-data-source.md index 8cdc4264cb47b..caaa3f76aa77b 100644 --- a/docs/sources/datasources/tempo/configure-tempo-data-source.md +++ b/docs/sources/datasources/tempo/configure-tempo-data-source.md @@ -41,11 +41,6 @@ You can also configure settings specific to the Tempo data source. These options ![Trace to logs settings](/media/docs/tempo/tempo-trace-to-logs-9-4.png) -{{% admonition type="note" %}} -Available in Grafana v7.4 and higher. -If you use Grafana Cloud, open a [support ticket in the Cloud Portal](/profile/org#support) to access this feature. -{{% /admonition %}} - The **Trace to logs** setting configures the [trace to logs feature][explore-trace-integration] that is available when you integrate Grafana with Tempo. There are two ways to configure the trace to logs feature: @@ -113,6 +108,8 @@ If you use Grafana Cloud, open a [support ticket in the Cloud Portal](/profile/o The **Trace to metrics** setting configures the [trace to metrics feature](/blog/2022/08/18/new-in-grafana-9.1-trace-to-metrics-allows-users-to-navigate-from-a-trace-span-to-a-selected-data-source/) available when integrating Grafana with Tempo. +{{< youtube id="TkapvLeMMpc" >}} + To configure trace to metrics: 1. Select the target data source from the drop-down list. @@ -133,6 +130,12 @@ Each linked query consists of: Interpolate tags using the `$__tags` keyword. For example, when you configure the query `requests_total{$__tags}`with the tags `k8s.pod=pod` and `cluster`, the result looks like `requests_total{pod="nginx-554b9", cluster="us-east-1"}`. +## Trace to profiles + +[//]: # 'Shared content for Trace to profiles in the Tempo data source' + +{{< docs/shared source="grafana" lookup="datasources/tempo-traces-to-profiles.md" leveloffset="+1" version="" >}} + ## Service Graph The **Service Graph** setting configures the [Service Graph](/docs/tempo/latest/metrics-generator/service_graphs/enable-service-graphs/) feature. diff --git a/docs/sources/datasources/testdata/_index.md b/docs/sources/datasources/testdata/_index.md index fbfa774b291e2..935cbb96cbb85 100644 --- a/docs/sources/datasources/testdata/_index.md +++ b/docs/sources/datasources/testdata/_index.md @@ -114,3 +114,28 @@ That makes it much easier for the developers to replicate and solve your issue. [panels-visualizations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations" [panels-visualizations]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations" {{% /docs/reference %}} + +## Use a custom version of TestData + +{{% admonition type="note" %}} +This feature is experimental and requires Grafana version 10.3.0 or later. +{{% /admonition %}} + +If you want to use a version of TestData different from the one shipped with Grafana, follow these steps: + +1. Enable the [feature toggle](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles/) `externalCorePlugins`. +1. Set the configuration field `as_external` for the plugin to `true`. An example configuration would be: + + ```ini + [feature_toggles] + externalCorePlugins = true + + [plugin.grafana-testdata-datasource] + as_external = true + ``` + +1. Restart Grafana. + +These settings, if enabled, allow you to to install TestData as an external plugin and manage its lifecycle independently of Grafana. + +With the feature toggle disabled (default) TestData can still be installed as an external plugin, but it has no effect as the bundled, Core version of TestData is already installed and takes precedence. diff --git a/docs/sources/developers/angular_deprecation/angular-plugins.md b/docs/sources/developers/angular_deprecation/angular-plugins.md index d27400acfd81e..be32d807fd807 100644 --- a/docs/sources/developers/angular_deprecation/angular-plugins.md +++ b/docs/sources/developers/angular_deprecation/angular-plugins.md @@ -20,7 +20,9 @@ The use of AngularJS in Grafana has been [deprecated]({{< relref "../angular_dep This page is to help users of Grafana understand how they might be impacted by the removal of Angular support, and whether a migration option exists. -It lists the latest versions of plugins currently available in the [Plugins Catalog](https://grafana.com/plugins) which depend on Angular, and will stop working when Angular support is removed from Grafana. The list will be updated as more plugins migrate to React or offer migration advice. +It lists the latest versions of plugins _currently available_ in the Grafana [plugin catalog](https://grafana.com/plugins) which depend on Angular, and will stop working when Angular support is removed from Grafana. The list will be updated as more plugins migrate to React or offer migration advice. + +Plugins which have been [deprecated](/legal/plugin-deprecation/) will _not_ be listed. Generally, we advise users to migrate away from deprecated plugins as they will not be updated and may not function in current or future versions of Grafana. {{% admonition type="note" %}} We advise you to ensure you are running the latest version of plugins, as previous releases of plugins not listed here may still require AngularJS. @@ -48,30 +50,12 @@ Guidance on migrating a plugin to React can be found in our [migration guide](/d ## Apps -### [BelugaCDN](https://grafana.com/grafana/plugins/belugacdn-app) - -Latest Version: 1.2.1 | Signature: Commercial | Last Updated: 2023 - -> [Migration issue](https://github.com/belugacdn/grafana-belugacdn-app/issues/7) has been raised. - -{{% admonition type="warning" %}} -Lack of recent activity in the [project repository](https://github.com/belugacdn/grafana-belugacdn-app) in the past 7 years suggests project _may_ not be actively maintained. -{{% /admonition %}} - ### [Bosun](https://grafana.com/grafana/plugins/bosun-app) Latest Version: 0.0.29 | Signature: Community | Last Updated: 2023 > [Migration issue](https://github.com/bosun-monitor/bosun-grafana-app/issues/63) has been raised. -### [Cloudflare Grafana App](https://grafana.com/grafana/plugins/cloudflare-app/) - -Latest Version: 0.2.4 | Signature: Commercial | Last Updated: 2022 - -{{% admonition type="warning" %}} -Guidance from the developer: This app is deprecated and will no longer be updated after December 31, 2023. Please consider using the [Cloudflare] Dashboard(https://dash.cloudflare.com/?to=/:account/:zone/analytics/dns) or [DNS Analytics API](https://developers.cloudflare.com/api/operations/dns-analytics-table) instead. -{{% /admonition %}} - ### [GLPI](https://grafana.com/grafana/plugins/ddurieux-glpi-app) Latest Version: 1.3.1 | Signature: Community | Last Updated: 2021 @@ -96,20 +80,6 @@ Latest Version: 1.6.2 | Signature: Grafana | Last Updated: 2023 Plugin should continue to work even if Angular is disabled, and a full removal of Angular related code is planned. {{% /admonition %}} -### [OpenNMS Helm](https://grafana.com/grafana/plugins/opennms-helm-app) - -Latest Version: 8.0.5 | Signature: Community | Last Updated: 2023 - -> **Migration available - plugin superseded:** The plugin has effectively been replaced with a [new plugin](https://grafana.com/grafana/plugins/opennms-opennms-app/) based on React. - -### [Percona](https://grafana.com/grafana/plugins/percona-percona-app/) - -Latest Version: 1.0.1 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -[Project repository](https://github.com/percona/grafana-app) was archived on June 12, 2020. -{{% /admonition %}} - ### [Stagemonitor Elasticsearch](https://grafana.com/grafana/plugins/stagemonitor-elasticsearch-app) Latest Version: 0.83.3 | Signature: Community | Last Updated: 2021 @@ -130,12 +100,6 @@ Lack of recent activity in the [project repository](https://github.com/raintank/ ## Datasources -### [Druid](https://grafana.com/grafana/plugins/abhisant-druid-datasource/) - -Latest Version: v0.0.6 | Signature: Community | Last Updated: 2021 - -> **Migration available - plugin superseded:** The original plugin only claims support for Grafana v4.x.x, it was replaced with a [new plugin](https://grafana.com/grafana/plugins/grafadruid-druid-datasource/) based on React. - ### [Akumuli](https://grafana.com/grafana/plugins/akumuli-datasource/) Latest Version: 1.3.12 | Signature: Community | Last Updated: 2021 @@ -148,18 +112,6 @@ Latest Version: 1.3.12 | Signature: Community | Last Updated: 2021 Lack of recent activity in the [project repository](https://github.com/akumuli/Akumuli/) in the past 3 years suggests project _may_ not be actively maintained. {{% /admonition %}} -### [DarkSky](https://grafana.com/grafana/plugins/andig-darksky-datasource/) - -Latest Version: 1.0.2 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -[Project repository](https://github.com/andig/grafana-darksky) was archived on September 27, 2022. -{{% /admonition %}} - -{{% admonition type="warning" %}} -Apple removed support for the DarkSky API on March 31, 2023 - [source](https://support.apple.com/en-us/HT213526). -{{% /admonition %}} - ### [Finance](https://grafana.com/grafana/plugins/ayoungprogrammer-finance-datasource/) Latest Version: 1.0.1 | Signature: Community | Last Updated: 2021 @@ -172,16 +124,6 @@ Latest Version: 1.0.1 | Signature: Community | Last Updated: 2021 Lack of recent activity in the [project repository](https://github.com/ayoungprogrammer/grafana-finance) in the past 6 years suggests project _may_ not be actively maintained. {{% /admonition %}} -### [Prometheus AlertManager](https://grafana.com/grafana/plugins/camptocamp-prometheus-alertmanager-datasource/) - -Latest Version: 1.2.1 | Signature: Community | Last Updated: 2022 - -{{% admonition type="warning" %}} -Lack of recent activity in the [project repository](https://github.com/camptocamp/grafana-prometheus-alertmanager-datasource) in the past year suggests project _may_ not be actively maintained. -{{% /admonition %}} - -> **Migration available - potential alternative:** Grafana includes an AlertManager data source as a Core plugin. - ### [Chaos Mesh](https://grafana.com/grafana/plugins/chaosmeshorg-datasource/) Latest Version: 2.2.3 | Signature: Community | Last Updated: 2022 @@ -310,18 +252,6 @@ Latest Version: 1.1.2 | Signature: Community | Last Updated: 2021 Lack of recent activity in the [project repository](https://github.com/hawkular/hawkular-grafana-datasource) in the past 5 years suggests project _may_ not be actively maintained. {{% /admonition %}} -### [Humio](https://grafana.com/grafana/plugins/humio-datasource/) - -Latest Version: 3.3.1 | Signature: Commercial | Last Updated: 2022 - -### [IBM APM](https://grafana.com/grafana/plugins/ibm-apm-datasource/) - -Latest Version: 0.9.1 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -Lack of recent activity in the [project repository](https://github.com/rafal-szypulka/grafana-ibm-apm) in the past 3 years suggests project _may_ not be actively maintained. -{{% /admonition %}} - ### [PRTG](https://grafana.com/grafana/plugins/jasonlashua-prtg-datasource/) Latest Version: 4.0.4 | Signature: Community | Last Updated: 2021 @@ -334,22 +264,6 @@ Lack of recent activity in the [project repository](https://github.com/neuralfra Unmaintained since 2017 - [source](https://github.com/neuralfraud/grafana-prtg/wiki). {{% /admonition %}} -### [LinkSmart HDS Datasource](https://grafana.com/grafana/plugins/linksmart-hds-datasource/) - -Latest Version: 1.0.2 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -[Project repository](https://github.com/linksmart/grafana-hds-datasource) was archived on April 4th, 2022, and is no longer maintained. -{{% /admonition %}} - -### [LinkSmart SensorThings](https://grafana.com/grafana/plugins/linksmart-sensorthings-datasource/) - -Latest Version: 1.3.1 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -[Project repository](https://github.com/linksmart/grafana-sensorthings-datasource) was archived on April 4th, 2022, and is no longer maintained. -{{% /admonition %}} - ### [Monasca](https://grafana.com/grafana/plugins/monasca-datasource/) Latest Version: 1.0.1 | Signature: Community | Last Updated: 2021 @@ -386,20 +300,6 @@ Latest Version: 0.0.3 | Signature: Community | Last Updated: 2021 Lack of recent activity in the [project repository](https://github.com/NatelEnergy/natel-usgs-datasource) in the past 3 years suggests project _may_ not be actively maintained. {{% /admonition %}} -### [ntopng](https://grafana.com/grafana/plugins/ntop-ntopng-datasource/) - -Latest Version: 1.0.1 | Signature: Community | Last Updated: 2021 - -> **Migration available - plugin superseded:** this plugin was [discontinued in favour of the InfluxDB data source](https://github.com/ntop/ntopng-grafana-datasource) - a Core plugin included in Grafana, additional guidance is available [here](https://www.ntop.org/guides/ntopng/basic_concepts/timeseries.html#influxdb-driver). - -### [Warp 10](https://grafana.com/grafana/plugins/ovh-warp10-datasource/) - -Latest Version: 2.2.1 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -[Project repository](https://github.com/ovh/ovh-warp10-datasource) was archived on March 22nd, 2023 and is no longer maintained. -{{% /admonition %}} - ### [KapacitorSimpleJson](https://grafana.com/grafana/plugins/paytm-kapacitor-datasource/) Latest Version: 0.1.3 | Signature: Community | Last Updated: 2021 @@ -446,10 +346,6 @@ Latest Version: 1.2.3 | Signature: Community | Last Updated: 2021 Lack of recent activity in the [project repository](https://github.com/netxms/grafana) in the past 2 years suggests project _may_ not be actively maintained. {{% /admonition %}} -### [Shoreline Data Source](https://grafana.com/grafana/plugins/shorelinesoftware-shoreline-datasource/) - -Latest Version: 1.1.0 | Signature: Commercial | Last Updated: 6 months ago - ### [Sidewinder](https://grafana.com/grafana/plugins/sidewinder-datasource/) Latest Version: 0.2.1 | Signature: Community | Last Updated: 2021 @@ -470,22 +366,6 @@ Lack of recent activity in the [project repository](https://github.com/skydive-p Issues suggest the entire project, not just the plugin, may be abandoned - [source](https://github.com/skydive-project/skydive/issues/2417). {{% /admonition %}} -### [Heroic](https://grafana.com/grafana/plugins/spotify-heroic-datasource/) - -Latest Version: 0.0.2 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -[Plugin](https://github.com/spotify/spotify-heroic-datasource) and [Heroic](https://github.com/spotify/heroic) were both archived on April 17th, 2021 and March 27th, 2021 respectively. -{{% /admonition %}} - -### [Heroic](https://grafana.com/grafana/plugins/udoprog-heroic-datasource/) - -Latest Version: 0.1.1 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -[Plugin](https://github.com/udoprog/udoprog-heroic-datasource) and [Heroic](https://github.com/spotify/heroic) were both archived on October 16th, 2022 and March 27th, 2021 respectively. -{{% /admonition %}} - ### [Altinity plugin for ClickHouse](https://grafana.com/grafana/plugins/vertamedia-clickhouse-datasource/) Latest Version: 2.5.3 | Signature: Community | Last Updated: 2022 @@ -499,7 +379,7 @@ The [migration issue](https://github.com/Altinity/clickhouse-grafana/issues/475) Latest Version: 0.2.2 | Signature: Community | Last Updated: 2021 {{% admonition type="warning" %}} -Lack of recent activity in the [project repository](https://github.com/skydive-project/skydive-grafana-datasource) in the past year suggests project _may_ not be actively maintained. +Lack of recent activity in the [project repository](https://github.com/xginn8/grafana-pagerduty) in the past year suggests project _may_ not be actively maintained. {{% /admonition %}} {{% admonition type="warning" %}} @@ -582,14 +462,6 @@ Latest Version: 1.0.3 | Signature: Community | Last Updated: 2021 Migration to React is planned - [issue](https://github.com/briangann/grafana-datatable-panel/issues/174). {{% /admonition %}} -### [D3 Gauge](https://grafana.com/grafana/plugins/briangann-gauge-panel/) - -Latest Version: 0.0.9 | Signature: Community | Last Updated: 2021 - -{{% admonition type="note" %}} -Migration to React is a planned [update](https://github.com/briangann/grafana-gauge-panel/issues/740). -{{% /admonition %}} - ### [GeoLoop](https://grafana.com/grafana/plugins/citilogics-geoloop-panel/) Latest Version: 1.1.2 | Signature: Community | Last Updated: 2021 @@ -784,12 +656,6 @@ Latest Version: 0.1.0 | Signature: Community | Last Updated: 2021 Lack of recent activity in the [project repository](https://github.com/ryantxu/ajax-panel) in the past 2 years suggests project _may_ not be actively maintained. {{% /admonition %}} -### [Annotation List](https://grafana.com/grafana/plugins/ryantxu-annolist-panel/) - -Latest Version: 0.0.2 | Signature: Community | Last Updated: 2021 - -> **Migration available - plugin superseded:** [Project repository](https://github.com/ryantxu/annotations-panel) for the plugin was archived on July 13th, 2019 in favour of native [annotations]({{< relref "../../panels-visualizations/visualizations/annotations/" >}}). - ### [3D Globe Panel](https://grafana.com/grafana/plugins/satellogic-3d-globe-panel/) Latest Version: 0.1.1 | Signature: Community | Last Updated: 2021 @@ -808,14 +674,6 @@ Lack of recent activity in the [project repository](https://github.com/savantly- > **Migration available - potential alternative:** other Heatmap panels exist including natively in Grafana - [learn more]({{< relref "../../panels-visualizations/visualizations/heatmap/" >}}). -### [SCADAvis Synoptic Panel](https://grafana.com/grafana/plugins/scadavis-synoptic-panel/) - -Latest Version: 1.0.5 | Signature: Community | Last Updated: 2021 - -{{% admonition type="warning" %}} -Lack of recent activity in the [project repository](https://github.com/riclolsen/scadavis-synoptic-panel) in the past 3 years suggests project _may_ not be actively maintained. -{{% /admonition %}} - ### [TrafficLight](https://grafana.com/grafana/plugins/smartmakers-trafficlight-panel/) Latest Version: 1.0.1 | Signature: Community | Last Updated: 2021 diff --git a/docs/sources/developers/http_api/_index.md b/docs/sources/developers/http_api/_index.md index aa01c6d188612..e986b3f1a56f4 100644 --- a/docs/sources/developers/http_api/_index.md +++ b/docs/sources/developers/http_api/_index.md @@ -27,7 +27,7 @@ Since version 8.4, HTTP API details are [specified](https://editor.swagger.io/?u Starting from version 9.1, there is also a [OpenAPI v3 specification](https://editor.swagger.io/?url=https://raw.githubusercontent.com/grafana/grafana/main/public/openapi3.json) (generated by the v2 one). -Users can browser and try out both via the Swagger UI editor (served by the grafana server) by navigating to `/swagger-ui` and `/openapi3` respectively. +Users can browser and try out both via the Swagger UI editor (served by the grafana server) by navigating to `/swagger`. ## Authenticating API requests @@ -47,7 +47,7 @@ curl http://admin:admin@localhost:3000/api/org ### Service Account Token -To create a service account token, click on **Administration** in the left-side menu, and then **Service Accounts**. +To create a service account token, click on **Administration** in the left-side menu, click **Users and access**, then **Service Accounts**. For more information on how to use service account tokens, refer to the [Service Accounts]({{< relref "../../administration/service-accounts/" >}}) documentation. You use the token in all requests in the `Authorization` header, like this: diff --git a/docs/sources/developers/http_api/sso-settings.md b/docs/sources/developers/http_api/sso-settings.md new file mode 100644 index 0000000000000..25d337104a842 --- /dev/null +++ b/docs/sources/developers/http_api/sso-settings.md @@ -0,0 +1,63 @@ +--- +aliases: + - ../../http_api/sso-settings/ + - ../../http_api/ssosettings/ +canonical: /docs/grafana/latest/developers/http_api/sso-settings/ +description: Grafana SSO Settings API +keywords: + - grafana + - http + - documentation + - api + - sso + - sso-settings +labels: + products: + - enterprise + - oss +title: SSO Settings API +--- + +# SSO Settings API + +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. + +The API can be used to create, update, delete, get, and list SSO Settings. + +## Delete SSO Settings + +`DELETE /api/v1/sso-settings/:provider` + +Deletes an existing SSO Settings entry for a provider. + +**Required permissions** + +See note in the [introduction]({{< ref "#sso-settings" >}}) for an explanation. + +| Action | Scope | +| ---------------- | ---------------------------- | +| `settings:write` | `settings:auth.{provider}:*` | + +**Example Request**: + +```http +DELETE /api/v1/sso-settings/azuread HTTP/1.1 +Accept: application/json +Content-Type: application/json +Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk +``` + +**Example Response**: + +```http +HTTP/1.1 204 +Content-Type: application/json +``` + +Status Codes: + +- **204** – SSO Settings deleted +- **400** – Bad Request +- **401** – Unauthorized +- **403** – Access Denied +- **404** – SSO Settings not found diff --git a/docs/sources/developers/kinds/composable/bargauge/panelcfg/schema-reference.md b/docs/sources/developers/kinds/composable/bargauge/panelcfg/schema-reference.md index 9109f367bd40a..b14e5954f9980 100644 --- a/docs/sources/developers/kinds/composable/bargauge/panelcfg/schema-reference.md +++ b/docs/sources/developers/kinds/composable/bargauge/panelcfg/schema-reference.md @@ -29,10 +29,12 @@ It extends [SingleStatBaseOptions](#singlestatbaseoptions). | Property | Type | Required | Default | Description | |-----------------|-------------------------------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------| | `displayMode` | string | **Yes** | | Enum expressing the possible display modes
    for the bar gauge component of Grafana UI
    Possible values are: `basic`, `lcd`, `gradient`. | -| `minVizHeight` | uint32 | **Yes** | `10` | | -| `minVizWidth` | uint32 | **Yes** | `0` | | +| `maxVizHeight` | uint32 | **Yes** | `300` | | +| `minVizHeight` | uint32 | **Yes** | `75` | | +| `minVizWidth` | uint32 | **Yes** | `75` | | | `namePlacement` | string | **Yes** | | Allows for the bar gauge name to be placed explicitly
    Possible values are: `auto`, `top`, `left`. | | `showUnfilled` | boolean | **Yes** | `true` | | +| `sizing` | string | **Yes** | | Allows for the bar gauge size to be set explicitly
    Possible values are: `auto`, `manual`. | | `valueMode` | string | **Yes** | | Allows for the table cell gauge display type to set the gauge mode.
    Possible values are: `color`, `text`, `hidden`. | | `orientation` | string | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs
    Possible values are: `auto`, `vertical`, `horizontal`. | | `reduceOptions` | [ReduceDataOptions](#reducedataoptions) | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs | diff --git a/docs/sources/developers/kinds/composable/gauge/panelcfg/schema-reference.md b/docs/sources/developers/kinds/composable/gauge/panelcfg/schema-reference.md index be536fd6df690..2015674854adb 100644 --- a/docs/sources/developers/kinds/composable/gauge/panelcfg/schema-reference.md +++ b/docs/sources/developers/kinds/composable/gauge/panelcfg/schema-reference.md @@ -28,10 +28,11 @@ It extends [SingleStatBaseOptions](#singlestatbaseoptions). | Property | Type | Required | Default | Description | |------------------------|-------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------| -| `minVizHeight` | uint32 | **Yes** | `75` | | -| `minVizWidth` | uint32 | **Yes** | `75` | | +| `minVizHeight` | uint32 | **Yes** | `200` | | +| `minVizWidth` | uint32 | **Yes** | `200` | | | `showThresholdLabels` | boolean | **Yes** | `false` | | | `showThresholdMarkers` | boolean | **Yes** | `true` | | +| `sizing` | string | **Yes** | | Allows for the bar gauge size to be set explicitly
    Possible values are: `auto`, `manual`. | | `orientation` | string | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs
    Possible values are: `auto`, `vertical`, `horizontal`. | | `reduceOptions` | [ReduceDataOptions](#reducedataoptions) | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs | | `text` | [VizTextDisplayOptions](#viztextdisplayoptions) | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs | diff --git a/docs/sources/developers/kinds/composable/grafanapyroscope/dataquery/schema-reference.md b/docs/sources/developers/kinds/composable/grafanapyroscope/dataquery/schema-reference.md index f65e65989ffcd..3b7a95d56c6c4 100644 --- a/docs/sources/developers/kinds/composable/grafanapyroscope/dataquery/schema-reference.md +++ b/docs/sources/developers/kinds/composable/grafanapyroscope/dataquery/schema-reference.md @@ -28,5 +28,6 @@ title: GrafanaPyroscopeDataQuery kind | `hide` | boolean | No | | true if query is disabled (ie should not be returned to the dashboard)
    Note this does not always imply that the query should not be executed since
    the results from a hidden query may be used as the input to other queries (SSE etc) | | `maxNodes` | integer | No | | Sets the maximum number of nodes in the flamegraph. | | `queryType` | string | No | | Specify the query flavor
    TODO make this required and give it a default | +| `spanSelector` | string[] | No | | Specifies the query span selectors. | diff --git a/docs/sources/developers/kinds/composable/heatmap/panelcfg/schema-reference.md b/docs/sources/developers/kinds/composable/heatmap/panelcfg/schema-reference.md index 89412c56f27d2..4427b6c99e9c4 100644 --- a/docs/sources/developers/kinds/composable/heatmap/panelcfg/schema-reference.md +++ b/docs/sources/developers/kinds/composable/heatmap/panelcfg/schema-reference.md @@ -124,10 +124,11 @@ Controls legend options Controls tooltip options -| Property | Type | Required | Default | Description | -|--------------|---------|----------|---------|----------------------------------------------------------------| -| `show` | boolean | **Yes** | | Controls if the tooltip is shown | -| `yHistogram` | boolean | No | | Controls if the tooltip shows a histogram of the y-axis values | +| Property | Type | Required | Default | Description | +|------------------|---------|----------|---------|----------------------------------------------------------------| +| `show` | boolean | **Yes** | | Controls if the tooltip is shown | +| `showColorScale` | boolean | No | | Controls if the tooltip shows a color scale in header | +| `yHistogram` | boolean | No | | Controls if the tooltip shows a histogram of the y-axis values | ### Options diff --git a/docs/sources/developers/kinds/composable/stat/panelcfg/schema-reference.md b/docs/sources/developers/kinds/composable/stat/panelcfg/schema-reference.md index e83f6c0b6084e..b5e134bc42687 100644 --- a/docs/sources/developers/kinds/composable/stat/panelcfg/schema-reference.md +++ b/docs/sources/developers/kinds/composable/stat/panelcfg/schema-reference.md @@ -32,6 +32,7 @@ It extends [SingleStatBaseOptions](#singlestatbaseoptions). | `graphMode` | string | **Yes** | | TODO docs
    Possible values are: `none`, `line`, `area`. | | `justifyMode` | string | **Yes** | | TODO docs
    Possible values are: `auto`, `center`. | | `textMode` | string | **Yes** | | TODO docs
    Possible values are: `auto`, `value`, `value_and_name`, `name`, `none`. | +| `wideLayout` | boolean | **Yes** | `true` | | | `orientation` | string | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs
    Possible values are: `auto`, `vertical`, `horizontal`. | | `reduceOptions` | [ReduceDataOptions](#reducedataoptions) | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs | | `text` | [VizTextDisplayOptions](#viztextdisplayoptions) | No | | *(Inherited from [SingleStatBaseOptions](#singlestatbaseoptions))*
    TODO docs | diff --git a/docs/sources/developers/kinds/core/dashboard/schema-reference.md b/docs/sources/developers/kinds/core/dashboard/schema-reference.md index 42b36f9f4865e..e8fb56b1c183d 100644 --- a/docs/sources/developers/kinds/core/dashboard/schema-reference.md +++ b/docs/sources/developers/kinds/core/dashboard/schema-reference.md @@ -88,7 +88,7 @@ extraFields is reserved for any fields that are pulled from the API server metad | `tags` | string[] | No | | Tags associated with dashboard. | | `templating` | [object](#templating) | No | | Configured template variables | | `time` | [object](#time) | No | | Time range for dashboard.
    Accepted values are relative time strings like {from: 'now-6h', to: 'now'} or absolute time strings like {from: '2020-07-10T08:00:00.000Z', to: '2020-07-10T14:00:00.000Z'}. | -| `timepicker` | [object](#timepicker) | No | | Configuration of the time picker shown at the top of a dashboard. | +| `timepicker` | [TimePickerConfig](#timepickerconfig) | No | | Time picker configuration
    It defines the default config for the time picker and the refresh picker for the specific dashboard. | | `timezone` | string | No | `browser` | Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc". | | `title` | string | No | | Title of dashboard. | | `uid` | string | No | | Unique dashboard identifier that can be generated by anyone. string (8-40) | @@ -166,7 +166,7 @@ Links with references to other dashboards or external resources | `title` | string | **Yes** | | Title to display with the link | | `tooltip` | string | **Yes** | | Tooltip to display when the user hovers their mouse over it | | `type` | string | **Yes** | | Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource)
    Possible values are: `link`, `dashboards`. | -| `url` | string | **Yes** | | Link URL. Only required/valid if the type is link | +| `url` | string | No | | Link URL. Only required/valid if the type is link | ### Snapshot @@ -190,11 +190,22 @@ Sensitive information stripped: queries (metric, template,annotation) and panel | `userId` | uint32 | **Yes** | | user id of the snapshot creator | | `url` | string | No | | url of the snapshot, if snapshot was shared internally | +### TimePickerConfig + +Time picker configuration +It defines the default config for the time picker and the refresh picker for the specific dashboard. + +| Property | Type | Required | Default | Description | +|---------------------|----------|----------|---------------------------------------|---------------------------------------------------------------------------------------------------| +| `hidden` | boolean | **Yes** | `false` | Whether timepicker is visible or not. | +| `refresh_intervals` | string[] | **Yes** | `[5s 10s 30s 1m 5m 15m 30m 1h 2h 1d]` | Interval options available in the refresh picker dropdown. | +| `time_options` | string[] | **Yes** | `[5m 15m 1h 6h 12h 24h 2d 7d 30d]` | Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. | + ### Panels -| Property | Type | Required | Default | Description | -|----------|-------------------------------------------------------------------------------------------------------------|----------|---------|-------------| -| `object` | Possible types are: [](#), [RowPanel](#rowpanel), [GraphPanel](#graphpanel), [HeatmapPanel](#heatmappanel). | | | +| Property | Type | Required | Default | Description | +|----------|---------------------------------------------------|----------|---------|-------------| +| `object` | Possible types are: [](#), [RowPanel](#rowpanel). | | | ### DataTransformerConfig @@ -392,26 +403,6 @@ in panel plugin schemas. | `id` | string | **Yes** | `` | | | `value` | | No | | | -### GraphPanel - -Support for legacy graph panel. -@deprecated this a deprecated panel type - -| Property | Type | Required | Default | Description | -|----------|-------------------|----------|---------|----------------------------------------------------| -| `type` | string | **Yes** | | Possible values are: `graph`. | -| `legend` | [object](#legend) | No | | @deprecated this is part of deprecated graph panel | - -### Legend - -@deprecated this is part of deprecated graph panel - -| Property | Type | Required | Default | Description | -|------------|---------|----------|---------|-------------| -| `show` | boolean | **Yes** | `true` | | -| `sortDesc` | boolean | No | | | -| `sort` | string | No | | | - ### GridPos Position and dimensions of a panel in the grid @@ -424,15 +415,6 @@ Position and dimensions of a panel in the grid | `y` | uint32 | **Yes** | `0` | Panel y. The y coordinate is the number of rows from the top edge of the grid | | `static` | boolean | No | | Whether the panel is fixed within the grid. If true, the panel will not be affected by other panels' interactions | -### HeatmapPanel - -Support for legacy heatmap panel. -@deprecated this a deprecated panel type - -| Property | Type | Required | Default | Description | -|----------|--------|----------|---------|---------------------------------| -| `type` | string | **Yes** | | Possible values are: `heatmap`. | - ### LibraryPanelRef A library panel is a reusable panel that you can use in any dashboard. @@ -444,6 +426,56 @@ Library panels streamline reuse of panels across multiple dashboards. | `name` | string | **Yes** | | Library panel name | | `uid` | string | **Yes** | | Library panel uid | +### Panel + +Dashboard panels are the basic visualization building blocks. + +| Property | Type | Required | Default | Description | +|--------------------|---------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `type` | string | **Yes** | | The panel plugin type id. This is used to find the plugin to display the panel.
    Constraint: `length >=1`. | +| `datasource` | [DataSourceRef](#datasourceref) | No | | Ref to a DataSource instance | +| `description` | string | No | | Panel description. | +| `fieldConfig` | [FieldConfigSource](#fieldconfigsource) | No | | The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.
    Each column within this structure is called a field. A field can represent a single time series or table column.
    Field options allow you to change how the data is displayed in your visualizations. | +| `gridPos` | [GridPos](#gridpos) | No | | Position and dimensions of a panel in the grid | +| `hideTimeOverride` | boolean | No | | Controls if the timeFrom or timeShift overrides are shown in the panel header | +| `id` | uint32 | No | | Unique identifier of the panel. Generated by Grafana when creating a new panel. It must be unique within a dashboard, but not globally. | +| `interval` | string | No | | The min time interval setting defines a lower limit for the $__interval and $__interval_ms variables.
    This value must be formatted as a number followed by a valid time
    identifier like: "40s", "3d", etc.
    See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options | +| `libraryPanel` | [LibraryPanelRef](#librarypanelref) | No | | A library panel is a reusable panel that you can use in any dashboard.
    When you make a change to a library panel, that change propagates to all instances of where the panel is used.
    Library panels streamline reuse of panels across multiple dashboards. | +| `links` | [DashboardLink](#dashboardlink)[] | No | | Panel links. | +| `maxDataPoints` | number | No | | The maximum number of data points that the panel queries are retrieving. | +| `maxPerRow` | number | No | | Option for repeated panels that controls max items per row
    Only relevant for horizontally repeated panels | +| `options` | [object](#options) | No | | It depends on the panel plugin. They are specified by the Options field in panel plugin schemas. | +| `pluginVersion` | string | No | | The version of the plugin that is used for this panel. This is used to find the plugin to display the panel and to migrate old panel configs. | +| `repeatDirection` | string | No | `h` | Direction to repeat in if 'repeat' is set.
    `h` for horizontal, `v` for vertical.
    Possible values are: `h`, `v`. | +| `repeat` | string | No | | Name of template variable to repeat for. | +| `tags` | string[] | No | | Tags for the panel. | +| `targets` | [Target](#target)[] | No | | Depends on the panel plugin. See the plugin documentation for details. | +| `timeFrom` | string | No | | Overrides the relative time range for individual panels,
    which causes them to be different than what is selected in
    the dashboard time picker in the top-right corner of the dashboard. You can use this to show metrics from different
    time periods or days on the same dashboard.
    The value is formatted as time operation like: `now-5m` (Last 5 minutes), `now/d` (the day so far),
    `now-5d/d`(Last 5 days), `now/w` (This week so far), `now-2y/y` (Last 2 years).
    Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
    See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options | +| `timeShift` | string | No | | Overrides the time range for individual panels by shifting its start and end relative to the time picker.
    For example, you can shift the time range for the panel to be two hours earlier than the dashboard time picker setting `2h`.
    Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
    See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options | +| `title` | string | No | | Panel title. | +| `transformations` | [DataTransformerConfig](#datatransformerconfig)[] | No | | List of transformations that are applied to the panel data before rendering.
    When there are multiple transformations, Grafana applies them in the order they are listed.
    Each transformation creates a result set that then passes on to the next transformation in the processing pipeline. | +| `transparent` | boolean | No | `false` | Whether to display the panel without a background. | + +### Target + +Schema for panel targets is specified by datasource +plugins. We use a placeholder definition, which the Go +schema loader either left open/as-is with the Base +variant of the Dashboard and Panel families, or filled +with types derived from plugins in the Instance variant. +When working directly from CUE, importers can extend this +type directly to achieve the same effect. + +| Property | Type | Required | Default | Description | +|----------|------|----------|---------|-------------| + +### Options + +It depends on the panel plugin. They are specified by the Options field in panel plugin schemas. + +| Property | Type | Required | Default | Description | +|----------|------|----------|---------|-------------| + ### RowPanel Row panel @@ -452,19 +484,13 @@ Row panel |--------------|---------------------------------|----------|---------|-----------------------------------------------------------------------------------------------------------------------------------------| | `collapsed` | boolean | **Yes** | `false` | Whether this row should be collapsed or not. | | `id` | uint32 | **Yes** | | Unique identifier of the panel. Generated by Grafana when creating a new panel. It must be unique within a dashboard, but not globally. | -| `panels` | [panels](#panels)[] | **Yes** | | List of panels in the row | +| `panels` | [Panel](#panel)[] | **Yes** | | List of panels in the row | | `type` | string | **Yes** | | The panel type
    Possible values are: `row`. | | `datasource` | [DataSourceRef](#datasourceref) | No | | Ref to a DataSource instance | | `gridPos` | [GridPos](#gridpos) | No | | Position and dimensions of a panel in the grid | | `repeat` | string | No | | Name of template variable to repeat for. | | `title` | string | No | | Row title | -### Panels - -| Property | Type | Required | Default | Description | -|----------|------------------------------------------------------------------------------------------------|----------|---------|-------------| -| `object` | Possible types are: [Panel](#panel), [GraphPanel](#graphpanel), [HeatmapPanel](#heatmappanel). | | | - ### Panel Dashboard panels are the basic visualization building blocks. @@ -483,7 +509,7 @@ Dashboard panels are the basic visualization building blocks. | `links` | [DashboardLink](#dashboardlink)[] | No | | Panel links. | | `maxDataPoints` | number | No | | The maximum number of data points that the panel queries are retrieving. | | `maxPerRow` | number | No | | Option for repeated panels that controls max items per row
    Only relevant for horizontally repeated panels | -| `options` | [object](#options) | No | | It depends on the panel plugin. They are specified by the Options field in panel plugin schemas. | +| `options` | [options](#options) | No | | It depends on the panel plugin. They are specified by the Options field in panel plugin schemas. | | `pluginVersion` | string | No | | The version of the plugin that is used for this panel. This is used to find the plugin to display the panel and to migrate old panel configs. | | `repeatDirection` | string | No | `h` | Direction to repeat in if 'repeat' is set.
    `h` for horizontal, `v` for vertical.
    Possible values are: `h`, `v`. | | `repeat` | string | No | | Name of template variable to repeat for. | @@ -562,66 +588,6 @@ For example, you can configure a special value mapping so that null values appea | `options` | [options](#options) | **Yes** | | | | `type` | string | **Yes** | | | -### Target - -Schema for panel targets is specified by datasource -plugins. We use a placeholder definition, which the Go -schema loader either left open/as-is with the Base -variant of the Dashboard and Panel families, or filled -with types derived from plugins in the Instance variant. -When working directly from CUE, importers can extend this -type directly to achieve the same effect. - -| Property | Type | Required | Default | Description | -|----------|------|----------|---------|-------------| - -### Options - -It depends on the panel plugin. They are specified by the Options field in panel plugin schemas. - -| Property | Type | Required | Default | Description | -|----------|------|----------|---------|-------------| - -### GraphPanel - -Support for legacy graph panel. -@deprecated this a deprecated panel type - -| Property | Type | Required | Default | Description | -|----------|-------------------|----------|---------|----------------------------------------------------| -| `type` | string | **Yes** | | Possible values are: `graph`. | -| `legend` | [legend](#legend) | No | | @deprecated this is part of deprecated graph panel | - -### Panel - -Dashboard panels are the basic visualization building blocks. - -| Property | Type | Required | Default | Description | -|--------------------|---------------------------------------------------|----------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `type` | string | **Yes** | | The panel plugin type id. This is used to find the plugin to display the panel.
    Constraint: `length >=1`. | -| `datasource` | [DataSourceRef](#datasourceref) | No | | Ref to a DataSource instance | -| `description` | string | No | | Panel description. | -| `fieldConfig` | [FieldConfigSource](#fieldconfigsource) | No | | The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results.
    Each column within this structure is called a field. A field can represent a single time series or table column.
    Field options allow you to change how the data is displayed in your visualizations. | -| `gridPos` | [GridPos](#gridpos) | No | | Position and dimensions of a panel in the grid | -| `hideTimeOverride` | boolean | No | | Controls if the timeFrom or timeShift overrides are shown in the panel header | -| `id` | uint32 | No | | Unique identifier of the panel. Generated by Grafana when creating a new panel. It must be unique within a dashboard, but not globally. | -| `interval` | string | No | | The min time interval setting defines a lower limit for the $__interval and $__interval_ms variables.
    This value must be formatted as a number followed by a valid time
    identifier like: "40s", "3d", etc.
    See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options | -| `libraryPanel` | [LibraryPanelRef](#librarypanelref) | No | | A library panel is a reusable panel that you can use in any dashboard.
    When you make a change to a library panel, that change propagates to all instances of where the panel is used.
    Library panels streamline reuse of panels across multiple dashboards. | -| `links` | [DashboardLink](#dashboardlink)[] | No | | Panel links. | -| `maxDataPoints` | number | No | | The maximum number of data points that the panel queries are retrieving. | -| `maxPerRow` | number | No | | Option for repeated panels that controls max items per row
    Only relevant for horizontally repeated panels | -| `options` | [options](#options) | No | | It depends on the panel plugin. They are specified by the Options field in panel plugin schemas. | -| `pluginVersion` | string | No | | The version of the plugin that is used for this panel. This is used to find the plugin to display the panel and to migrate old panel configs. | -| `repeatDirection` | string | No | `h` | Direction to repeat in if 'repeat' is set.
    `h` for horizontal, `v` for vertical.
    Possible values are: `h`, `v`. | -| `repeat` | string | No | | Name of template variable to repeat for. | -| `tags` | string[] | No | | Tags for the panel. | -| `targets` | [Target](#target)[] | No | | Depends on the panel plugin. See the plugin documentation for details. | -| `timeFrom` | string | No | | Overrides the relative time range for individual panels,
    which causes them to be different than what is selected in
    the dashboard time picker in the top-right corner of the dashboard. You can use this to show metrics from different
    time periods or days on the same dashboard.
    The value is formatted as time operation like: `now-5m` (Last 5 minutes), `now/d` (the day so far),
    `now-5d/d`(Last 5 days), `now/w` (This week so far), `now-2y/y` (Last 2 years).
    Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
    See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options | -| `timeShift` | string | No | | Overrides the time range for individual panels by shifting its start and end relative to the time picker.
    For example, you can shift the time range for the panel to be two hours earlier than the dashboard time picker setting `2h`.
    Note: Panel time overrides have no effect when the dashboard’s time range is absolute.
    See: https://grafana.com/docs/grafana/latest/panels-visualizations/query-transform-data/#query-options | -| `title` | string | No | | Panel title. | -| `transformations` | [DataTransformerConfig](#datatransformerconfig)[] | No | | List of transformations that are applied to the panel data before rendering.
    When there are multiple transformations, Grafana applies them in the order they are listed.
    Each transformation creates a result set that then passes on to the next transformation in the processing pipeline. | -| `transparent` | boolean | No | `false` | Whether to display the panel without a background. | - ### Templating Configured template variables @@ -648,7 +614,7 @@ A variable is a placeholder for a value. You can use variables in metric queries | `query` | | No | | Query used to fetch values for a variable | | `refresh` | integer | No | | Options to config when to refresh a variable
    `0`: Never refresh the variable
    `1`: Queries the data source every time the dashboard loads.
    `2`: Queries the data source when the dashboard time range changes.
    Possible values are: `0`, `1`, `2`. | | `skipUrlSync` | boolean | No | `false` | Whether the variable value should be managed by URL query params or not | -| `sort` | integer | No | | Sort variable options
    Accepted values are:
    `0`: No sorting
    `1`: Alphabetical ASC
    `2`: Alphabetical DESC
    `3`: Numerical ASC
    `4`: Numerical DESC
    `5`: Alphabetical Case Insensitive ASC
    `6`: Alphabetical Case Insensitive DESC
    Possible values are: `0`, `1`, `2`, `3`, `4`, `5`, `6`. | +| `sort` | integer | No | | Sort variable options
    Accepted values are:
    `0`: No sorting
    `1`: Alphabetical ASC
    `2`: Alphabetical DESC
    `3`: Numerical ASC
    `4`: Numerical DESC
    `5`: Alphabetical Case Insensitive ASC
    `6`: Alphabetical Case Insensitive DESC
    `7`: Natural ASC
    `8`: Natural DESC
    Possible values are: `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`. | ### VariableOption @@ -670,17 +636,6 @@ Accepted values are relative time strings like {from: 'now-6h', to: 'now'} or ab | `from` | string | **Yes** | `now-6h` | | | `to` | string | **Yes** | `now` | | -### Timepicker - -Configuration of the time picker shown at the top of a dashboard. - -| Property | Type | Required | Default | Description | -|---------------------|----------|----------|---------------------------------------|---------------------------------------------------------------------------------------------------| -| `collapse` | boolean | **Yes** | `false` | Whether timepicker is collapsed or not. Has no effect on provisioned dashboard. | -| `hidden` | boolean | **Yes** | `false` | Whether timepicker is visible or not. | -| `refresh_intervals` | string[] | **Yes** | `[5s 10s 30s 1m 5m 15m 30m 1h 2h 1d]` | Interval options available in the refresh picker dropdown. | -| `time_options` | string[] | **Yes** | `[5m 15m 1h 6h 12h 24h 2d 7d 30d]` | Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. | - ### Status | Property | Type | Required | Default | Description | diff --git a/docs/sources/developers/kinds/core/preferences/schema-reference.md b/docs/sources/developers/kinds/core/preferences/schema-reference.md index 1605808409408..e5ac35187cdc4 100644 --- a/docs/sources/developers/kinds/core/preferences/schema-reference.md +++ b/docs/sources/developers/kinds/core/preferences/schema-reference.md @@ -21,7 +21,7 @@ The user or team frontend preferences | Property | Type | Required | Default | Description | |------------|---------------------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `metadata` | [object](#metadata) | **Yes** | | metadata contains embedded CommonMetadata and can be extended with custom string fields
    TODO: use CommonMetadata instead of redefining here; currently needs to be defined here
    without external reference as using the CommonMetadata reference breaks thema codegen. | -| `spec` | [object](#spec) | **Yes** | | | +| `spec` | [object](#spec) | **Yes** | | Spec defines user, team or org Grafana preferences
    swagger:model Preferences | | `status` | [object](#status) | **Yes** | | | ### Metadata @@ -69,6 +69,9 @@ extraFields is reserved for any fields that are pulled from the API server metad ### Spec +Spec defines user, team or org Grafana preferences +swagger:model Preferences + | Property | Type | Required | Default | Description | |---------------------|---------------------------------------------------|----------|---------|---------------------------------------------------------------------------------| | `cookiePreferences` | [CookiePreferences](#cookiepreferences) | No | | | diff --git a/docs/sources/developers/plugins/plugin.schema.json b/docs/sources/developers/plugins/plugin.schema.json index f19c1a542c1b2..41ee3c2b3f19c 100644 --- a/docs/sources/developers/plugins/plugin.schema.json +++ b/docs/sources/developers/plugins/plugin.schema.json @@ -166,7 +166,7 @@ "grafanaDependency": { "type": "string", "description": "Required Grafana version for this plugin. Validated using https://github.com/npm/node-semver.", - "pattern": "^(<=|>=|<|>|=|~|\\^)?([0-9]+)(\\.[0-9x\\*]+)(\\.[0-9x\\*]+)?(\\s(<=|>=|<|=>)?([0-9]+)(\\.[0-9x]+)(\\.[0-9x]+))?$" + "pattern": "^(<=|>=|<|>|=|~|\\^)?([0-9]+)(\\.[0-9x\\*]+)(\\.[0-9x\\*]+)?(\\s(<=|>=|<|=>)?([0-9]+)(\\.[0-9x]+)(\\.[0-9x]+))?(\\-[0-9]+)?$" }, "plugins": { "type": "array", @@ -478,51 +478,37 @@ "type": "boolean", "description": "For data source plugins, if the plugin supports tracing. Used for example to link logs (e.g. Loki logs) with tracing plugins." }, - "externalServiceRegistration": { + "iam": { "type": "object", - "description": "Oauth App Service Registration.", + "description": "Identity and Access Management.", "properties": { - "impersonation": { - "type": "object", - "description": "Impersonation describes the permissions that the external service will have on behalf of the user.", - "properties": { - "enabled": { - "type": "boolean", - "description": "Enabled allows the service to request access tokens to impersonate users using the jwtbearer grant" - }, - "groups": { - "type": "boolean", - "description": "Groups allows the service to list the impersonated user's teams." - }, - "permissions": { - "type": "array", - "description": "Permissions are the permissions that the external service needs when impersonating a user. The intersection of this set with the impersonated user's permission guarantees that the client will not gain more privileges than the impersonated user has.", - "items": { - "type": "object", - "additionalProperties": false, - "properties": { - "action": { - "type": "string" - }, - "scope": { - "type": "string" - } - } + "permissions": { + "type": "array", + "description": "Permissions are the permissions that the plugin needs its associated service account to have", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "action": { + "type": "string" + }, + "scope": { + "type": "string" } } } }, - "self": { + "impersonation": { "type": "object", - "description": "Self describes the permissions that the external service will have on behalf of itself", + "description": "Impersonation describes the permissions that the plugin will be restricted to when acting on behalf of the user.", "properties": { - "enabled": { + "groups": { "type": "boolean", - "description": "Enabled allows the service to request access tokens for itself using the client_credentials grant" + "description": "Groups allows the service to list the impersonated user's teams." }, "permissions": { "type": "array", - "description": "Permissions are the permissions that the external service needs its associated service account to have", + "description": "Permissions are the permissions that the plugin needs when impersonating a user. The intersection of this set with the impersonated user's permission guarantees that the client will not gain more privileges than the impersonated user has.", "items": { "type": "object", "additionalProperties": false, diff --git a/docs/sources/explore/_index.md b/docs/sources/explore/_index.md index a6175ec073b4d..92257239d952b 100644 --- a/docs/sources/explore/_index.md +++ b/docs/sources/explore/_index.md @@ -33,6 +33,10 @@ If you just want to explore your data and do not want to create a dashboard, the In order to access Explore, you must have an editor or an administrator role, unless the [viewers_can_edit option]({{< relref "../setup-grafana/configure-grafana/#viewers_can_edit" >}}) is enabled. Refer to [About users and permissions]({{< relref "../administration/roles-and-permissions/" >}}) for more information on what each role has access to. +{{% admonition type="note" %}} +If you are using Grafana Cloud, open a [support ticket in the Cloud Portal](/profile/org#support) to enable the `viewers_can_edit` option +{{% /admonition %}} + To access Explore: 1. Click on the Explore icon on the menu bar. @@ -83,6 +87,10 @@ You can then click on any panel icon in the content outline to navigate to that When using Explore, the URL in the browser address bar updates as you make changes to the queries. You can share or bookmark this URL. +{{% admonition type="note" %}} +Explore may generate relatively long URLs, some tools, like messaging or videoconferencing apps, may truncate messages to a fixed length. In such cases Explore will display a warning message and load a default state. If you encounter issues when sharing Explore links in such apps, you can generate shortened links. See [Share shortened link](#share-shortened-link) for more information. +{{% /admonition %}} + ### Generating Explore URLs from external tools Because Explore URLs have a defined structure, you can build a URL from external tools and open it in Grafana. The URL structure is: @@ -125,4 +133,14 @@ The `from` and `to` also accept relative ranges defined in [Time units and relat Available in Grafana 7.3 and later versions. {{% /admonition %}} -The Share shortened link capability allows you to create smaller and simpler URLs of the format /goto/:uid instead of using longer URLs with query parameters. To create a shortened link to the executed query, click the **Share** option in the Explore toolbar. A shortened link that is never used will automatically get deleted after seven (7) days. +The Share shortened link capability allows you to create smaller and simpler URLs of the format /goto/:uid instead of using longer URLs with query parameters. To create a shortened link to the executed query, click the **Share** option in the Explore toolbar. + +A shortened link will automatically get deleted after seven (7) days from its creation if it's never used. If a link is used at least once, it won't ever get deleted. + +### Sharing shortened links with absolute time + +{{% admonition type="note" %}} +Available in Grafana 10.3 and later versions. +{{% /admonition %}} + +Short links have two options - keeping relative time (for example, from two hours ago to now) or absolute time (for example, from 8am to 10am). Sharing a shortened link by default will copy the time range selected, relative or absolute. Clicking the dropdown button next to the share shortened link button and selecting one of the options under "Time-Sync URL Links" will allow you to create a short link with the absolute time - meaning anyone receiving the link will see the same data you are seeing, even if they open the link at another time. This will not affect your selected time range. diff --git a/docs/sources/explore/correlations-editor-in-explore.md b/docs/sources/explore/correlations-editor-in-explore.md new file mode 100644 index 0000000000000..04ba3c709c831 --- /dev/null +++ b/docs/sources/explore/correlations-editor-in-explore.md @@ -0,0 +1,136 @@ +--- +labels: + products: + - enterprise + - oss +title: Correlations Editor in Explore +weight: 400 +--- + +# Correlations Editor in Explore + +{{% admonition type="note" %}} +The Explore editor is available in 10.1 and later versions. In the editor, transformations is available in Grafana 10.3 and later versions. +{{% /admonition %}} + +Correlations allow users to build a link between any two data sources. For more information about correlations in general, please see the [correlations]({{< relref "../administration/correlations" >}}) topic in the administration page. + +## Create a correlation + +1. In Grafana, navigate to the Explore page. +1. Select a data source that you would like to be [the source data source]({{< relref "../administration/correlations/correlation-configuration#source-data-source-and-result-field" >}}) for a new correlation. +1. Run a query producing data in [a supported visualization]({{< relref "../administration/correlations#correlations" >}}). +1. Click **+ Add** in the top toolbar and select **Add correlation** (you can also select **Correlations Editor** from the [Command Palette]({{< relref "../search#command-palette" >}})). +1. Explore is now in Correlations Editor mode indicated by a blue border and top bar. You can exit Correlations Editor by clicking **Exit** in the top bar. +1. You can now create the following new correlations for the visualization with links that are attached to the data that you can use to build a new query: + - Logs: links are displayed next to field values inside log details for each log row + - Table: every table cell is a link +1. Click on a link to add a new correlation. + Links are associated with a field that is used as a [result field of a correlation]({{< relref "../administration/correlations/correlation-configuration" >}}). +1. In the split view that opens, use the right pane to set up [the target query source of the correlation]({{< relref "../administration/correlations/correlation-configuration#target-query" >}}). +1. Build a target query using [variables syntax]({{< relref "../dashboards/variables/variable-syntax" >}}) with variables from the list provided at the top of the pane. The list contains sample values from the selected data row. +1. Provide a label and description (optional). + A label will be used as the name of the link inside the visualization and can contain variables. +1. Provide transformations (optional; see below for details). +1. Click **Save** in the top toolbar to save the correlation and exit Correlations Editor mode. + The link used to create the correlation is replaced with a data link in each row. When the link is clicked, the query you defined will run in another pane, with the variables replaced dynamically with the values from the selected row. + +## Transformations + +Transformations allow you to extract values that exist in a field with other data. For example, using a transformation, you can extract one portion of a log line to use in a correlation. For more details on transformations in correlations, see [Correlations]({{< relref "../administration/correlations/correlation-configuration/#correlation-transformations" >}}). + +After clicking one of the generated links in the editor mode, you can add transformations by clicking **Add transformation** in the Transformations dropdown menu. + +You can use a transformation in your correlation with the following steps: + +1. Select a field to apply the transformation to. + Select the portion of the field that you want to use for the transformation. For example, a log line. + Once selected, the value of this field will be used to assist you in building the transformation. +1. Select the type of the transformation. + See [correlations]({{< relref "../administration/correlations/correlation-configuration/#correlation-transformations" >}}) for the options and relevant settings. +1. Based on your selection, you might see one or more variables populate, or you might need to provide more specifications in options that are displayed. +1. Select **Add transformation to correlation** to add the specified variables to the list of available variables. + +### Notes for regular expressions + +For regular expressions in this dialog box, the `mapValue` referred to in other documentation is called `Variable Name` here. Grafana highlights any text that matches the expression in the field value. Use regular expression capture groups to select what portion of the match should be extracted. When a valid regular expression is provided, the variable and the value of that variable appear below the `Variable Name` field. + +## Correlations examples + +The following examples show how to create correlations using the Correlations Editor in Explore. If you'd like to follow these examples, make sure to set up a [test data source]({{< relref "../datasources/testdata#testdata-data-source" >}}). + +### Create a text to graph correlation + +This example shows how to create a correlation using Correlations Editor in Explore. + +Correlations allow you to use results of one query to run a new query in any data source. In this example, you will run a query that renders tabular data. The data will be used to run a different query that yields a graph result. + +To follow this example, make sure you have set up [a test data source]({{< relref "../datasources/testdata#testdata-data-source" >}}). + +1. In Grafana, navigate to **Explore**. +1. Select the **test data source** from the dropdown menu at the top left of the page. +1. Click **+ Add** in the dropdown menu to the right and select **Add correlation**. +1. Explore is now in Correlations Editor mode, indicated by a blue border. +1. Select the following scenario from the scenario dropdown menu: **CSV File**. +1. Select the file, **population_by_state.csv**. + Each cell is a link that you can click on to begin creating a new correlation. + + {{< figure src="/static/img/docs/correlations/screenshot-correlations-editor-source-10.2.png" max-width="600px" caption="Selecting the source of a correlation" >}} + +1. Click on any cell in the `State` column to create a new correlation that attaches a data link to that entry. For example, select "California". +1. In the split view, select the same data source you selected in the left pane. + The helper above the query editor contains all available variables you can use the target query. Variables contain all data fields (table columns) from the selected row. +1. In the **Scenario** menu, select **CSV Metric Values**. + The `String Input` field in the Query editor provides variables with population values for each year: `${1980},${2000},${2020}`. This will generate a graph using variable values. +1. In the Query Editor **Alias** field, enter "${State}". + + {{< figure src="/static/img/docs/correlations/screenshot-correlations-editor-target-10.2.png" max-width="600px" caption="Setting up the target of a correlation" >}} + + Run a query to see that it produces a graph using sample values from the variables. + +1. Click **Save** to save the correlation and exit the Correlations Editor. + + After the correlation is saved, Explore will rerun the query in the left pane. By clicking a state name, the query on the right is rerun with values from the row being inserted into the CSV, thus changing the graph. The query is rerun with updated values every time you click on a state name. + + {{< figure src="/static/img/docs/correlations/screenshot-correlations-example-link-10.2.png" max-width="600px" caption="Result of clicking on a data link" >}} + +You can apply the same steps to any data source. Correlations allow you to create links in visualizations to run dynamic queries based on selected data. In this example we used data returned by a query to build a new query generating different visualization using the same data source. However, you can create correlations between any data sources to create custom exploration flows. + +### Create a logs to table correlation + +In this example, you will create a correlation to demonstrate how to use transformations to extract values from the log line and another field. + +To follow this example, make sure you have set up [a test data source]({{< relref "../datasources/testdata#testdata-data-source" >}}). + +1. In Grafana, navigate to **Explore**. +1. Select the **test data source** from the dropdown menu at the top left of the page. +1. Click **+ Add** in the dropdown menu to the right and select **Add correlation**. +1. Explore is now in Correlations Editor mode, indicated by a blue border. +1. In the **Scenario** menu, select **Logs**. +1. Expand a log line to see the correlation links. Select `Correlate with hostname`. +1. Explore opens in split view. Select the same data source you selected in the left pane. + The helper above the query editor contains all available variables you can use the target query. +1. Expand the transformations section, and click **Add transformation**. +1. In the **Field** dropdown menu, select **message**. + The log line shows up as example data. +1. Under **Type**, select **Logfmt**. + This populates the list of variables. +1. Click **Add transformation to correlation**. +1. Click **Add transformation** again and under **Field**, select **hostname**. +1. Under **Type**, select **Regular expression**. +1. Under **Expression**, enter the following: + `-([0-9]\*)` + This selects any numbers to the right of the dash. +1. Under **Variable Name**, enter the following: + hostNumber + This populates the list of variables. +1. Click **Add transformation to correlation** to add it to the other variables. +1. In the data source editor, open the **Scenario** dropdown menu and select **CSV Content**. +1. In the text box below, provide the following and save the correlation: + + ```csv + time,msg,hostNumber,status + ${time},${msg},${hostNumber},${status} + ``` + + This closes the split view and reruns the left query. Expand any log line to see the correlation button. Clicking the correlation button opens the split view with the `time` (a field), `msg` (extracted with `logfmt` from the log line), host number (extracted with `regex` from the `hostname`) and the `status` (extracted with `logfmt` from the log line). diff --git a/docs/sources/explore/trace-integration.md b/docs/sources/explore/trace-integration.md index 5b2d19b35fe38..dad3dbf68f6ff 100644 --- a/docs/sources/explore/trace-integration.md +++ b/docs/sources/explore/trace-integration.md @@ -30,7 +30,7 @@ For information on how to configure queries for the data sources listed above, r You can query and search tracing data using a data source's query editor. -Each data source can have it's own query editor. The query editor for the Tempo data source is slightly different than the query editor for the Jaegar data source. +Each data source can have it's own query editor. The query editor for the Tempo data source is slightly different than the query editor for the Jaeger data source. For information on querying each data source, refer to their documentation: @@ -39,7 +39,7 @@ For information on querying each data source, refer to their documentation: - [Zipkin query editor]({{< relref "../datasources/zipkin/#query-the-data-source" >}}) - [Azure Monitor Application Insights query editor]({{< relref "../datasources/azure-monitor/query-editor/#query-application-insights-traces" >}}) -## Trace View +## Trace view This section explains the elements of the Trace View. @@ -59,7 +59,7 @@ This section explains the elements of the Trace View. Shows condensed view or the trace timeline. Drag your mouse over the minimap to zoom into smaller time range. Zooming will also update the main timeline, so it is easy to see shorter spans. Hovering over the minimap, when zoomed, will show Reset Selection button which resets the zoom. -### Span Filters +### Span filters ![Screenshot of span filtering](/media/docs/tempo/screenshot-grafana-tempo-span-filters-v10-1.png) @@ -67,13 +67,15 @@ Using span filters, you can filter your spans in the trace timeline viewer. The You can add one or more of the following filters: -- Service name +- Resource service name - Span name - Duration - Tags (which include tags, process tags, and log fields) To only show the spans you have matched, you can press the `Show matches only` toggle. +{{< youtube id="VP2XV3IIc80" >}} + ### Timeline {{< figure src="/media/docs/tempo/screenshot-grafana-trace-view-timeline.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the trace view timeline" >}} @@ -99,10 +101,6 @@ Clicking anywhere on the span row shows span details. ### Trace to logs -{{% admonition type="note" %}} -Available in Grafana 7.4 and later versions. -{{% /admonition %}} - You can navigate from a span in a trace view directly to logs relevant for that span. This feature is available for Tempo, Jaeger, and Zipkin data sources. Refer to their [relevant documentation](/docs/grafana/latest/datasources/tempo/#trace-to-logs) for configuration instructions. {{< figure src="/media/docs/tempo/screenshot-grafana-trace-view-trace-to-logs.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the trace view in Explore with icon next to the spans" >}} @@ -112,12 +110,21 @@ Click the document icon to open a split view in Explore with the configured data ### Trace to metrics {{% admonition type="note" %}} -This feature is currently in beta & behind the `traceToMetrics` feature toggle. +This feature is currently in beta and behind the `traceToMetrics` feature toggle. {{% /admonition %}} -You can navigate from a span in a trace view directly to metrics relevant for that span. This feature is available for Tempo, Jaeger, and Zipkin data sources. Refer to their [relevant documentation](/docs/grafana/latest/datasources/tempo/#trace-to-metrics) for configuration instructions. +You can navigate from a span in a trace view directly to metrics relevant for that span. This feature is available for Tempo, Jaeger, and Zipkin data sources. Refer to their [relevant documentation](/docs/grafana/latest/datasources/tempo/configure-tempo-data-source/#trace-to-metrics) for configuration instructions. + +### Trace to profiles + +{{< docs/experimental product="Trace to profiles" featureFlag="traceToProfiles" >}} + +Using Trace to profiles, you can use Grafana’s ability to correlate different signals by adding the functionality to link between traces and profiles. +Refer to the [relevant documentation](/docs/grafana/latest/datasources/tempo/configure-tempo-data-source#trace-to-profiles) for configuration instructions. + +![Selecting a link in the span queries the profile data source](/static/img/docs/tempo/profiles/tempo-profiles-Span-link-profile-data-source.png) -## Node Graph +## Node graph You can optionally expand the node graph for the displayed trace. Depending on the data source, this can show spans of the trace as nodes in the graph, or as some additional context like service graph based on the current trace. diff --git a/docs/sources/panels-visualizations/configure-data-links/index.md b/docs/sources/panels-visualizations/configure-data-links/index.md index da954089d97f5..a65db5c1b2005 100644 --- a/docs/sources/panels-visualizations/configure-data-links/index.md +++ b/docs/sources/panels-visualizations/configure-data-links/index.md @@ -20,7 +20,7 @@ labels: - oss menuTitle: Configure data links title: Configure data links -weight: 400 +weight: 80 --- # Configure data links @@ -109,7 +109,7 @@ You can use variables in data links to send people to a detailed dashboard with When creating or updating a data link, press Cmd+Space or Ctrl+Space on your keyboard to open the typeahead suggestions to more easily add variables to your URL. -{{< figure src="/static/img/docs/data_link_typeahead.png" max-width= "800px" >}} +{{< figure src="/static/img/docs/data_link_typeahead.png" max-width= "800px" alt="Drop-down list with variable suggestions open from the URL field" >}} ### Add a data link diff --git a/docs/sources/panels-visualizations/configure-legend/index.md b/docs/sources/panels-visualizations/configure-legend/index.md index 8f4b899bb3d1c..aef872cb07360 100644 --- a/docs/sources/panels-visualizations/configure-legend/index.md +++ b/docs/sources/panels-visualizations/configure-legend/index.md @@ -8,7 +8,7 @@ labels: - enterprise - oss title: Configure a legend -weight: 400 +weight: 70 --- # Configure a legend @@ -90,8 +90,8 @@ This feature is only supported in these panels: Bar chart, Histogram, Time serie [Time series]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/visualizations/time-series" [Time series]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/visualizations/time-series" -[calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[calculations]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[calculations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" [Pie chart]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/visualizations/pie-chart" [Pie chart]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/visualizations/pie-chart" diff --git a/docs/sources/panels-visualizations/configure-overrides/index.md b/docs/sources/panels-visualizations/configure-overrides/index.md index 05122b0e7fd83..9c6851ee5925f 100644 --- a/docs/sources/panels-visualizations/configure-overrides/index.md +++ b/docs/sources/panels-visualizations/configure-overrides/index.md @@ -15,7 +15,7 @@ labels: - oss menuTitle: Configure field overrides title: Configure field overrides -weight: 400 +weight: 110 --- # Configure field overrides diff --git a/docs/sources/panels-visualizations/configure-panel-options/index.md b/docs/sources/panels-visualizations/configure-panel-options/index.md index 3708445a1e914..a10fae91c62ba 100644 --- a/docs/sources/panels-visualizations/configure-panel-options/index.md +++ b/docs/sources/panels-visualizations/configure-panel-options/index.md @@ -19,7 +19,7 @@ labels: - oss menuTitle: Configure panel options title: Configure panel options -weight: 2 +weight: 50 --- # Configure panel options @@ -71,7 +71,7 @@ Add a title and description to a panel to share with users any important informa You can use [variables you have defined][] in the **Title** and **Description** field, but not [global variables][]. - ![](/static/img/docs/panels/panel-options-8-0.png) + ![Panel editor pane with Panel options section expanded](/static/img/docs/panels/panel-options-8-0.png) ## View a panel JSON model diff --git a/docs/sources/panels-visualizations/configure-standard-options/index.md b/docs/sources/panels-visualizations/configure-standard-options/index.md index 860f5238f7faa..36f497eea61ca 100644 --- a/docs/sources/panels-visualizations/configure-standard-options/index.md +++ b/docs/sources/panels-visualizations/configure-standard-options/index.md @@ -19,7 +19,7 @@ labels: - oss menuTitle: Configure standard options title: Configure standard options -weight: 2 +weight: 60 --- # Configure standard options diff --git a/docs/sources/panels-visualizations/configure-thresholds/index.md b/docs/sources/panels-visualizations/configure-thresholds/index.md index c519f78992c14..4ff7612047cda 100644 --- a/docs/sources/panels-visualizations/configure-thresholds/index.md +++ b/docs/sources/panels-visualizations/configure-thresholds/index.md @@ -15,7 +15,7 @@ labels: - oss menuTitle: Configure thresholds title: Configure thresholds -weight: 300 +weight: 100 --- # Configure thresholds diff --git a/docs/sources/panels-visualizations/configure-value-mappings/index.md b/docs/sources/panels-visualizations/configure-value-mappings/index.md index e108a255a3bc5..aea0297d0d584 100644 --- a/docs/sources/panels-visualizations/configure-value-mappings/index.md +++ b/docs/sources/panels-visualizations/configure-value-mappings/index.md @@ -16,7 +16,7 @@ labels: - oss menuTitle: Configure value mappings title: Configure value mappings -weight: 600 +weight: 90 --- # Configure value mappings diff --git a/docs/sources/panels-visualizations/panel-editor-overview/index.md b/docs/sources/panels-visualizations/panel-editor-overview/index.md index 1cfc94cbe6726..b2a4da43740a0 100644 --- a/docs/sources/panels-visualizations/panel-editor-overview/index.md +++ b/docs/sources/panels-visualizations/panel-editor-overview/index.md @@ -24,7 +24,7 @@ labels: - oss menuTitle: Panel editor overview title: Panel editor overview -weight: 1 +weight: 20 --- # Panel editor overview diff --git a/docs/sources/panels-visualizations/panel-inspector/index.md b/docs/sources/panels-visualizations/panel-inspector/index.md index 01cbef7570e2c..7482c93582673 100644 --- a/docs/sources/panels-visualizations/panel-inspector/index.md +++ b/docs/sources/panels-visualizations/panel-inspector/index.md @@ -10,7 +10,7 @@ labels: - enterprise - oss title: The panel inspect view -weight: 1200 +weight: 30 --- # The panel inspect view diff --git a/docs/sources/panels-visualizations/query-transform-data/_index.md b/docs/sources/panels-visualizations/query-transform-data/_index.md index ba309c241632f..d70949b3b5b3b 100644 --- a/docs/sources/panels-visualizations/query-transform-data/_index.md +++ b/docs/sources/panels-visualizations/query-transform-data/_index.md @@ -19,7 +19,7 @@ labels: - enterprise - oss title: Query and transform data -weight: 200 +weight: 40 --- # Query and transform data @@ -41,7 +41,7 @@ Grafana supports up to 26 queries per panel. ### Query editors -{{< figure src="/static/img/docs/queries/influxdb-query-editor-7-2.png" class="docs-image--no-shadow" max-width="1000px" caption="The InfluxDB query editor" >}} +{{< figure src="/static/img/docs/queries/influxdb-query-editor-7-2.png" class="docs-image--no-shadow" max-width="1000px" alt="The InfluxDB query editor" >}} Each data source's **query editor** provides a customized user interface that helps you write queries that take advantage of its unique capabilities. @@ -123,20 +123,20 @@ Each query row contains a query editor and is identified with a letter (A, B, C, You can: -| Icon | Description | -| :-----------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| {{< figure src="/static/img/docs/queries/query-editor-help-7-4.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" >}} | Toggles query editor help. If supported by the data source, click this icon to display information on how to use the query editor or provide quick access to common queries. | -| {{< figure src="/static/img/docs/queries/duplicate-query-icon-7-0.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" >}} | Copies a query. Duplicating queries is useful when working with multiple complex queries that are similar and you want to either experiment with different variants or do minor alterations. | -| {{< figure src="/static/img/docs/queries/hide-query-icon-7-0.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" >}} | Hides a query. Grafana does not send hidden queries to the data source. | -| {{< figure src="/static/img/docs/queries/remove-query-icon-7-0.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" >}} | Removes a query. Removing a query permanently deletes it, but sometimes you can recover deleted queries by reverting to previously saved versions of the panel. | -| {{< figure src="/static/img/docs/queries/query-drag-icon-7-2.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" >}} | Reorders queries. Change the order of queries by clicking and holding the drag icon, then drag queries where desired. The order of results reflects the order of the queries, so you can often adjust your visual results based on query order. | +| Icon | Description | +| :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| {{< figure src="/static/img/docs/queries/query-editor-help-7-4.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" alt="Help icon" >}} | Toggles query editor help. If supported by the data source, click this icon to display information on how to use the query editor or provide quick access to common queries. | +| {{< figure src="/static/img/docs/queries/duplicate-query-icon-7-0.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" alt="Duplicate icon" >}} | Copies a query. Duplicating queries is useful when working with multiple complex queries that are similar and you want to either experiment with different variants or do minor alterations. | +| {{< figure src="/static/img/docs/queries/hide-query-icon-7-0.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" alt="Hide icon" >}} | Hides a query. Grafana does not send hidden queries to the data source. | +| {{< figure src="/static/img/docs/queries/remove-query-icon-7-0.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" alt="Remove icon">}} | Removes a query. Removing a query permanently deletes it, but sometimes you can recover deleted queries by reverting to previously saved versions of the panel. | +| {{< figure src="/static/img/docs/queries/query-drag-icon-7-2.png" class="docs-image--no-shadow" max-width="30px" max-height="30px" alt="Drag icon" >}} | Reorders queries. Change the order of queries by clicking and holding the drag icon, then drag queries where desired. The order of results reflects the order of the queries, so you can often adjust your visual results based on query order. | ## Query options Click **Query options** next to the data source selector to see settings for the selected data source. Changes you make here affect only queries made in this panel. -{{< figure src="/static/img/docs/queries/data-source-options-7-0.png" class="docs-image--no-shadow" max-width="1000px" >}} +{{< figure src="/static/img/docs/queries/data-source-options-7-0.png" class="docs-image--no-shadow" max-width="1000px" alt="Data source query options" >}} Grafana sets defaults that are shown in dark gray text. Changes are displayed in white text. diff --git a/docs/sources/panels-visualizations/calculation-types/index.md b/docs/sources/panels-visualizations/query-transform-data/calculation-types/index.md similarity index 85% rename from docs/sources/panels-visualizations/calculation-types/index.md rename to docs/sources/panels-visualizations/query-transform-data/calculation-types/index.md index 1471e0f00ce7e..dac122108df2a 100644 --- a/docs/sources/panels-visualizations/calculation-types/index.md +++ b/docs/sources/panels-visualizations/query-transform-data/calculation-types/index.md @@ -1,8 +1,9 @@ --- aliases: - - ../panels/calculation-types/ - - ../panels/calculations-list/ - - ../panels/reference-calculation-types/ + - ../../panels/calculation-types/ # /docs/grafana//panels/calculation-types/ + - ../../panels/calculations-list/ # /docs/grafana//panels/calculations-list/ + - ../../panels/reference-calculation-types/ # /docs/grafana//panels/reference-calculation-types/ + - ../calculation-types/ # /docs/grafana//panels-visualizations/calculation-types/ labels: products: - cloud diff --git a/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md b/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md index 5bbec1eba119d..d275d0ccbb6d4 100644 --- a/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md +++ b/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md @@ -80,7 +80,7 @@ The following steps guide you in adding a transformation to data. This documenta For information about available calculations, refer to [Calculation types][]. 1. To apply another transformation, click **Add transformation**. This transformation acts on the result set returned by the previous transformation. - {{< figure src="/static/img/docs/transformations/transformations-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} + {{< figure src="/static/img/docs/transformations/transformations-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="Transform tab in the panel editor" >}} ## Debug a transformation @@ -88,13 +88,13 @@ To see the input and the output result sets of the transformation, click the bug The input and output results sets can help you debug a transformation. -{{< figure src="/static/img/docs/transformations/debug-transformations-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/debug-transformations-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="The debug transformation screen with the debug icon highlighted" >}} ## Disable a transformation You can disable or hide one or more transformations by clicking on the eye icon on the top right side of the transformation row. This disables the applied actions of that specific transformation and can help to identify issues when you change several transformations one after another. -{{< figure src="/static/img/docs/transformations/screenshot-example-disable-transformation.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/screenshot-example-disable-transformation.png" class="docs-image--no-shadow" max-width= "1100px" alt="A transformation row with the disable transformation icon highlighted" >}} ## Filter a transformation @@ -126,30 +126,46 @@ You can perform the following transformations on your data. Use this transformation to add a new field calculated from two other fields. Each transformation allows you to add one new field. -- **Mode -** Select a mode: - - **Reduce row -** Apply selected calculation on each row of selected fields independently. - - **Binary operation -** Apply basic binary operations (for example, sum or multiply) on values in a single row from two selected fields. - - **Unary operation -** Apply basic unary operations on values in a single row from a selected field. The available operations are: +- **Mode** - Select a mode: + - **Reduce row** - Apply selected calculation on each row of selected fields independently. + - **Binary operation** - Apply basic binary operations (for example, sum or multiply) on values in a single row from two selected fields. + - **Unary operation** - Apply basic unary operations on values in a single row from a selected field. The available operations are: - **Absolute value (abs)** - Returns the absolute value of a given expression. It represents its distance from zero as a positive number. - **Natural exponential (exp)** - Returns _e_ raised to the power of a given expression. - **Natural logarithm (ln)** - Returns the natural logarithm of a given expression. - **Floor (floor)** - Returns the largest integer less than or equal to a given expression. - **Ceiling (ceil)** - Returns the smallest integer greater than or equal to a given expression. - - **Row index -** Insert a field with the row index. -- **Field name -** Select the names of fields you want to use in the calculation for the new field. -- **Calculation -** If you select **Reduce row** mode, then the **Calculation** field appears. Click in the field to see a list of calculation choices you can use to create the new field. For information about available calculations, refer to [Calculation types][]. -- **Operation -** If you select **Binary operation** or **Unary operation** mode, then the **Operation** fields appear. These fields allow you to apply basic math operations on values in a single row from selected fields. You can also use numerical values for binary operations. -- **As percentile -** If you select **Row index** mode, then the **As percentile** switch appears. This switch allows you to transform the row index as a percentage of the total number of rows. -- **Alias -** (Optional) Enter the name of your new field. If you leave this blank, then the field will be named to match the calculation. -- **Replace all fields -** (Optional) Select this option if you want to hide all other fields and display only your calculated field in the visualization. + - **Cumulative functions** - Apply functions on the current row and all preceding rows. + - **Total** - Calculates the cumulative total up to and including the current row. + - **Mean** - Calculates the mean up to and including the current row. + - **Window functions** - Apply window functions. The window can either be **trailing** or **centered**. + With a trailing window the current row will be the last row in the window. + With a centered window the window will be centered on the current row. + For even window sizes, the window will be centered between the current row, and the previous row. + - **Mean** - Calculates the moving mean or running average. + - **Stddev** - Calculates the moving standard deviation. + - **Variance** - Calculates the moving variance. + - **Row index** - Insert a field with the row index. +- **Field name** - Select the names of fields you want to use in the calculation for the new field. +- **Calculation** - If you select **Reduce row** mode, then the **Calculation** field appears. Click in the field to see a list of calculation choices you can use to create the new field. For information about available calculations, refer to [Calculation types][]. +- **Operation** - If you select **Binary operation** or **Unary operation** mode, then the **Operation** fields appear. These fields allow you to apply basic math operations on values in a single row from selected fields. You can also use numerical values for binary operations. +- **As percentile** - If you select **Row index** mode, then the **As percentile** switch appears. This switch allows you to transform the row index as a percentage of the total number of rows. +- **Alias** - (Optional) Enter the name of your new field. If you leave this blank, then the field will be named to match the calculation. +- **Replace all fields** - (Optional) Select this option if you want to hide all other fields and display only your calculated field in the visualization. + +> **Note:** **Cumulative functions** and **Window functions** modes are experimental features. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Enable the **addFieldFromCalculationStatFunctions** feature toggle in Grafana to use this feature. Contact Grafana Support to enable this feature in Grafana Cloud. In the example below, we added two fields together and named them Sum. -{{< figure src="/static/img/docs/transformations/add-field-from-calc-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/add-field-from-calc-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A stat visualization including one field called Sum" >}} ### Concatenate fields -Use this transformation to combine all fields from all frames into one result. Consider the following: +Use this transformation to combine all fields from all frames into one result. + +For example, if you have separate queries retrieving temperature and uptime data (Query A) and air quality index and error information (Query B), applying the concatenate transformation yields a consolidated data frame with all relevant information in one view. + +Consider the following: **Query A:** @@ -169,21 +185,21 @@ After you concatenate the fields, the data frame would be: | ---- | ------- | --- | ------ | | 15.4 | 1230233 | 3.2 | 5 | +This transformation simplifies the process of merging data from different sources, providing a comprehensive view for analysis and visualization. + ### Config from query results -Use this transformation to select one query and from it extract standard options such as -**Min**, **Max**, **Unit**, and **Thresholds** and apply them to other query results. -This enables dynamic query driven visualization configuration. +Use this transformation to select a query and extract standard options, such as **Min**, **Max**, **Unit**, and **Thresholds**, and apply them to other query results. This feature enables dynamic visualization configuration based on the data returned by a specific query. #### Options -- **Config query**: Select the query that returns the data you want to use as configuration. -- **Apply to**: Select what fields or series to apply the configuration to. -- **Apply to options**: Usually a field type or field name regex depending on what option you selected in **Apply to**. +- **Config query** - Select the query that returns the data you want to use as configuration. +- **Apply to** - Select the fields or series to which the configuration should be applied. +- **Apply to options** - Specify a field type or use a field name regex, depending on your selection in **Apply to**. #### Field mapping table -Below the configuration listed above you will find the field table. Here all fields found in the data returned by the config query will be listed along with a **Use as** and **Select** option. This table gives you control over what field should be mapped to which config property and if there are multiple rows which value to select. +Below the configuration options, you'll find the field mapping table. This table lists all fields found in the data returned by the config query, along with **Use as** and **Select** options. It provides control over mapping fields to config properties, and for multiple rows, it allows you to choose which value to select. #### Example @@ -208,14 +224,11 @@ Output (Same as Input[0] but now with config on the Value field) | 1626178119127 | 10 | | 1626178119129 | 30 | -Each row in the source data becomes a separate field. Each field now also has a maximum -configuration option set. Options such as **min**, **max**, **unit**, and **thresholds** are all part of field configuration, and if they are set like this, they will be used by the visualization instead of any options that are manually configured. -in the panel editor options pane. +Each row in the source data becomes a separate field. Each field now has a maximum configuration option set. Options such as **Min**, **Max**, **Unit**, and **Thresholds** are part of the field configuration. If set, they are used by the visualization instead of any options manually configured in the panel editor options pane. #### Value mappings -You can also transform a query result into value mappings. This is is a bit different because every -row in the configuration query result is used to define a single value mapping row. See the following example. +You can also transform a query result into value mappings. With this option, every row in the configuration query result defines a single value mapping row. See the following example. Config query result: @@ -233,21 +246,26 @@ In the field mapping specify: | Text | Value mappings / Text | All values | | Color | Value mappings / Ciolor | All values | -Grafana will build the value mappings from you query result and apply it the the real data query results. You should see values being mapped and colored according to the config query results. +Grafana builds value mappings from your query result and applies them to the real data query results. You should see values being mapped and colored according to the config query results. ### Convert field type -Use this transformation to change the field type of the specified field. +Use this transformation to modify the field type of a specified field. -- **Field -** Select from available fields -- **as -** Select the FieldType to convert to - - **Numeric -** attempts to make the values numbers - - **String -** will make the values strings - - **Time -** attempts to parse the values as time +This transformation has the following options: + +- **Field** - Select from available fields +- **as** - Select the FieldType to convert to + - **Numeric** - attempts to make the values numbers + - **String** - will make the values strings + - **Time** - attempts to parse the values as time - Will show an option to specify a DateFormat as input by a string like yyyy-mm-dd or DD MM YYYY hh:mm:ss - - **Boolean -** will make the values booleans + - **Boolean** - will make the values booleans + - **Enum** - will make the values enums + - Will show a table to manage the enums + - **Other** - attempts to parse the values as JSON -For example, the following query could be modified by selecting the time field, as Time, and Date Format as YYYY. +For example, consider the following query that could be modified by selecting the time field as Time and specifying Date Format as YYYY. #### Sample Query @@ -269,21 +287,23 @@ The result: | 2019-01-01 00:00:00 | below | 29 | | 2020-01-01 00:00:00 | above | 22 | +This transformation allows you to flexibly adapt your data types, ensuring compatibility and consistency in your visualizations. + ### Extract fields -Use this transformation to select one source of data and extract content from it in different formats. Set the following fields: +Use this transformation to select a source of data and extract content from it in different formats. This transformation has the following fields: - **Source** - Select the field for the source of data. -- **Format** - Select one of the following: - - **JSON** - To parse JSON content from the source. - - **Key+value parse** - To parse content in the format 'a=b' or 'c:d' from the source. - - **Auto** - To discover fields automatically. -- **Replace all fields** - Optional: Select this option if you want to hide all other fields and display only your calculated field in the visualization. -- **Keep time** - Optional: Only available if **Replace all fields** is true. Keep the time field in the output. +- **Format** - Choose one of the following: + - **JSON** - Parse JSON content from the source. + - **Key+value pairs** - Parse content in the format 'a=b' or 'c:d' from the source. + - **Auto** - Discover fields automatically. +- **Replace All Fields** - (Optional) Select this option to hide all other fields and display only your calculated field in the visualization. +- **Keep Time** - (Optional) Available only if **Replace All Fields** is true. Keeps the time field in the output. -Consider the following data set: +Consider the following dataset: -#### Data Set Example +#### Dataset Example | Timestamp | json_data | | ------------------- | ------------- | @@ -310,18 +330,22 @@ This will generate the following output: | 1636678680000000000 | 5 | | 1636678620000000000 | 12 | +This transformation allows you to extract and format data in various ways. You can customize the extraction format based on your specific data needs. + ### Lookup fields from resource -Use this transformation on a field value to look up additional fields from an external source. +Use this transformation to enrich a field value by looking up additional fields from an external source. + +This transformation has the following fields: -- **Field** - Select a text field. -- **Lookup** - Select from **Countries**, **USA States**, and **Airports**. +- **Field** - Select a text field from your dataset. +- **Lookup** - Choose from **Countries**, **USA States**, and **Airports**. This transformation currently supports spatial data. For example, if you have this data: -#### Data Set Example +#### Dataset Example | Location | Values | | --------- | ------ | @@ -348,9 +372,11 @@ You'll get the following output: | Arkansas | | | | | 1 | | Somewhere | | | | | 5 | +This transformation lets you augment your data by fetching additional information from external sources, providing a more comprehensive dataset for analysis and visualization. + ### Filter data by query refId -Use this transformation in panels that have multiple queries, if you want to hide one or more of the queries. +Use this transformation to hide one or more queries in panels that have multiple queries. Grafana displays the query identification letters in dark gray text. Click a query identifier to toggle filtering. If the query letter is white, then the results are displayed. If the query letter is dark, then the results are hidden. @@ -358,33 +384,33 @@ Grafana displays the query identification letters in dark gray text. Click a que In the example below, the panel has three queries (A, B, C). We removed the B query from the visualization. -{{< figure src="/static/img/docs/transformations/filter-by-query-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/filter-by-query-stat-example-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A stat visualization with results from two queries, A and C" >}} ### Filter data by values -Use this transformation to filter your data directly in Grafana and remove some data points from your query result. You have the option to include or exclude data that match one or more conditions you define. The conditions are applied on a selected field. +Use this transformation to selectively filter data points directly within your visualization. This transformation provides options to include or exclude data based on one or more conditions applied to a selected field. This transformation is very useful if your data source does not natively filter by values. You might also use this to narrow values to display if you are using a shared query. The available conditions for all fields are: -- **Regex:** Match a regex expression -- **Is Null:** Match if the value is null -- **Is Not Null:** Match if the value is not null -- **Equal:** Match if the value is equal to the specified value -- **Different:** Match if the value is different than the specified value +- **Regex** - Match a regex expression. +- **Is Null** - Match if the value is null. +- **Is Not Null** - Match if the value is not null. +- **Equal** - Match if the value is equal to the specified value. +- **Different** - Match if the value is different than the specified value. The available conditions for number fields are: -- **Greater:** Match if the value is greater than the specified value -- **Lower:** Match if the value is lower than the specified value -- **Greater or equal:** Match if the value is greater or equal -- **Lower or equal:** Match if the value is lower or equal -- **Range:** Match a range between a specified minimum and maximum, min and max included +- **Greater** - Match if the value is greater than the specified value. +- **Lower** - Match if the value is lower than the specified value. +- **Greater or equal** - Match if the value is greater or equal. +- **Lower or equal** - Match if the value is lower or equal. +- **Range** - Match a range between a specified minimum and maximum, min and max included. -Consider the following data set: +Consider the following dataset: -#### Data Set Example +#### Dataset Example | Time | Temperature | Altitude | | ------------------- | ----------- | -------- | @@ -419,17 +445,17 @@ You can add more than one condition to the filter. For example, you might want t - Condition 1: Rows where 'Temperature' matches 'Lower' than '30' - Condition 2: Rows where 'Altitude' matches 'Greater' than '100' -When you have more than one condition, you can choose if you want the action (include / exclude) to be applied on rows that **Match all** conditions or **Match any** of the conditions you added. +When you have more than one condition, you can choose if you want the action (include/exclude) to be applied on rows that **Match all** conditions or **Match any** of the conditions you added. In the example above, we chose **Match all** because we wanted to include the rows that have a temperature lower than 30°C _AND_ an altitude higher than 100. If we wanted to include the rows that have a temperature lower than 30°C _OR_ an altitude higher than 100 instead, then we would select **Match any**. This would include the first row in the original data, which has a temperature of 32°C (does not match the first condition) but an altitude of 101 (which matches the second condition), so it is included. Conditions that are invalid or incompletely configured are ignored. -### Filter fields by name +This versatile data filtering transformation lets you to selectively include or exclude data points based on specific conditions. Customize the criteria to tailor your data presentation to meet your unique analytical needs. -Use this transformation to remove parts of the query results. +### Filter fields by name -You can filter field names in three different ways: +Use this transformation to selectively remove parts of your query results. There are three ways to filter field names: - [Using a regular expression](#use-a-regular-expression) - [Manually selecting included fields](#manually-select-included-fields) @@ -439,7 +465,7 @@ You can filter field names in three different ways: When you filter using a regular expression, field names that match the regular expression are included. -From the input data: +For example, from the input data: | Time | dev-eu-west | dev-eu-north | prod-eu-west | prod-eu-north | | ------------------- | ----------- | ------------ | ------------ | ------------- | @@ -453,7 +479,7 @@ The result from using the regular expression 'prod.\*' would be: | 2023-03-04 23:56:23 | 22.2 | 20.2 | | 2023-03-04 23:56:23 | 22.1 | 20.1 | -The regular expression can include an interpolated dashboard variable by using the ${$variableName} syntax. +The regular expression can include an interpolated dashboard variable by using the ${variableName} syntax. #### Manually select included fields @@ -463,36 +489,58 @@ Click and uncheck the field names to remove them from the result. Fields that ar Enable 'From variable' to let you select a dashboard variable that's used to include fields. By setting up a [dashboard variable][] with multiple choices, the same fields can be displayed across multiple visualizations. -{{< figure src="/static/img/docs/transformations/filter-name-table-before-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/filter-name-table-before-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A table visualization with time, value, Min, and Max columns" >}} Here's the table after we applied the transformation to remove the Min field. -{{< figure src="/static/img/docs/transformations/filter-name-table-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/filter-name-table-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A table visualization with time, value, and Max columns" >}} Here is the same query using a Stat visualization. -{{< figure src="/static/img/docs/transformations/filter-name-stat-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/filter-name-stat-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A stat visualization with value and Max fields" >}} + +This transformation provides flexibility in tailoring your query results to focus on the specific fields you need for effective analysis and visualization. ### Format string -> **Note:** This transformation is an experimental feature. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Enable the 'formatString' in Grafana to use this feature. Contact Grafana Support to enable this feature in Grafana Cloud. +Use this transformation to customize the output of a string field. This transformation has the following fields: + +- **Upper case** - Formats the entire string in uppercase characters. +- **Lower case** - Formats the entire string in lowercase characters. +- **Sentence case** - Formats the first character of the string in uppercase. +- **Title case** - Formats the first character of each word in the string in uppercase. +- **Pascal case** - Formats the first character of each word in the string in uppercase and doesn't include spaces between words. +- **Camel case** - Formats the first character of each word in the string in uppercase, except the first word, and doesn't include spaces between words. +- **Snake case** - Formats all characters in the string in lowercase and uses underscores instead of spaces between words. +- **Kebab case** - Formats all characters in the string in lowercase and uses dashes instead of spaces between words. +- **Trim** - Removes all leading and trailing spaces from the string. +- **Substring** - Returns a substring of the string, using the specified start and end positions. -Use this transformation to format the output of a string field. You can format output in the following ways: +This transformation provides a convenient way to standardize and tailor the presentation of string data for better visualization and analysis. -- Upper case - Formats the entire string in upper case characters. -- Lower case - Formats the entire string in lower case characters. -- Sentence case - Formats the the first character of the string in upper case. -- Title case - Formats the first character of each word in the string in upper case. -- Pascal case - Formats the first character of each word in the string in upper case and doesn't include spaces between words. -- Camel case - Formats the first character of each word in the string in upper case, except the first word, and doesn't include spaces between words. -- Snake case - Formats all characters in the string in lower case and uses underscores instead of spaces between words. -- Kebab case - Formats all characters in the string in lower case and uses dashes instead of spaces between words. -- Trim - Removes all leading and trailing spaces from the string. -- Substring - Returns a substring of the string, using the specified start and end positions. +> **Note:** This transformation is an experimental feature. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Enable the **formatString** feature toggle in Grafana to use this feature. Contact Grafana Support to enable this feature in Grafana Cloud. ### Format time -Use this transformation to format the output of a time field. Output can be formatted using [Moment.js format strings](https://momentjs.com/docs/#/displaying/). For instance, if you would like to display only the year of a time field the format string 'YYYY' can be used to show the calendar year (e.g. 1999, 2012, etc.). +Use this transformation to customize the output of a time field. Output can be formatted using [Moment.js format strings](https://momentjs.com/docs/#/displaying/). For example, if you want to display only the year of a time field, the format string 'YYYY' can be used to show the calendar year (for example, 1999 or 2012). + +**Before Transformation:** + +| Timestamp | Event | +| ------------------- | ------------ | +| 1636678740000000000 | System Start | +| 1636678680000000000 | User Login | +| 1636678620000000000 | Data Updated | + +**After applying 'YYYY-MM-DD HH:mm:ss':** + +| Timestamp | Event | +| ------------------- | ------------ | +| 2021-11-12 14:25:40 | System Start | +| 2021-11-12 14:24:40 | User Login | +| 2021-11-12 14:23:40 | Data Updated | + +This transformation lets you tailor the time representation in your visualizations, providing flexibility and precision in displaying temporal data. > **Note:** This transformation is available in Grafana 10.1+ as an alpha feature. @@ -544,7 +592,7 @@ And we can add more than one calculation. For instance: - For field Server Status, we can calculate the _Last_ value to know what is the last state value for each server - For field Temperature, we can also calculate the _Last_ value to know what is the latest monitored temperature for each server -We would then get : +We would then get: | Server ID | CPU Temperature (mean) | CPU Temperature (last) | Time (last) | Server Status (last) | | --------- | ---------------------- | ---------------------- | ------------------- | -------------------- | @@ -552,11 +600,11 @@ We would then get : | server 2 | 88.6 | 90 | 2020-07-07 10:32:20 | Overload | | server 3 | 59.6 | 62 | 2020-07-07 11:34:20 | OK | -This transformation enables you to extract key information from your time series and display it in a convenient way. +This transformation allows you to extract essential information from your time series and present it conveniently. ### Grouping to matrix -Use this transformation to combine three fields-that will be used as input for the **Column**, **Row**, and **Cell value** fields-from the query output, and generate a matrix. This matrix will be calculated as follows: +Use this transformation to combine three fields—which are used as input for the **Column**, **Row**, and **Cell value** fields from the query output—and generate a matrix. The matrix is calculated as follows: **Original data** @@ -576,32 +624,46 @@ We can generate a matrix using the values of 'Server Status' as column names, th | server 2 | 88.6 | | | server 3 | | 59.6 | +Use this transformation to construct a matrix by specifying fields from your query results. The matrix output reflects the relationships between the unique values in these fields. This helps you present complex relationships in a clear and structured matrix format. + ### Create heatmap -Use this transformation to prepare histogram data to be visualized over time. Similar to the Heatmap panel, this transformation allows you to convert histogram metrics to buckets over time. +Use this transformation to prepare histogram data for visualizing trends over time. Similar to the heatmap visualization, this transformation converts histogram metrics into temporal buckets. #### X Bucket This setting determines how the x-axis is split into buckets. -- **Size** - Specify a time interval in the input field. For example, a time range of '1h' makes the cells one hour wide on the x-axis. -- **Count** - For non-time related series, use this option to define the number of elements in a bucket. +- **Size** - Specify a time interval in the input field. For example, a time range of '1h' creates cells one hour wide on the x-axis. +- **Count** - For non-time-related series, use this option to define the number of elements in a bucket. #### Y Bucket This setting determines how the y-axis is split into buckets. - **Linear** -- **Logarithmic** - Use a base 2 or base 10. -- **Symlog** - A symmetrical logarithmic scale. Use a base 2 or base 10; allows negative values. +- **Logarithmic** - Choose between log base 2 or log base 10. +- **Symlog** - Uses a symmetrical logarithmic scale. Choose between log base 2 or log base 10, allowing for negative values. + +Assume you have the following dataset: + +| Timestamp | Value | +| ------------------- | ----- | +| 2023-01-01 12:00:00 | 5 | +| 2023-01-01 12:15:00 | 10 | +| 2023-01-01 12:30:00 | 15 | +| 2023-01-01 12:45:00 | 8 | + +- With X Bucket set to 'Size: 15m' and Y Bucket as 'Linear', the histogram organizes values into time intervals of 15 minutes on the x-axis and linearly on the y-axis. +- For X Bucket as 'Count: 2' and Y Bucket as 'Logarithmic (base 10)', the histogram groups values into buckets of two on the x-axis and use a logarithmic scale on the y-axis. ### Histogram -Use this transformation to generate a histogram based on the input data. +Use this transformation to generate a histogram based on input data, allowing you to visualize the distribution of values. -- **Bucket size** - The distance between the lowest item in the bucket (xMin) and the highest item in the bucket (xMax). -- **Bucket offset** - The offset for non-zero based buckets. -- **Combine series** - Create a histogram using all the available series. +- **Bucket size** - The range between the lowest and highest items in a bucket (xMin to xMax). +- **Bucket offset** - The offset for non-zero-based buckets. +- **Combine series** - Create a unified histogram using all available series. **Original data** @@ -639,21 +701,23 @@ Series 2: | 8 | 9 | 0 | 0 | 1 | 1 | | 9 | 10 | 0 | 0 | 1 | 1 | +Visualize the distribution of values using the generated histogram, providing insights into the data's spread and density. + ### Join by field -Use this transformation to join multiple results into a single table. This is especially useful for converting multiple -time series results into a single wide table with a shared time field. +Use this transformation to merge multiple results into a single table, enabling the consolidation of data from different queries. + +This is especially useful for converting multiple time series results into a single wide table with a shared time field. #### Inner join -An inner join merges data from multiple tables where all tables share the same value from the selected field. This type of join excludes -data where values do not match in every result. +An inner join merges data from multiple tables where all tables share the same value from the selected field. This type of join excludes data where values do not match in every result. Use this transformation to combine the results from multiple queries (combining on a passed join field or the first time column) into one result, and drop rows where a successful join cannot occur. In the following example, two queries return table data. It is visualized as two separate tables before applying the inner join transformation. -Query A: +**Query A:** | Time | Job | Uptime | | ------------------- | ------- | --------- | @@ -661,7 +725,7 @@ Query A: | 2020-07-07 11:24:20 | postgre | 123001233 | | 2020-07-07 11:14:20 | postgre | 345001233 | -Query B: +**Query B:** | Time | Server | Errors | | ------------------- | -------- | ------ | @@ -682,7 +746,7 @@ An outer join includes all data from an inner join and rows where values do not In the following example, two queries return table data. It is visualized as two tables before applying the outer join transformation. -Query A: +**Query A:** | Time | Job | Uptime | | ------------------- | ------- | --------- | @@ -690,7 +754,7 @@ Query A: | 2020-07-07 11:24:20 | postgre | 123001233 | | 2020-07-07 11:14:20 | postgre | 345001233 | -Query B: +**Query B:** | Time | Server | Errors | | ------------------- | -------- | ------ | @@ -709,16 +773,19 @@ The result after applying the outer join transformation looks like the following In the following example, a template query displays time series data from multiple servers in a table visualization. The results of only one query can be viewed at a time. -{{< figure src="/static/img/docs/transformations/join-fields-before-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/join-fields-before-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A table visualization showing results for one server" >}} I applied a transformation to join the query results using the time field. Now I can run calculations, combine, and organize the results in this new table. -{{< figure src="/static/img/docs/transformations/join-fields-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/join-fields-after-7-0.png" class="docs-image--no-shadow" max-width= "1100px" alt="A table visualization showing results for multiple servers" >}} + +Combine and analyze data from various queries with table joining for a comprehensive view of your information. ### Join by labels -Use this transformation to join multiple results into a single table. This is especially useful for converting multiple -time series results into a single wide table with a shared **Label** field. +Use this transformation to join multiple results into a single table. + +This is especially useful for converting multiple time series results into a single wide table with a shared **Label** field. - **Join** - Select the label to join by between the labels available or common across all time series. - **Value** - The name for the output result. @@ -761,9 +828,11 @@ value: "what" | B | J1 | 10 | 22 | | B | J1 | 200 | 77 | +Combine and organize time series data effectively with this transformation for comprehensive insights. + ### Labels to fields -Use this transformation to change time series results that include labels or tags into a table where each label's keys and values are included in the table result. The labels can be displayed as either columns or row values. +Use this transformation to convert time series results with labels or tags into a table, including each label's keys and values in the result. Display labels as either columns or row values for enhanced data visualization. Given a query result of two time series: @@ -823,11 +892,13 @@ After merge: | 2020-07-07 11:34:20 | ServerA | 10 | | | 2020-07-07 11:34:20 | | 20 | EU | +Convert your time series data into a structured table format for a clearer and more organized representation. + ### Limit -Use this transformation to limit the number of rows displayed. +Use this transformation to restrict the number of rows displayed, providing a more focused view of your data. This is particularly useful when dealing with large datasets. -In the example below, we have the following response from the data source: +Below is an example illustrating the impact of the **Limit** transformation on a response from a data source: | Time | Metric | Value | | ------------------- | ----------- | ----- | @@ -846,20 +917,22 @@ Here is the result after adding a Limit transformation with a value of '3': | 2020-07-07 11:34:20 | Humidity | 22 | | 2020-07-07 10:32:20 | Humidity | 29 | -### Merge +This transformation helps you tailor the visual presentation of your data to focus on the most relevant information. + +### Merge series/tables -Use this transformation to combine the result from multiple queries into one single result. This is helpful when using the table panel visualization. Values that can be merged are combined into the same row. Values are mergeable if the shared fields contain the same data. For information, refer to [Table panel][]. +Use this transformation to combine the results from multiple queries into a single result, which is particularly useful when using the table panel visualization. This transformation merges values into the same row if the shared fields contain the same data. -In the example below, we have two queries returning table data. It is visualized as two separate tables before applying the transformation. +Here's an example illustrating the impact of the **Merge series/tables** transformation on two queries returning table data: -Query A: +**Query A:** | Time | Job | Uptime | | ------------------- | ------- | --------- | | 2020-07-07 11:34:20 | node | 25260122 | | 2020-07-07 11:24:20 | postgre | 123001233 | -Query B: +**Query B:** | Time | Job | Errors | | ------------------- | ------- | ------ | @@ -873,21 +946,45 @@ Here is the result after applying the Merge transformation. | 2020-07-07 11:34:20 | node | 15 | 25260122 | | 2020-07-07 11:24:20 | postgre | 5 | 123001233 | -### Oraganize fields +This transformation combines values from Query A and Query B into a unified table, enhancing the presentation of data for better insights. + +### Organize fields by name + +Use this transformation to provide the flexibility to rename, reorder, or hide fields returned by a single query in your panel. This transformation is applicable only to panels with a single query. If your panel has multiple queries, consider using an "Outer join" transformation or removing extra queries. + +#### Transforming fields + +Grafana displays a list of fields returned by the query, allowing you to perform the following actions: + +- **Change field order** - Hover over a field, and when your cursor turns into a hand, drag the field to its new position. +- **Hide or show a field** - Use the eye icon next to the field name to toggle the visibility of a specific field. +- **Rename fields** - Type a new name in the "Rename " box to customize field names. -Use this transformation to rename, reorder, or hide fields returned by the query. +#### Example: -> **Note:** This transformation only works in panels with a single query. If your panel has multiple queries, then you must either apply an Outer join transformation or remove the extra queries. +##### Original Query Result -Grafana displays a list of fields returned by the query. You can: +| Time | Metric | Value | +| ------------------- | ----------- | ----- | +| 2020-07-07 11:34:20 | Temperature | 25 | +| 2020-07-07 11:34:20 | Humidity | 22 | +| 2020-07-07 10:32:20 | Humidity | 29 | -- Change field order by hovering your cursor over a field. The cursor turns into a hand and then you can drag the field to its new place. -- Hide or show a field by clicking the eye icon next to the field name. -- Rename fields by typing a new name in the **Rename ** box. +##### After Applying Field Overrides + +| Time | Sensor | Reading | +| ------------------- | ----------- | ------- | +| 2020-07-07 11:34:20 | Temperature | 25 | +| 2020-07-07 11:34:20 | Humidity | 22 | +| 2020-07-07 10:32:20 | Humidity | 29 | + +This transformation lets you to tailor the display of query results, ensuring a clear and insightful representation of your data in Grafana. ### Partition by values -Use this transformation to eliminate the need for multiple queries to the same data source with different 'WHERE' clauses when graphing multiple series. Consider a metrics SQL table with the following data: +Use this transformation to streamline the process of graphing multiple series without the need for multiple queries with different 'WHERE' clauses. + +This is particularly useful when dealing with a metrics SQL table, as illustrated below: | Time | Region | Value | | ------------------- | ------ | ----- | @@ -896,14 +993,7 @@ Use this transformation to eliminate the need for multiple queries to the same d | 2022-10-20 01:00:00 | US | 1327 | | 2022-10-20 01:00:00 | EU | 912 | -Prior to v9.3, if you wanted to plot a red trendline for US and a blue one for EU in the same TimeSeries panel, you would likely have to split this into two queries: - -'SELECT Time, Value FROM metrics WHERE Time > "2022-10-20" AND Region="US"'
    -'SELECT Time, Value FROM metrics WHERE Time > "2022-10-20" AND Region="EU"' - -This also requires you to know ahead of time which regions actually exist in the metrics table. - -With the _Partition by values_ transformer, you can now issue a single query and split the results by unique values in one or more columns ('fields') of your choosing. The following example uses 'Region'. +With the **Partition by values** transformation, you can issue a single query and split the results by unique values in one or more columns (fields) of your choosing. The following example uses 'Region': 'SELECT Time, Region, Value FROM metrics WHERE Time > "2022-10-20"' @@ -917,32 +1007,70 @@ With the _Partition by values_ transformer, you can now issue a single query and | 2022-10-20 12:00:00 | EU | 2936 | | 2022-10-20 01:00:00 | EU | 912 | +This transformation simplifies the process and enhances the flexibility of visualizing multiple series within the same time series visualization. + ### Prepare time series -Use this transformation when a data source returns time series data in a format that isn't supported by the panel you want to use. For more information about data frame formats, refer to [Data frames][]. +Use this transformation to address issues when a data source returns time series data in a format that isn't compatible with the desired visualization. This transformation allows you to convert time series data between wide and long formats, providing flexibility in data frame structures. + +#### Available options + +##### Multi-frame time series + +Use this option to transform the time series data frame from the wide format to the long format. This is particularly helpful when your data source delivers time series information in a format that needs to be reshaped for optimal compatibility with your visualization. + +**Example: Converting from wide to long format** + +| Timestamp | Value1 | Value2 | +| ------------------- | ------ | ------ | +| 2023-01-01 00:00:00 | 10 | 20 | +| 2023-01-01 01:00:00 | 15 | 25 | + +**Transformed to:** + +| Timestamp | Variable | Value | +| ------------------- | -------- | ----- | +| 2023-01-01 00:00:00 | Value1 | 10 | +| 2023-01-01 00:00:00 | Value2 | 20 | +| 2023-01-01 01:00:00 | Value1 | 15 | +| 2023-01-01 01:00:00 | Value2 | 25 | + +##### Wide time series -This transformation helps you resolve this issue by converting the time series data from either the wide format to the long format or the other way around. +Select this option to transform the time series data frame from the long format to the wide format. If your data source returns time series data in a long format and your visualization requires a wide format, this transformation simplifies the process. -Select the 'Multi-frame time series' option to transform the time series data frame from the wide to the long format. +**Example: Converting from long to wide format** -Select the 'Wide time series' option to transform the time series data frame from the long to the wide format. +| Timestamp | Variable | Value | +| ------------------- | -------- | ----- | +| 2023-01-01 00:00:00 | Value1 | 10 | +| 2023-01-01 00:00:00 | Value2 | 20 | +| 2023-01-01 01:00:00 | Value1 | 15 | +| 2023-01-01 01:00:00 | Value2 | 25 | + +**Transformed to:** + +| Timestamp | Value1 | Value2 | +| ------------------- | ------ | ------ | +| 2023-01-01 00:00:00 | 10 | 20 | +| 2023-01-01 01:00:00 | 15 | 25 | > **Note:** This transformation is available in Grafana 7.5.10+ and Grafana 8.0.6+. ### Reduce -Use this transformation to apply a calculation to each field in the frame and return a single value. Time fields are removed when applying this transformation. +Use this transformation to apply a calculation to each field in the data frame and return a single value. This transformation is particularly useful for consolidating multiple time series data into a more compact, summarized format. Time fields are removed when applying this transformation. Consider the input: -Query A: +**Query A:** | Time | Temp | Uptime | | ------------------- | ---- | ------- | | 2020-07-07 11:34:20 | 12.3 | 256122 | | 2020-07-07 11:24:20 | 15.4 | 1230233 | -Query B: +**Query B:** | Time | AQI | Errors | | ------------------- | --- | ------ | @@ -951,8 +1079,8 @@ Query B: The reduce transformer has two modes: -- **Series to rows -** Creates a row for each field and a column for each calculation. -- **Reduce fields -** Keeps the existing frame structure, but collapses each field into a single value. +- **Series to rows** - Creates a row for each field and a column for each calculation. +- **Reduce fields** - Keeps the existing frame structure, but collapses each field into a single value. For example, if you used the **First** and **Last** calculation with a **Series to rows** transformation, then the result would be: @@ -967,18 +1095,20 @@ the result would be: The **Reduce fields** with the **Last** calculation, results in two frames, each with one row: -Query A: +**Query A:** | Temp | Uptime | | ---- | ------- | | 15.4 | 1230233 | -Query B: +**Query B:** | AQI | Errors | | --- | ------ | | 3.2 | 5 | +This flexible transformation simplifies the process of consolidating and summarizing data from multiple time series into a more manageable and organized format. + ### Rename by regex Use this transformation to rename parts of the query results using a regular expression and replacement pattern. @@ -987,17 +1117,19 @@ You can specify a regular expression, which is only applied to matches, along wi In the following example, we are stripping the prefix from event types. In the before image, you can see everything is prefixed with 'system.' -{{< figure src="/static/img/docs/transformations/rename-by-regex-before-7-3.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/rename-by-regex-before-7-3.png" class="docs-image--no-shadow" max-width= "1100px" alt="A bar chart with long series names" >}} With the transformation applied, you can see we are left with just the remainder of the string. -{{< figure src="/static/img/docs/transformations/rename-by-regex-after-7-3.png" class="docs-image--no-shadow" max-width= "1100px" >}} +{{< figure src="/static/img/docs/transformations/rename-by-regex-after-7-3.png" class="docs-image--no-shadow" max-width= "1100px" alt="A bar chart with shortened series names" >}} + +This transformation lets you to tailor your data to meet your visualization needs, making your dashboards more informative and user-friendly. ### Rows to fields Use this transformation to convert rows into separate fields. This can be useful because fields can be styled and configured individually. It can also use additional fields as sources for dynamic field configuration or map them to field labels. The additional labels can then be used to define better display names for the resulting fields. -This transformation includes a field table which lists all fields in the data returned by the config query. This table gives you control over what field should be mapped to each config property (the \*Use as\*\* option). You can also choose which value to select if there are multiple rows in the returned data. +This transformation includes a field table which lists all fields in the data returned by the configuration query. This table gives you control over what field should be mapped to each configuration property (the **Use as** option). You can also choose which value to select if there are multiple rows in the returned data. This transformation requires: @@ -1019,14 +1151,14 @@ Useful when visualizing data in: If a field does not map to config property Grafana will automatically use it as source for a label on the output field- -Example: +**Example:** | Name | DataCenter | Value | | ------- | ---------- | ----- | | ServerA | US | 100 | | ServerB | EU | 200 | -Output: +**Output:** | ServerA (labels: DataCenter: US) | ServerB (labels: DataCenter: EU) | | -------------------------------- | -------------------------------- | @@ -1038,7 +1170,7 @@ If you want to extract config from one query and apply it to another you should #### Example -Input: +**Input:** | Name | Value | Max | | ------- | ----- | --- | @@ -1046,7 +1178,7 @@ Input: | ServerB | 20 | 200 | | ServerC | 30 | 300 | -Output: +**Output:** | ServerA (config: max=100) | ServerB (config: max=200) | ServerC (config: max=300) | | ------------------------- | ------------------------- | ------------------------- | @@ -1054,6 +1186,8 @@ Output: As you can see each row in the source data becomes a separate field. Each field now also has a max config option set. Options like **Min**, **Max**, **Unit** and **Thresholds** are all part of field configuration and if set like this will be used by the visualization instead of any options manually configured in the panel editor options pane. +This transformation enables the conversion of rows into individual fields, facilitates dynamic field configuration, and maps additional fields to labels. + ### Series to rows Use this transformation to combine the result from multiple time series data queries into one single result. This is helpful when using the table panel visualization. @@ -1062,7 +1196,7 @@ The result from this transformation will contain three columns: Time, Metric, an In the example below, we have two queries returning time series data. It is visualized as two separate tables before applying the transformation. -Query A: +**Query A:** | Time | Temperature | | ------------------- | ----------- | @@ -1070,7 +1204,7 @@ Query A: | 2020-07-07 10:31:22 | 22 | | 2020-07-07 09:30:05 | 19 | -Query B: +**Query B:** | Time | Humidity | | ------------------- | -------- | @@ -1089,30 +1223,68 @@ Here is the result after applying the Series to rows transformation. | 2020-07-07 09:30:57 | Humidity | 33 | | 2020-07-07 09:30:05 | Temperature | 19 | +This transformation facilitates the consolidation of results from multiple time series queries, providing a streamlined and unified dataset for efficient analysis and visualization in a tabular format. + > **Note:** This transformation is available in Grafana 7.1+. ### Sort by -Use this transformation to sort each frame by the configured field. When the **Reverse** switch is on, the values will return in the opposite order. +Use this transformation to sort each frame within a query result based on a specified field, making your data easier to understand and analyze. By configuring the desired field for sorting, you can control the order in which the data is presented in the table or visualization. + +Use the **Reverse** switch to inversely order the values within the specified field. This functionality is particularly useful when you want to quickly toggle between ascending and descending order to suit your analytical needs. + +For example, in a scenario where time-series data is retrieved from a data source, the **Sort by** transformation can be applied to arrange the data frames based on the timestamp, either in ascending or descending order, depending on the analytical requirements. This capability ensures that you can easily navigate and interpret time-series data, gaining valuable insights from the organized and visually coherent presentation. ### Spatial -Use this transformation to apply spatial operations to query results +Use this transformation to apply spatial operations to query results. + +- **Action** - Select an action: + - **Prepare spatial field** - Set a geometry field based on the results of other fields. + - **Location mode** - Select a location mode (these options are shared by the **Calculate value** and **Transform** modes): + - **Auto** - Automatically identify location data based on default field names. + - **Coords** - Specify latitude and longitude fields. + - **Geohash** - Specify a geohash field. + - **Lookup** - Specify Gazetteer location fields. + - **Calculate value** - Use the geometry to define a new field (heading/distance/area). + - **Function** - Choose a mathematical operation to apply to the geometry: + - **Heading** - Calculate the heading (direction) between two points. + - **Area** - Calculate the area enclosed by a polygon defined by the geometry. + - **Distance** - Calculate the distance between two points. + - **Transform** - Apply spatial operations to the geometry. + - **Operation** - Choose an operation to apply to the geometry: + - **As line** - Create a single line feature with a vertex at each row. + - **Line builder** - Create a line between two points. + +This transformation allows you to manipulate and analyze geospatial data, enabling operations such as creating lines between points, calculating spatial properties, and more. ### Time series to table transform -Use this transformation to convert time series result into a table, converting time series data frame into a "Trend" field. "Trend" field can then be rendered using [sparkline cell type][], producing an inline sparkline for each table row. If there are multiple time series queries, each will result in a separate table data frame. These can be joined using join or merge transforms to produce a single table with multiple sparklines per row. +Use this transformation to convert time series results into a table, transforming a time series data frame into a **Trend** field. The **Trend** field can then be rendered using the [sparkline cell type][], generating an inline sparkline for each table row. If there are multiple time series queries, each will result in a separate table data frame. These can be joined using join or merge transforms to produce a single table with multiple sparklines per row. + +For each generated **Trend** field value, a calculation function can be selected. The default is **Last non-null value**. This value is displayed next to the sparkline and used for sorting table rows. + +> **Note:** This transformation is available in Grafana 9.5+ as an opt-in beta feature. Modify the Grafana [configuration file][] to use it. + +### Regression analysis + +Use this transformation to create a new data frame containing values predicted by a statistical model. This is useful for finding a trend in chaotic data. It works by fitting a mathematical function to the data, using either linear or polynomial regression. The data frame can then be used in a visualization to display a trendline. + +There are two different models: -For each generated "Trend" field value calculation function can be selected. Default is "last non null value". This value will be displayed next to the sparkline and used for sorting table rows. +- **Linear regression** - Fits a linear function to the data. + {{< figure src="/static/img/docs/transformations/linear-regression.png" class="docs-image--no-shadow" max-width= "1100px" alt="A time series visualization with a straight line representing the linear function" >}} +- **Polynomial regression** - Fits a polynomial function to the data. + {{< figure src="/static/img/docs/transformations/polynomial-regression.png" class="docs-image--no-shadow" max-width= "1100px" alt="A time series visualization with a curved line representing the polynomial function" >}} -> **Note:** This transformation is available in Grafana 9.5+ as an opt-in beta feature. Modify Grafana [configuration file][] to use it. +> **Note:** This transformation is an experimental feature. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Enable the `regressionTransformation` feature toggle in Grafana to use this feature. Contact Grafana Support to enable this feature in Grafana Cloud. {{% docs/reference %}} [Table panel]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/visualizations/table" [Table panel]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/visualizations/table" -[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" [sparkline cell type]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/visualizations/table#sparkline" [sparkline cell type]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/visualizations/table#sparkline" diff --git a/docs/sources/panels-visualizations/visualizations/_index.md b/docs/sources/panels-visualizations/visualizations/_index.md index b2ad2318ce4d3..10042851d851b 100644 --- a/docs/sources/panels-visualizations/visualizations/_index.md +++ b/docs/sources/panels-visualizations/visualizations/_index.md @@ -12,7 +12,8 @@ labels: - enterprise - oss title: Visualizations -weight: 75 +description: Apply visualizations to your data +weight: 10 --- # Visualizations @@ -75,11 +76,11 @@ A [stat][] shows one large stat value with an optional graph sparkline. You can If you want to present a value as it relates to a min and max value you have two options. First a standard radial [gauge][] shown below. -{{< figure src="/static/img/docs/v66/gauge_panel_cover.png" max-width="700px" >}} +{{< figure src="/static/img/docs/v66/gauge_panel_cover.png" max-width="700px" alt="A gauge visualization" >}} Secondly Grafana also has a horizontal or vertical [bar gauge][] with three different distinct display modes. -{{< figure src="/static/img/docs/v66/bar_gauge_lcd.png" max-width="700px" >}} +{{< figure src="/static/img/docs/v66/bar_gauge_lcd.png" max-width="700px" alt="A bar gauge visualization" >}} ### Table diff --git a/docs/sources/panels-visualizations/visualizations/alert-list/index.md b/docs/sources/panels-visualizations/visualizations/alert-list/index.md index 3a94bc34b6e85..d16718efce575 100644 --- a/docs/sources/panels-visualizations/visualizations/alert-list/index.md +++ b/docs/sources/panels-visualizations/visualizations/alert-list/index.md @@ -16,6 +16,7 @@ labels: - enterprise - oss title: Alert list +description: Configure options for Grafana's alert list visualization weight: 100 --- @@ -23,7 +24,7 @@ weight: 100 Use alert lists to display your alerts. You can configure the list to show the current state. You can read more about alerts in [Grafana Alerting overview][]. -{{< figure src="/static/img/docs/alert-list-panel/alert-list-panel.png" max-width="850px" >}} +{{< figure src="/static/img/docs/alert-list-panel/alert-list-panel.png" max-width="850px" alt="An alert list visualization" >}} Customize your visualization using the following settings. diff --git a/docs/sources/panels-visualizations/visualizations/annotations/index.md b/docs/sources/panels-visualizations/visualizations/annotations/index.md index 77b10782a0e0d..a1940ebd7e36d 100644 --- a/docs/sources/panels-visualizations/visualizations/annotations/index.md +++ b/docs/sources/panels-visualizations/visualizations/annotations/index.md @@ -3,7 +3,7 @@ aliases: - ../../features/panels/annotations/ - ../../panels/visualizations/annotations/ - ../../visualizations/annotations/ -description: Annotations visualization documentation +description: Configure options for Grafana's annotations list visualization keywords: - grafana - Annotations diff --git a/docs/sources/panels-visualizations/visualizations/bar-chart/index.md b/docs/sources/panels-visualizations/visualizations/bar-chart/index.md index 5478aee90df93..753adfce32811 100644 --- a/docs/sources/panels-visualizations/visualizations/bar-chart/index.md +++ b/docs/sources/panels-visualizations/visualizations/bar-chart/index.md @@ -2,7 +2,7 @@ aliases: - ../../panels/visualizations/bar-chart/ - ../../visualizations/bar-chart/ -description: Bar chart visualization +description: Configure options for Grafana's bar chart visualization keywords: - grafana - docs @@ -195,8 +195,8 @@ You can set standard min/max options to define hard limits of the Y-axis. For mo [Add a field override]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/configure-overrides#add-a-field-override" [Add a field override]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/configure-overrides#add-a-field-override" -[standard calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[standard calculations]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[standard calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[standard calculations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" [Standard options definitions]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/configure-standard-options#max" [Standard options definitions]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/configure-standard-options#max" diff --git a/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md b/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md index 955229cf0db1f..c773210ef4241 100644 --- a/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md +++ b/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md @@ -3,7 +3,7 @@ aliases: - ../../features/panels/bar_gauge/ - ../../panels/visualizations/bar-gauge-panel/ - ../../visualizations/bar-gauge-panel/ -description: Bar gauge panel options +description: Configure options for Grafana's bar gauge visualization keywords: - grafana - bar @@ -91,19 +91,44 @@ This option only applies when the orientation of the bar gauge is horizontal. Wh Select this if you want to render the unfilled region of the bars as dark gray. Not applicable to Retro LCD display mode. +### Bar size + +Choose a bar size mode. + +- **Auto -** Grafana determines the best bar gauge size. +- **Manual -** Manually configure the bar gauge size. + ### Min width -Limit the minimum width of the bar column in the vertical direction. +Limit the minimum width of the bar column when the gauge is oriented vertically. + +Automatically show x-axis scrollbar when there's a large amount of data. -Automatically show x-axis scrollbar when there is a large amount of data. +{{% admonition type="note" %}} +This option only applies when bar size is set to manual. +{{% /admonition %}} ### Min height -Limit the minimum height of the bar row in the horizontal direction. +Limit the minimum height of the bar row when the gauge is oriented horizontally. -Automatically show y-axis scrollbar when there is a large amount of data. +Automatically show y-axis scrollbar when there's a large amount of data. + +{{% admonition type="note" %}} +This option only applies when bar size is set to manual. +{{% /admonition %}} + +### Max height + +Limit the maximum height of the bar row when the gauge is oriented horizontally. + +Automatically show y-axis scrollbar when there's a large amount of data. + +{{% admonition type="note" %}} +This option only applies when bar size is set to manual. +{{% /admonition %}} {{% docs/reference %}} -[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" {{% /docs/reference %}} diff --git a/docs/sources/panels-visualizations/visualizations/candlestick/index.md b/docs/sources/panels-visualizations/visualizations/candlestick/index.md index 12f0c9809882b..770ac1368d5b5 100644 --- a/docs/sources/panels-visualizations/visualizations/candlestick/index.md +++ b/docs/sources/panels-visualizations/visualizations/candlestick/index.md @@ -3,7 +3,7 @@ aliases: - ../../features/panels/candlestick/ - ../../panels/visualizations/candlestick/ - ../../visualizations/candlestick/ -description: Candlestick visualization documentation +description: Configure options for Grafana's candlestick visualization keywords: - grafana - Candlestick @@ -51,17 +51,29 @@ The **Up color** and **Down color** options select which colors are used when th ## Open, High, Low, Close -The candlestick visualization will attempt to map fields to the appropriate dimension. The **Open**, **High**, **Low**, and **Close** options allow you to map your data to these dimensions if the panel is unable to do so. - -{{% admonition type="note" %}} -These values are hidden from the legend. -{{% /admonition %}} +The candlestick visualization will attempt to map fields from your data to the appropriate dimension: - **Open** corresponds to the starting value of the given period. - **High** corresponds to the highest value of the given period. - **Low** corresponds to the lowest value of the given period. - **Close** corresponds to the final (end) value of the given period. -- **Volume** corresponds to the sample count in the given period. (e.g. number of trades) +- **Volume** corresponds to the sample count in the given period. (for example, number of trades) + +{{% admonition type="note" %}} +The candlestick visualization legend doesn't display these values. +{{% /admonition %}} + +To properly map these dimensions, the query results table from your data must include _at least_ the following columns: + +- timestamp +- open +- high +- low +- close + +If your data can't be mapped to these dimensions for some reason (for example, because the column names aren't the same), you can map them manually using the **Open**, **High**, **Low**, and **Close** fields under the **Candlestick** options in the panel editor: + +![Open, High, Low, and Close fields in the panel editor](/media/docs/grafana/panels-visualizations/screenshot-olhc-options-10.3.png) ## Additional fields diff --git a/docs/sources/panels-visualizations/visualizations/canvas/index.md b/docs/sources/panels-visualizations/visualizations/canvas/index.md index 1e69ccfeaa516..1b0b4e41ab1e1 100644 --- a/docs/sources/panels-visualizations/visualizations/canvas/index.md +++ b/docs/sources/panels-visualizations/visualizations/canvas/index.md @@ -2,7 +2,7 @@ aliases: - ../../features/panels/canvas/ - ../../visualizations/canvas/ -description: Canvas visualization documentation +description: Configure options for Grafana's canvas visualization keywords: - grafana - canvas diff --git a/docs/sources/panels-visualizations/visualizations/dashboard-list/index.md b/docs/sources/panels-visualizations/visualizations/dashboard-list/index.md index 7c67fbd26dbda..79461e4c0cec1 100644 --- a/docs/sources/panels-visualizations/visualizations/dashboard-list/index.md +++ b/docs/sources/panels-visualizations/visualizations/dashboard-list/index.md @@ -15,6 +15,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's dashboard list visualization title: Dashboard list weight: 100 --- @@ -23,7 +24,7 @@ weight: 100 Dashboard lists allow you to display dynamic links to other dashboards. The list can be configured to use starred dashboards, recently viewed dashboards, a search query, and dashboard tags. -{{< figure src="/static/img/docs/v45/dashboard-list-panels.png" max-width="850px">}} +{{< figure src="/static/img/docs/v45/dashboard-list-panels.png" max-width="850px" alt="A dashboard list visualization" >}} On each dashboard load, this panel queries the dashboard list, always providing the most up-to-date results. diff --git a/docs/sources/panels-visualizations/visualizations/datagrid/index.md b/docs/sources/panels-visualizations/visualizations/datagrid/index.md index af530fcaa3dd8..a74c3eb41eca1 100644 --- a/docs/sources/panels-visualizations/visualizations/datagrid/index.md +++ b/docs/sources/panels-visualizations/visualizations/datagrid/index.md @@ -3,7 +3,7 @@ aliases: - ../../features/panels/datagrid_panel/ - ../../reference/datagrid/ - ../../visualizations/datagrid/ -description: Learn about datagrid panel visualization features. +description: Configure options for Grafana's datagrid visualization keywords: - grafana - dashboard diff --git a/docs/sources/panels-visualizations/visualizations/flame-graph/index.md b/docs/sources/panels-visualizations/visualizations/flame-graph/index.md index 6b2adb29ed2b3..73af1e94cbd8a 100644 --- a/docs/sources/panels-visualizations/visualizations/flame-graph/index.md +++ b/docs/sources/panels-visualizations/visualizations/flame-graph/index.md @@ -12,6 +12,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's flame graph visualization title: Flame graph weight: 100 --- diff --git a/docs/sources/panels-visualizations/visualizations/gauge/index.md b/docs/sources/panels-visualizations/visualizations/gauge/index.md index 3e6975afb603e..b8da365a21d28 100644 --- a/docs/sources/panels-visualizations/visualizations/gauge/index.md +++ b/docs/sources/panels-visualizations/visualizations/gauge/index.md @@ -3,7 +3,7 @@ aliases: - ../../features/panels/gauge/ - ../../panels/visualizations/gauge-panel/ - ../../visualizations/gauge-panel/ -description: Gauge panel docs +description: Configure options for Grafana's gauge visualization keywords: - grafana - gauge @@ -21,7 +21,7 @@ weight: 100 Gauges are single-value visualizations that can repeat a gauge for every series, column or row. -{{< figure src="/static/img/docs/v66/gauge_panel_cover.png" max-width="1025px" >}} +{{< figure src="/static/img/docs/v66/gauge_panel_cover.png" max-width="1025px" alt="A gauge visualization">}} ## Value options @@ -65,18 +65,33 @@ Controls if threshold values are shown. Controls if a threshold band is shown outside the inner gauge value band. +### Gauge size + +Choose a gauge size mode. + +- **Auto -** Grafana determines the best gauge size. +- **Manual -** Manually configure the gauge size. + ### Min width Set the minimum width of vertically-oriented gauges. If you set a minimum width, the x-axis scrollbar is automatically displayed when there's a large amount of data. +{{% admonition type="note" %}} +This option only applies when gauge size is set to manual. +{{% /admonition %}} + ### Min height Set the minimum height of horizontally-oriented gauges. If you set a minimum height, the y-axis scrollbar is automatically displayed when there's a large amount of data. +{{% admonition type="note" %}} +This option only applies when gauge size is set to manual. +{{% /admonition %}} + ### Neutral Set the starting value from which every gauge will be filled. @@ -89,6 +104,6 @@ Adjust the sizes of the gauge text. - **Value -** Enter a numeric value for the gauge value size. {{% docs/reference %}} -[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" {{% /docs/reference %}} diff --git a/docs/sources/panels-visualizations/visualizations/geomap/index.md b/docs/sources/panels-visualizations/visualizations/geomap/index.md index c53ccb0535e35..ce21ee4262142 100644 --- a/docs/sources/panels-visualizations/visualizations/geomap/index.md +++ b/docs/sources/panels-visualizations/visualizations/geomap/index.md @@ -21,7 +21,7 @@ aliases: - ../../panels/visualizations/geomap/osm/ - ../../panels/visualizations/geomap/zyx/ - ../../visualizations/geomap/ -description: Geomap visualization documentation +description: Configure options for Grafana's geomap visualization keywords: - grafana - Geomap diff --git a/docs/sources/panels-visualizations/visualizations/heatmap/index.md b/docs/sources/panels-visualizations/visualizations/heatmap/index.md index 08eb5f4be3b03..68e51bdd3cb9d 100644 --- a/docs/sources/panels-visualizations/visualizations/heatmap/index.md +++ b/docs/sources/panels-visualizations/visualizations/heatmap/index.md @@ -2,7 +2,7 @@ aliases: - ../../features/panels/heatmap/ - ../../visualizations/heatmap/ -description: Heatmap visualization documentation +description: Configure options for Grafana's heatmap visualization keywords: - grafana - heatmap @@ -21,7 +21,7 @@ weight: 100 Heatmaps allow you to view histograms over time. For more information about histograms, refer to [Introduction to histograms and heatmaps][]. -![](/static/img/docs/v43/heatmap_panel_cover.jpg) +![A heatmap visualization](/static/img/docs/v43/heatmap_panel_cover.jpg) ## Calculate from data @@ -114,6 +114,7 @@ Use these settings to refine your visualization. - **Show tooltip -** Show heatmap tooltip. - **Show Histogram -** Show a Y-axis histogram on the tooltip. A histogram represents the distribution of the bucket values for a specific timestamp. +- **Show color scale -** Show a color scale on the tooltip. The color scale represents the mapping between bucket value and color. This option is configurable when you enable the `newVizTooltips` feature flag. ### Legend diff --git a/docs/sources/panels-visualizations/visualizations/histogram/index.md b/docs/sources/panels-visualizations/visualizations/histogram/index.md index 905549dc104fe..3c6c2cc13fb29 100644 --- a/docs/sources/panels-visualizations/visualizations/histogram/index.md +++ b/docs/sources/panels-visualizations/visualizations/histogram/index.md @@ -3,7 +3,7 @@ aliases: - ../../features/panels/histogram/ - ../../panels/visualizations/histogram/ - ../../visualizations/histogram/ -description: Histogram visualization +description: Configure options for Grafana's histogram visualization keywords: - grafana - docs @@ -83,6 +83,6 @@ Choose a [standard calculations][] to show in the legend. You can select more th [color scheme]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/configure-standard-options#color-scheme" [color scheme]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/configure-standard-options#color-scheme" -[standard calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[standard calculations]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[standard calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[standard calculations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" {{% /docs/reference %}} diff --git a/docs/sources/panels-visualizations/visualizations/logs/index.md b/docs/sources/panels-visualizations/visualizations/logs/index.md index 21a3b5ed0b61c..2068923c17428 100644 --- a/docs/sources/panels-visualizations/visualizations/logs/index.md +++ b/docs/sources/panels-visualizations/visualizations/logs/index.md @@ -15,6 +15,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's logs visualization title: Logs weight: 100 --- diff --git a/docs/sources/panels-visualizations/visualizations/news/index.md b/docs/sources/panels-visualizations/visualizations/news/index.md index f7d35116870f7..b38a82d628be3 100644 --- a/docs/sources/panels-visualizations/visualizations/news/index.md +++ b/docs/sources/panels-visualizations/visualizations/news/index.md @@ -13,6 +13,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's news visualization title: News weight: 100 --- diff --git a/docs/sources/panels-visualizations/visualizations/node-graph/index.md b/docs/sources/panels-visualizations/visualizations/node-graph/index.md index 7e7a3d2c588bf..96fe3cb7bfa2e 100644 --- a/docs/sources/panels-visualizations/visualizations/node-graph/index.md +++ b/docs/sources/panels-visualizations/visualizations/node-graph/index.md @@ -14,6 +14,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's node graph visualization title: Node graph weight: 100 --- diff --git a/docs/sources/panels-visualizations/visualizations/pie-chart/index.md b/docs/sources/panels-visualizations/visualizations/pie-chart/index.md index e3abe45f7cd82..c2bf7cf200c84 100644 --- a/docs/sources/panels-visualizations/visualizations/pie-chart/index.md +++ b/docs/sources/panels-visualizations/visualizations/pie-chart/index.md @@ -10,6 +10,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's pie chart visualization title: Pie chart weight: 100 --- @@ -109,6 +110,6 @@ Select values to display in the legend. You can select more than one. - **Value:** The raw numerical value. {{% docs/reference %}} -[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" {{% /docs/reference %}} diff --git a/docs/sources/panels-visualizations/visualizations/stat/index.md b/docs/sources/panels-visualizations/visualizations/stat/index.md index a53d31b00c526..81574aa5ae5b2 100644 --- a/docs/sources/panels-visualizations/visualizations/stat/index.md +++ b/docs/sources/panels-visualizations/visualizations/stat/index.md @@ -5,7 +5,7 @@ aliases: - ../../panels/visualizations/stat-panel/ - ../../reference/singlestat/ - ../../visualizations/stat-panel/ -description: Stat panel documentation +description: Configure options for Grafana's stat visualization keywords: - grafana - docs @@ -88,6 +88,17 @@ You can use the Text mode option to control what text the visualization renders. - **Name -** Show name instead of value. Value is displayed in the hover tooltip. - **None -** Show nothing (empty). Name and value are displayed in the hover tooltip. +### Wide layout + +Set whether wide layout is enabled or not. Wide layout is enabled by default. + +- **On -** Wide layout is enabled. +- **Off -** Wide layout is disabled. + +{{% admonition type="note" %}} +This option is only applicable when **Text mode** is set to **Value and name**. When wide layout is enabled, the value and name are displayed side-by-side with the value on the right, if the panel is wide enough. When wide layout is disabled, the value is always rendered underneath the name. +{{% /admonition %}} + ### Color mode Select a color mode. @@ -119,6 +130,6 @@ Adjust the sizes of the gauge text. - **Value -** Enter a numeric value for the gauge value size. {{% docs/reference %}} -[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[Calculation types]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[Calculation types]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" {{% /docs/reference %}} diff --git a/docs/sources/panels-visualizations/visualizations/state-timeline/index.md b/docs/sources/panels-visualizations/visualizations/state-timeline/index.md index c989233945f69..b7cf7ff472c23 100644 --- a/docs/sources/panels-visualizations/visualizations/state-timeline/index.md +++ b/docs/sources/panels-visualizations/visualizations/state-timeline/index.md @@ -2,7 +2,7 @@ aliases: - ../../panels/visualizations/state-timeline/ - ../../visualizations/state-timeline/ -description: State timeline visualization +description: Configure options for Grafana's state timeline visualization keywords: - grafana - docs diff --git a/docs/sources/panels-visualizations/visualizations/status-history/index.md b/docs/sources/panels-visualizations/visualizations/status-history/index.md index a5c48800184f8..b3e9c5e6837d6 100644 --- a/docs/sources/panels-visualizations/visualizations/status-history/index.md +++ b/docs/sources/panels-visualizations/visualizations/status-history/index.md @@ -2,7 +2,7 @@ aliases: - ../../panels/visualizations/status-history/ - ../../visualizations/status-history/ -description: Status history visualization +description: Configure options for Grafana's status history visualization keywords: - grafana - docs diff --git a/docs/sources/panels-visualizations/visualizations/table/index.md b/docs/sources/panels-visualizations/visualizations/table/index.md index 8459bf2b13f62..d78221b79d0af 100644 --- a/docs/sources/panels-visualizations/visualizations/table/index.md +++ b/docs/sources/panels-visualizations/visualizations/table/index.md @@ -6,7 +6,7 @@ aliases: - ../../visualizations/table/ - ../../visualizations/table/filter-table-columns/ - /docs/grafana/next/panels/visualizations/table/table-field-options/ -description: Learn about table panel visualization features. +description: Configure options for Grafana's table visualization keywords: - grafana - dashboard @@ -215,8 +215,8 @@ The system applies the calculation to all numeric fields if you do not select a If you want to show the number of rows in the dataset instead of the number of values in the selected fields, select the **Count** calculation and enable **Count rows**. {{% docs/reference %}} -[calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/calculation-types" -[calculations]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/calculation-types" +[calculations]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/calculation-types" +[calculations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/calculation-types" [time series to table]: "/docs/grafana/ -> /docs/grafana//panels-visualizations/query-transform-data/transform-data#time-series-to-table-transform" [time series to table]: "/docs/grafana-cloud/ -> /docs/grafana//panels-visualizations/query-transform-data/transform-data#time-series-to-table-transform" diff --git a/docs/sources/panels-visualizations/visualizations/text/index.md b/docs/sources/panels-visualizations/visualizations/text/index.md index 8095a2da643d7..eb003b96df1be 100644 --- a/docs/sources/panels-visualizations/visualizations/text/index.md +++ b/docs/sources/panels-visualizations/visualizations/text/index.md @@ -14,6 +14,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's text visualization title: Text weight: 100 --- diff --git a/docs/sources/panels-visualizations/visualizations/time-series/index.md b/docs/sources/panels-visualizations/visualizations/time-series/index.md index 209df93cf86e7..ace758155b924 100644 --- a/docs/sources/panels-visualizations/visualizations/time-series/index.md +++ b/docs/sources/panels-visualizations/visualizations/time-series/index.md @@ -29,6 +29,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's time series visualization title: Time series weight: 10 --- diff --git a/docs/sources/panels-visualizations/visualizations/traces/index.md b/docs/sources/panels-visualizations/visualizations/traces/index.md index 8b0e85c4c0d26..fa2ecb9098944 100644 --- a/docs/sources/panels-visualizations/visualizations/traces/index.md +++ b/docs/sources/panels-visualizations/visualizations/traces/index.md @@ -12,6 +12,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's traces visualization title: Traces weight: 100 --- diff --git a/docs/sources/panels-visualizations/visualizations/trend/index.md b/docs/sources/panels-visualizations/visualizations/trend/index.md index be40fe985e849..c7ae5cef5e4c3 100644 --- a/docs/sources/panels-visualizations/visualizations/trend/index.md +++ b/docs/sources/panels-visualizations/visualizations/trend/index.md @@ -12,6 +12,7 @@ labels: - cloud - enterprise - oss +description: Configure options for Grafana's trend visualization title: Trend weight: 100 --- diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 7f50adfce3da8..a4a0ea3888968 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -148,11 +148,19 @@ Options are `production` and `development`. Default is `production`. _Do not_ ch Set the name of the grafana-server instance. Used in logging, internal metrics, and clustering info. Defaults to: `${HOSTNAME}`, which will be replaced with environment variable `HOSTNAME`, if that is empty or does not exist Grafana will try to use system calls to get the machine name. -### force_migration +## force_migration -Force migration will run migrations that might cause data loss. Default is `false`. +{{% admonition type="note" %}} +This option is deprecated - [See `clean_upgrade` option]({{< relref "#clean_upgrade" >}}) instead. +{{% /admonition %}} + +When you restart Grafana to rollback from Grafana Alerting to legacy alerting, delete any existing Grafana Alerting data, such as alert rules, contact points, and notification policies. Default is `false`. -Set force_migration=true in your grafana.ini and restart Grafana to roll back and delete Unified Alerting configuration data. Any alert rules created while using Unified Alerting will be deleted by rolling back. +If `false` or unset, existing Grafana Alerting data is not changed or deleted when rolling back to legacy alerting. + +{{% admonition type="note" %}} +It should be kept false or unset when not needed, as it may cause unintended data loss if left enabled. +{{% /admonition %}}
    @@ -518,8 +526,7 @@ Sets a custom value for the `User-Agent` header for outgoing data proxy requests ### enabled -This option is also known as _usage analytics_. When `false`, this option disables the writers that read/write from and to the Grafana databases. The default -value is `true`. +This option is also known as _usage analytics_. When `false`, this option disables the writers that write to the Grafana database and the associated features, such as dashboard and data source insights, presence indicators, and advanced dashboard search. The default value is `true`. ### reporting_enabled @@ -1490,7 +1497,7 @@ For more information about the Grafana alerts, refer to [About Grafana Alerting] ### enabled -Enable or disable Grafana Alerting. If disabled, all your legacy alerting data will be available again, but the data you created using Grafana Alerting will be deleted. Set force_migration=true to avoid deletion of data. The default value is `true`. +Enable or disable Grafana Alerting. If disabled, all your legacy alerting data will be available again. The default value is `true`. Alerting Rules migrated from dashboards and panels will include a link back via the `annotations`. @@ -1510,6 +1517,34 @@ Specify the frequency of polling for Alertmanager config changes. The default va The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. +### ha_redis_address + +The Redis server address that should be connected to. + +### ha_redis_username + +The username that should be used to authenticate with the Redis server. + +### ha_redis_password + +The password that should be used to authenticate with the Redis server. + +### ha_redis_db + +The Redis database. The default value is `0`. + +### ha_redis_prefix + +A prefix that is used for every key or channel that is created on the Redis server as part of HA for alerting. + +### ha_redis_peer_name + +The name of the cluster peer that will be used as an identifier. If none is provided, a random one will be generated. + +### ha_redis_max_conns + +The maximum number of simultaneous Redis connections. + ### ha_listen_address Listen IP address and port to receive unified alerting messages for other Grafana instances. The port is used for both TCP and UDP. It is assumed other Grafana instances are also running on the same port. The default value is `0.0.0.0:9094`. @@ -1530,6 +1565,10 @@ each instance wait before sending the notification to take into account replicat The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. +### ha_label + +The label is an optional string to include on each packet and stream. It uniquely identifies the cluster and prevents cross-communication issues when sending gossip messages in an environment with multiple clusters. + ### ha_gossip_interval The interval between sending gossip messages. By lowering this value (more frequent) gossip messages are propagated @@ -1550,13 +1589,13 @@ Enable or disable alerting rule execution. The default value is `true`. The aler ### evaluation_timeout -Sets the alert evaluation timeout when fetching data from the datasource. The default value is `30s`. This option has a [legacy version in the alerting section]({{< relref "#evaluation_timeout_seconds" >}}) that takes precedence. +Sets the alert evaluation timeout when fetching data from the data source. The default value is `30s`. This option has a [legacy version in the alerting section]({{< relref "#evaluation_timeout_seconds" >}}) that takes precedence. The timeout string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m. ### max_attempts -Sets a maximum number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is `3`. This option has a [legacy version in the alerting section]({{< relref "#max_attempts-1" >}}) that takes precedence. +Sets a maximum number of times we'll attempt to evaluate an alert rule before giving up on that evaluation. The default value is `1`. ### min_interval @@ -1598,6 +1637,22 @@ For example: `disabled_labels=grafana_folder`
    +## [unified_alerting.upgrade] + +For more information about upgrading to Grafana Alerting, refer to [Upgrade Alerting](/docs/grafana/next/alerting/set-up/migrating-alerts/). + +### clean_upgrade + +When you restart Grafana to upgrade from legacy alerting to Grafana Alerting, delete any existing Grafana Alerting data from a previous upgrade, such as alert rules, contact points, and notification policies. Default is `false`. + +If `false` or unset, existing Grafana Alerting data is not changed or deleted when you switch between legacy and Unified Alerting. + +{{% admonition type="note" %}} +It should be kept false when not needed, as it may cause unintended data loss if left enabled. +{{% /admonition %}} + +
    + ## [alerting] For more information about the legacy dashboard alerting feature in Grafana, refer to [the legacy Grafana alerts](/docs/grafana/v8.5/alerting/old-alerting/). @@ -2271,6 +2326,14 @@ Instruct headless browser instance whether to output its debug and error message It can be useful to set this to `true` when troubleshooting. +### rendering_timing_metrics + +> **Note:** Available from grafana-image-renderer v3.9.0+ + +Instruct a headless browser instance on whether to record metrics for the duration of every rendering step. Default is `false`. + +Setting this to `true` when optimizing the rendering mode settings to improve the plugin performance or when troubleshooting can be useful. + ### rendering_args Additional arguments to pass to the headless browser instance. Defaults are `--no-sandbox,--disable-gpu`. The list of Chromium flags can be found at (https://peter.sh/experiments/chromium-command-line-switches/). Separate multiple arguments with commas. @@ -2456,9 +2519,9 @@ Refer to [Role-based access control]({{< relref "../../administration/roles-and- ## [navigation.app_sections] -Move an app plugin (referenced by its id), including all its pages, to a specific navigation section. Format: = +Move an app plugin (referenced by its id), including all its pages, to a specific navigation section. Format: ` = ` ## [navigation.app_standalone_pages] Move an individual app plugin page (referenced by its `path` field) to a specific navigation section. -Format: = +Format: ` = ` diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 461521bb069d2..ee6ea77c3f93b 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -19,51 +19,47 @@ This page contains a list of available feature toggles. To learn how to turn on Some features are enabled by default. You can disable these feature by setting the feature flag to "false" in the configuration. -| Feature toggle name | Description | Enabled by default | -| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | | -| `publicDashboards` | Enables public access to dashboards | Yes | -| `featureHighlights` | Highlight Grafana Enterprise features | | -| `exploreContentOutline` | Content outline sidebar | Yes | -| `dataConnectionsConsole` | Enables a new top-level page called Connections. This page is an experiment that provides a better experience when you install and configure data sources and other plugins. | Yes | -| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes | -| `redshiftAsyncQueryDataSupport` | Enable async query data support for Redshift | Yes | -| `athenaAsyncQueryDataSupport` | Enable async query data support for Athena | Yes | -| `nestedFolderPicker` | Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle | Yes | -| `accessTokenExpirationCheck` | Enable OAuth access_token expiration check and token refresh using the refresh_token | | -| `emptyDashboardPage` | Enable the redesigned user interface of a dashboard page that includes no panels | Yes | -| `disablePrometheusExemplarSampling` | Disable Prometheus exemplar sampling | | -| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes | -| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes | -| `gcomOnlyExternalOrgRoleSync` | Prohibits a user from changing organization roles synced with Grafana Cloud auth provider | | -| `prometheusMetricEncyclopedia` | Adds the metrics explorer component to the Prometheus query builder as an option in metric select | Yes | -| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes | -| `prometheusDataplane` | Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label. | Yes | -| `lokiMetricDataplane` | Changes metric responses from Loki to be compliant with the dataplane specification. | Yes | -| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes | -| `alertingNotificationsPoliciesMatchingInstances` | Enables the preview of matching instances for notification policies | Yes | -| `useCachingService` | When active, the new query and resource caching implementation using a wire service inject replaces the previous middleware implementation. | Yes | -| `enableElasticsearchBackendQuerying` | Enable the processing of queries and responses in the Elasticsearch data source through backend | Yes | -| `advancedDataSourcePicker` | Enable a new data source picker with contextual information, recently used order and advanced mode | Yes | -| `cloudWatchLogsMonacoEditor` | Enables the Monaco editor for CloudWatch Logs queries | Yes | -| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes | -| `transformationsRedesign` | Enables the transformations redesign | Yes | -| `azureMonitorDataplane` | Adds dataplane compliant frame metadata in the Azure Monitor datasource | Yes | -| `prometheusConfigOverhaulAuth` | Update the Prometheus configuration page with the new auth component | Yes | -| `dashgpt` | Enable AI powered features in dashboards | Yes | -| `newBrowseDashboards` | New browse/manage dashboards UI | Yes | -| `alertingInsights` | Show the new alerting insights landing page | Yes | -| `cloudWatchWildCardDimensionValues` | Fetches dimension values from CloudWatch to correctly label wildcard dimensions | Yes | +| Feature toggle name | Description | Enabled by default | +| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | | +| `publicDashboards` | Enables public access to dashboards | Yes | +| `featureHighlights` | Highlight Grafana Enterprise features | | +| `exploreContentOutline` | Content outline sidebar | Yes | +| `newVizTooltips` | New visualizations tooltips UX | | +| `dataConnectionsConsole` | Enables a new top-level page called Connections. This page is an experiment that provides a better experience when you install and configure data sources and other plugins. | Yes | +| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes | +| `redshiftAsyncQueryDataSupport` | Enable async query data support for Redshift | Yes | +| `athenaAsyncQueryDataSupport` | Enable async query data support for Athena | Yes | +| `nestedFolderPicker` | Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle | Yes | +| `accessTokenExpirationCheck` | Enable OAuth access_token expiration check and token refresh using the refresh_token | | +| `emptyDashboardPage` | Enable the redesigned user interface of a dashboard page that includes no panels | Yes | +| `disablePrometheusExemplarSampling` | Disable Prometheus exemplar sampling | | +| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes | +| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes | +| `prometheusMetricEncyclopedia` | Adds the metrics explorer component to the Prometheus query builder as an option in metric select | Yes | +| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes | +| `clientTokenRotation` | Replaces the current in-request token rotation so that the client initiates the rotation | Yes | +| `prometheusDataplane` | Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label. | Yes | +| `lokiMetricDataplane` | Changes metric responses from Loki to be compliant with the dataplane specification. | Yes | +| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes | +| `useCachingService` | When active, the new query and resource caching implementation using a wire service inject replaces the previous middleware implementation. | Yes | +| `enableElasticsearchBackendQuerying` | Enable the processing of queries and responses in the Elasticsearch data source through backend | Yes | +| `advancedDataSourcePicker` | Enable a new data source picker with contextual information, recently used order and advanced mode | Yes | +| `cloudWatchLogsMonacoEditor` | Enables the Monaco editor for CloudWatch Logs queries | Yes | +| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes | +| `transformationsRedesign` | Enables the transformations redesign | Yes | +| `prometheusConfigOverhaulAuth` | Update the Prometheus configuration page with the new auth component | Yes | +| `alertingInsights` | Show the new alerting insights landing page | Yes | +| `cloudWatchWildCardDimensionValues` | Fetches dimension values from CloudWatch to correctly label wildcard dimensions | Yes | +| `displayAnonymousStats` | Enables anonymous stats to be shown in the UI for Grafana | Yes | ## Preview feature toggles | Feature toggle name | Description | | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `trimDefaults` | Use cue schema to remove values that will be applied automatically | | `panelTitleSearch` | Search for dashboards using panel title | | `migrationLocking` | Lock database during migrations | | `correlations` | Correlations page | -| `newDBLibrary` | Use jmoiron/sqlx rather than xorm for a few backend services | | `autoMigrateOldPanels` | Migrate old angular panels to supported versions (graph, table-old, worldmap, etc) | | `disableAngular` | Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime. | | `grpcServer` | Run the GRPC server | @@ -74,12 +70,12 @@ Some features are enabled by default. You can disable these feature by setting t | `refactorVariablesTimeRange` | Refactor time range variables flow to reduce number of API calls made when query variables are chained | | `faroDatasourceSelector` | Enable the data source selector within the Frontend Apps section of the Frontend Observability | | `enableDatagridEditing` | Enables the edit functionality in the datagrid panel | -| `dataSourcePageHeader` | Apply new pageHeader UI in data source edit page | | `sqlDatasourceDatabaseSelection` | Enables previous SQL data source dataset dropdown behavior | | `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the `useCachingService` feature toggle is enabled and the datasource has caching and async query support enabled | | `splitScopes` | Support faster dashboard and folder search by splitting permission scopes into parts | +| `dashgpt` | Enable AI powered features in dashboards | | `reportingRetries` | Enables rendering retries for the reporting feature | -| `alertingContactPointsV2` | Show the new contacpoints list view | +| `transformationsVariableSupport` | Allows using variables in transformations | | `cloudWatchBatchQueries` | Runs CloudWatch metrics queries as separate batches | ## Experimental feature toggles @@ -107,7 +103,7 @@ Experimental features might be changed or removed without prior notice. | `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files | | `lokiQuerySplittingConfig` | Give users the option to configure split durations for Loki queries | | `individualCookiePreferences` | Support overriding cookie preferences per user | -| `clientTokenRotation` | Replaces the current in-request token rotation so that the client initiates the rotation | +| `influxqlStreamingParser` | Enable streaming JSON parser for InfluxDB datasource InfluxQL query language | | `lokiLogsDataplane` | Changes logs responses from Loki to be compliant with the dataplane specification. | | `disableSSEDataplane` | Disables dataplane specific processing in server side expressions. | | `alertStateHistoryLokiSecondary` | Enable Grafana to write alert state history to an external Loki instance in addition to Grafana annotations. | @@ -132,6 +128,8 @@ Experimental features might be changed or removed without prior notice. | `grafanaAPIServer` | Enable Kubernetes API Server for Grafana resources | | `grafanaAPIServerWithExperimentalAPIs` | Register experimental APIs with the k8s API server | | `featureToggleAdminPage` | Enable admin page for managing feature toggles from the Grafana front-end | +| `traceToProfiles` | Enables linking between traces and profiles | +| `tracesEmbeddedFlameGraph` | Enables embedding a flame graph in traces | | `permissionsFilterRemoveSubquery` | Alternative permission filter implementation that does not use subqueries for fetching the dashboard folder | | `influxdbSqlSupport` | Enable InfluxDB SQL query language support with new querying UI | | `angularDeprecationUI` | Display new Angular deprecation-related UI features | @@ -142,13 +140,14 @@ Experimental features might be changed or removed without prior notice. | `externalCorePlugins` | Allow core plugins to be loaded as external | | `pluginsAPIMetrics` | Sends metrics of public grafana packages usage by plugins | | `httpSLOLevels` | Adds SLO level to http request metrics | +| `idForwarding` | Generate signed id token for identity that can be forwarded to plugins and external services | | `panelMonitoring` | Enables panel monitoring through logs and measurements | | `enableNativeHTTPHistogram` | Enables native HTTP Histograms | | `formatString` | Enable format string transformer | -| `transformationsVariableSupport` | Allows using variables in transformations | -| `kubernetesPlaylists` | Use the kubernetes API in the frontend for playlists | -| `navAdminSubsections` | Splits the administration section of the nav tree into subsections | +| `kubernetesPlaylists` | Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s | +| `kubernetesSnapshots` | Use the kubernetes API in the frontend to support playlists | | `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | +| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | | `teamHttpHeaders` | Enables datasources to apply team headers to the client requests | | `awsDatasourcesNewFormStyling` | Applies new form styling for configuration and query editors in AWS plugins | | `cachingOptimizeSerializationMemoryUsage` | If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses. | @@ -156,19 +155,30 @@ Experimental features might be changed or removed without prior notice. | `costManagementUi` | Toggles the display of the cost management ui plugin | | `managedPluginsInstall` | Install managed plugins directly from plugins catalog | | `prometheusPromQAIL` | Prometheus and AI/ML to assist users in creating a query | +| `addFieldFromCalculationStatFunctions` | Add cumulative and window functions to the add field from calculation transformation | | `alertmanagerRemoteSecondary` | Enable Grafana to sync configuration and state with a remote Alertmanager. | | `alertmanagerRemotePrimary` | Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager. | | `alertmanagerRemoteOnly` | Disable the internal Alertmanager and only use the external one defined. | | `annotationPermissionUpdate` | Separate annotation permissions from dashboard permissions to allow for more granular control. | +| `extractFieldsNameDeduplication` | Make sure extracted field names are unique in the dataframe | +| `dashboardSceneForViewers` | Enables dashboard rendering using Scenes for viewer roles | +| `dashboardScene` | Enables dashboard rendering using scenes for all roles | +| `logsInfiniteScrolling` | Enables infinite scrolling for the Logs panel in Explore and Dashboards | +| `flameGraphItemCollapsing` | Allow collapsing of flame graph items | +| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | +| `pluginsSkipHostEnvVars` | Disables passing host environment variable to plugin processes | +| `tableSharedCrosshair` | Enables shared crosshair in table panel | +| `regressionTransformation` | Enables regression analysis transformation | ## Development feature toggles The following toggles require explicitly setting Grafana's [app mode]({{< relref "../_index.md#app_mode" >}}) to 'development' before you can enable this feature toggle. These features tend to be experimental. -| Feature toggle name | Description | -| ------------------------- | -------------------------------------------------------------------------------------------- | -| `entityStore` | SQL-based entity store (requires storage flag also) | -| `externalServiceAuth` | Starts an OAuth2 authentication provider for external services | -| `idForwarding` | Generate signed id token for identity that can be forwarded to plugins and external services | -| `externalServiceAccounts` | Automatic service account and token setup for plugins | -| `panelTitleSearchInV1` | Enable searching for dashboards using panel title in search v1 | +| Feature toggle name | Description | +| ------------------------------------- | -------------------------------------------------------------- | +| `unifiedStorage` | SQL-based k8s storage | +| `externalServiceAuth` | Starts an OAuth2 authentication provider for external services | +| `grafanaAPIServerEnsureKubectlAccess` | Start an additional https handler and write kubectl options | +| `externalServiceAccounts` | Automatic service account and token setup for plugins | +| `panelTitleSearchInV1` | Enable searching for dashboards using panel title in search v1 | +| `ssoSettingsApi` | Enables the SSO settings API | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md index 5ebd7f2d5d9b0..ab42698568193 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md @@ -205,10 +205,12 @@ disable_signout_menu = true ### URL redirect after signing out -URL to redirect the user to after signing out from Grafana. This can for example be used to enable signout from OAuth provider. +URL to redirect the user to after signing out from Grafana. This can for example be used to enable signout from an OAuth provider. + +Example for Generic OAuth: ```bash -[auth] +[auth.generic_oauth] signout_redirect_url = ``` diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md index 7c3d163a79aaf..b6d638d4e6dde 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md @@ -19,24 +19,7 @@ weight: 800 # Configure Azure AD OAuth2 authentication -The Azure AD authentication allows you to use an Azure Active Directory tenant as an identity provider for Grafana. You can use Azure AD Application Roles to assign users and groups to Grafana roles from the Azure Portal. This topic has the following sections: - -- [Configure Azure AD OAuth2 authentication](#configure-azure-ad-oauth2-authentication) - - [Create the Azure AD application](#create-the-azure-ad-application) - - [Assign server administrator privileges](#assign-server-administrator-privileges) - - [Enable Azure AD OAuth in Grafana](#enable-azure-ad-oauth-in-grafana) - - [Configure refresh token](#configure-refresh-token) - - [Configure allowed tenants](#configure-allowed-tenants) - - [Configure allowed groups](#configure-allowed-groups) - - [Configure allowed domains](#configure-allowed-domains) - - [PKCE](#pkce) - - [Configure automatic login](#configure-automatic-login) - - [Team Sync (Enterprise only)](#team-sync-enterprise-only) - - [Common troubleshooting](#common-troubleshooting) - - [Users with over 200 Group assignments](#users-with-over-200-group-assignments) - - [Force fetching groups from Microsoft graph API](#force-fetching-groups-from-microsoft-graph-api) - - [Map roles](#map-roles) - - [Skip organization role sync](#skip-organization-role-sync) +The Azure AD authentication allows you to use an Azure Active Directory tenant as an identity provider for Grafana. You can use Azure AD application roles to assign users and groups to Grafana roles from the Azure Portal. ## Create the Azure AD application @@ -66,9 +49,50 @@ To enable the Azure AD OAuth2, register your application with Azure AD. 1. Click **Add** then copy the key value. This is the OAuth client secret. -1. Click **Manifest**, then define the required Application Role values for Grafana: Viewer, Editor, or Admin. If not defined, all users will have the Viewer role. Every role requires a unique ID which you can generate on Linux with `uuidgen`, and on Windows through Microsoft PowerShell with `New-Guid`. +1. Define the required application roles for Grafana [using the Azure Portal](#configure-application-roles-for-grafana-in-the-azure-portal) or [using the manifest file](#configure-application-roles-for-grafana-in-the-manifest-file). -1. Include the unique ID in the configuration file: +1. Go to **Azure Active Directory** and then to **Enterprise Applications**. + +1. Search for your application and click it. + +1. Click **Users and Groups**. +1. Click **Add user/group** to add a user or group to the Grafana roles. + +#### Configure application roles for Grafana in the Azure Portal + +This section describes setting up basic application roles for Grafana within the Azure Portal. For more information, see [Add app roles to your application and receive them in the token](https://learn.microsoft.com/en-us/entra/identity-platform/howto-add-app-roles-in-apps). + +1. Go to **App Registrations**, search for your application, and click it. + +1. Click **App roles** and then **Create app role**. + +1. Define a role corresponding to each Grafana role: Viewer, Editor, and Admin. + + 1. Choose a **Display name** for the role. For example, "Grafana Editor". + + 1. Set the **Allowed member types** to **Users/Groups**. + + 1. Ensure that the **Value** field matches the Grafana role name. For example, "Editor". + + 1. Choose a **Description** for the role. For example, "Grafana Editor Users". + + 1. Click **Apply**. + +#### Configure application roles for Grafana in the manifest file + +If you prefer to configure the application roles for Grafana in the manifest file, complete the following steps: + +1. Go to **App Registrations**, search for your application, and click it. + +1. Click **Manifest** and then click **Edit**. + +1. Add a Universally Unique Identifier to each role. + +{{% admonition type="note" %}} +Every role requires a [Universally Unique Identifier](https://en.wikipedia.org/wiki/Universally_unique_identifier) which you can generate on Linux with `uuidgen`, and on Windows through Microsoft PowerShell with `New-Guid`. +{{% /admonition %}} + +1. Replace each "SOME_UNIQUE_ID" with the generated ID in the manifest file: ```json "appRoles": [ @@ -111,9 +135,7 @@ To enable the Azure AD OAuth2, register your application with Azure AD. ], ``` -1. Go to **Azure Active Directory** and then to **Enterprise Applications**. Search for your application and click on it. - -1. Click on **Users and Groups** and add Users/Groups to the Grafana roles by using **Add User**. +1. Click **Save**. ### Assign server administrator privileges @@ -141,7 +163,7 @@ If the setting is set to `false`, the user is assigned the role of `Admin` of th ## Enable Azure AD OAuth in Grafana -1. Add the following to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}): +Add the following to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}): ``` [auth.azuread] @@ -170,13 +192,17 @@ GF_AUTH_AZUREAD_CLIENT_ID GF_AUTH_AZUREAD_CLIENT_SECRET ``` -**Note:** Verify that the Grafana [root_url]({{< relref "../../../configure-grafana#root_url" >}}) is set in your Azure Application Redirect URLs. +{{% admonition type="note" %}} +Verify that the Grafana [root_url]({{< relref "../../../configure-grafana#root_url" >}}) is set in your Azure Application Redirect URLs. +{{% /admonition %}} ### Configure refresh token > Available in Grafana v9.3 and later versions. -> **Note:** This feature is behind the `accessTokenExpirationCheck` feature toggle. +{{% admonition type="note" %}} +This feature is behind the `accessTokenExpirationCheck` feature toggle. +{{% /admonition %}} When a user logs in using an OAuth provider, Grafana verifies that the access token has not expired. When an access token expires, Grafana uses the provided refresh token (if any exists) to obtain a new access token. @@ -184,7 +210,7 @@ Grafana uses a refresh token to obtain a new access token without requiring the Refresh token fetching and access token expiration check is enabled by default for the AzureAD provider since Grafana v10.1.0 if the `accessTokenExpirationCheck` feature toggle is enabled. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.2.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. ### Configure allowed tenants @@ -201,16 +227,44 @@ allowed_organizations = 8bab1c86-8fba-33e5-2089-1d1c80ec267d ### Configure allowed groups -To limit access to authenticated users who are members of one or more groups, set `allowed_groups` -to a comma- or space-separated list of group object IDs. You can find object IDs for a specific group on the Azure portal: +Azure AD groups can be used to limit user access to Grafana. For more information about managing groups in Azure AD, refer to [Manage Microsoft Entra groups and group membership](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-manage-groups). + +To limit access to authenticated users who are members of one or more AzureAD groups, set `allowed_groups` +to a **comma-** or **space-separated** list of group object IDs. -1. Go to **Azure Active Directory -> Groups**. If you want to only give access to members of the group `example` with an ID of `8bab1c86-8fba-33e5-2089-1d1c80ec267d`, then set the following: +1. To find object IDs for a specific group on the Azure portal, go to **Azure Active Directory > Groups**. + + You can find the Object Id of a group by clicking on the group and then clicking on **Properties**. The object ID is listed under **Object ID**. If you want to only give access to members of the group `example` with an Object Id of `8bab1c86-8fba-33e5-2089-1d1c80ec267d`, then set the following: ``` - allowed_groups = 8bab1c86-8fba-33e5-2089-1d1c80ec267d + allowed_groups = 8bab1c86-8fba-33e5-2089-1d1c80ec267d ``` -1. Verify that [group attributes](https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-fed-group-claims#configure-the-azure-ad-application-registration-for-group-attributes) is enabled in your Azure AD Application Registration manifest file by navigating to **Azure Portal** > **Azure Active Directory** > **Application Registrations** > **Select Application** -> **Manifest**, and set the following: +1. You must enable adding the [group attribute](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims#configure-groups-optional-claims) to the tokens in your Azure AD App registration either [from the Azure Portal](#configure-group-membership-claims-on-the-azure-portal) or [from the manifest file](#configure-group-membership-claim-in-the-manifest-file). + +#### Configure group membership claims on the Azure Portal + +To ensure that the `groups` claim is included in the token, add the `groups` claim to the token configuration either through the Azure Portal UI or by editing the manifest file. + +To configure group membership claims from the Azure Portal UI, complete the following steps: + +1. Navigate to the **App Registrations** page and select your application. +1. Select **Token configuration**. +1. Click **Add groups claim** and select the relevant option for your use case (for example, **Security groups** and **Groups assigned to the application**). + +For more information, see [Configure groups optional claims](https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims#configure-groups-optional-claims). + +{{% admonition type="note" %}} +If the user is a member of more than 200 groups, Azure AD does not emit the groups claim in the token and instead emits a group overage claim. To set up a group overage claim, see [Users with over 200 Group assignments](#users-with-over-200-group-assignments). +{{% /admonition %}} + +#### Configure group membership claim in the manifest file + +1. Go to **App Registrations**, search for your application, and click it. + +1. Click **Manifest** and then click **Edit**. + +1. Add the following to the root of the manifest file: ``` "groupMembershipClaims": "ApplicationGroup, SecurityGroup" @@ -271,8 +325,24 @@ Azure AD does not emit the groups claim in the token and emits a group overage c If Grafana receives a token with a group overage claim instead of a groups claim, Grafana attempts to retrieve the user's group membership by calling the included endpoint. -> Note: The token must include the `GroupMember.Read.All` permission for group overage claim calls to succeed. -> Admin consent may be required for this permission. +{{% admonition type="note" %}} +The 'App registration' must include the `GroupMember.Read.All` API permission for group overage claim calls to succeed. + +Admin consent might be required for this permission. +{{% /admonition %}} + +#### Configure the required Graph API permissions + +1. Navigate to **Azure Active Directory > App registrations** and select your application. +1. Select **API permissions** and then click on **Add a permission**. +1. Select **Microsoft Graph** from the list of APIs. +1. Select **Delegated permissions**. +1. Under the **GroupMember** section, select **GroupMember.Read.All**. +1. Click **Add permissions**. + +{{% admonition type="note" %}} +Admin consent may be required for this permission. +{{% /admonition %}} ### Force fetching groups from Microsoft graph API diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md index fb37aadfb1a2f..b2deba95f26f7 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md @@ -183,7 +183,7 @@ To configure generic OAuth2 to use a refresh token, set `use_refresh_token` conf 1. Extend the `scopes` field of `[auth.generic_oauth]` section in Grafana configuration file with additional scopes. 1. Enable the refresh token on the provider. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.2.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. ## Configure role mapping diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md index 9d92aaa5e9dfe..ac71e3aedb67d 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md @@ -79,7 +79,7 @@ The table below describes all GitHub OAuth configuration options. Like any other | `skip_org_role_sync` | No | Set to `true` to stop automatically syncing user roles. | `false` | | `allowed_organizations` | No | List of comma- or space-separated organizations. User must be a member of at least one organization to log in. | | | `allowed_domains` | No | List of comma- or space-separated domains. User must belong to at least one domain to log in. | | -| `team_ids` | No | String list of team IDs. If set, user has to be a member of one of the given teams to log in. | | +| `team_ids` | No | Integer list of team IDs. If set, user has to be a member of one of the given teams to log in. | | | `tls_skip_verify_insecure` | No | If set to `true`, the client accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks. | `false` | | `tls_client_cert` | No | The path to the certificate. | | | `tls_client_key` | No | The path to the key. | | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md index 3b0a69f3481f6..ba06e0b33c779 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md @@ -109,7 +109,7 @@ By default, GitLab provides a refresh token. Refresh token fetching and access token expiration check is enabled by default for the GitLab provider since Grafana v10.1.0 if the `accessTokenExpirationCheck` feature toggle is enabled. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.2.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. ### Configure allowed groups diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md index 2c0b586c523d1..8fa9962eaa813 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md @@ -89,7 +89,7 @@ By default, Grafana includes the `access_type=offline` parameter in the authoriz Refresh token fetching and access token expiration check is enabled by default for the Google provider since Grafana v10.1.0 if the `accessTokenExpirationCheck` feature toggle is enabled. If you would like to disable access token expiration check then set the `use_refresh_token` configuration value to `false`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.2.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. ### Configure automatic login diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md index e1d2bc0420e05..51a4e6062b210 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/grafana/index.md @@ -121,9 +121,12 @@ disable_signout_menu = true ### URL redirect after signing out -URL to redirect the user to after signing out from Grafana. This can for example be used to enable signout from oauth provider. +The URL to redirect the user to after signing out from Grafana can be configured under `[auth]` or under a specific OAuth provider section (for example, `[auth.generic_oauth]`). The URL configured under a specific OAuth provider section takes precedence over the URL configured in `[auth]` section. This can, for example, enable signout from the OAuth provider. ```bash +[auth.generic_oauth] +signout_redirect_url = + [auth] signout_redirect_url = ``` diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md index 322df6c50a37d..7dfef92701393 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md @@ -136,7 +136,7 @@ groups_attribute_path = reverse("Global:department") To enable Single Logout, you need to add the following option to the configuration of Grafana: ```ini -[auth] +[auth.generic_oauth] signout_redirect_url = https:///auth/realms//protocol/openid-connect/logout?post_logout_redirect_uri=https%3A%2F%2%2Flogin ``` diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md index 1a163cc928ee5..4a8245954a16d 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md @@ -1,18 +1,18 @@ --- aliases: - ../../../auth/okta/ -description: Grafana Okta OAuth Guide +description: Grafana Okta OIDC Guide labels: products: - cloud - enterprise - oss -menuTitle: Okta OAuth2 -title: Configure Okta OAuth2 authentication +menuTitle: Okta OIDC +title: Configure Okta OIDC authentication weight: 1400 --- -# Configure Okta OAuth2 authentication +# Configure Okta OIDC authentication {{< docs/shared lookup="auth/intro.md" source="grafana" version="" >}} @@ -21,38 +21,44 @@ weight: 1400 To follow this guide: - Ensure that you have access to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). -- Ensure you know how to create an OAuth2 application with your OAuth2 provider. Consult the [documentation of Okta OAuth2](https://help.okta.com/en-us/Content/Topics/Apps/Apps_App_Integration_Wizard.htm) for more information. -- If you are using refresh tokens, ensure you know how to set them up with your OAuth2 provider. Consult the documentation of your OAuth2 provider for more information. +- Ensure you have permissions in your Okta workspace to create an OIDC app. ## Steps -To integrate your Okta OAuth2 provider with Grafana using our Okta OAuth2 integration, follow these steps: +To integrate your Okta OIDC provider with Grafana using our Okta OIDC integration, follow these steps: -1. [Create an SWA app](https://help.okta.com/en-us/Content/Topics/Apps/Apps_App_Integration_Wizard_SWA.htm) or [OIDC app](https://help.okta.com/en-us/Content/Topics/Apps/Apps_App_Integration_Wizard_OIDC.htm) in the Okta applications section. +1. Follow the [OIDC app integration guide](https://help.okta.com/en-us/content/topics/apps/apps_app_integration_wizard_oidc.htm) + to reach the OIDC new application configuration wizard. -1. Set the callback URL for your OAuth2 app to `http://:/login/okta`. +1. Select `OIDC - OpenID Connect` as the sign-in method and `Single-Page Application`. - Ensure that the callback URL is the complete HTTP address that you use to access Grafana via your browser, but with the appended path of `/login/okta`. +1. Select `Authorization Code` and `Refresh Token` as the grant types. - For the callback URL to be correct, it might be necessary to set the root_url option to [server], for example, if you are serving Grafana behind a proxy. +1. Set the `Sign-in redirect URI` to `http://:/login/okta`. + + Ensure that the sign-in redirect URI is the complete HTTP address that you use to access Grafana via your browser, but with the appended path of `/login/okta`. + + For the sign-in redirect URI to be correct, it might be necessary to set the root_url option to [server], for example, if you are serving Grafana behind a proxy. + +1. Set the `Sign-out redirect URI` to `http://:/logout`. 1. Refer to the following table to update field values located in the `[auth.okta]` section of the Grafana configuration file: - | Field | Description | - | ---------------------------- | ------------------------------------------------------------------------------------------------------------- | - | `client_id`, `client_secret` | These values must match the client ID and client secret from your Okta OAuth2 app. | - | `auth_url` | The authorization endpoint of your OAuth2 provider. `https://.okta.com/oauth2/v1/authorize` | - | `token_url` | The token endpoint of your Okta OAuth2 provider. `https://.okta.com/oauth2/v1/token` | - | `api_url` | The user information endpoint of your Okta OAuth2 provider. `https://.okta.com/oauth2/v1/userinfo` | - | `enabled` | Enables Okta OAuth2 authentication. Set this value to `true`. | + | Field | Description | + | ----------- | ----------------------------------------------------------------------------------------------------------- | + | `client_id` | These values must match the client ID from your Okta OIDC app. | + | `auth_url` | The authorization endpoint of your OIDC provider. `https://.okta.com/oauth2/v1/authorize` | + | `token_url` | The token endpoint of your Okta OIDC provider. `https://.okta.com/oauth2/v1/token` | + | `api_url` | The user information endpoint of your Okta OIDC provider. `https://.okta.com/oauth2/v1/userinfo` | + | `enabled` | Enables Okta OIDC authentication. Set this value to `true`. | -1. Review the list of other Okta OAuth2 [configuration options]({{< relref "#configuration-options" >}}) and complete them as necessary. +1. Review the list of other Okta OIDC [configuration options]({{< relref "#configuration-options" >}}) and complete them as necessary. 1. Optional: [Configure a refresh token]({{< relref "#configure-a-refresh-token" >}}): a. Enable the `accessTokenExpirationCheck` feature toggle. - b. Extend the `scopes` field of `[auth.okta]` section in Grafana configuration file with the refresh token scope used by your OAuth2 provider. + b. Extend the `scopes` field of `[auth.okta]` section in Grafana configuration file with the refresh token scope used by your OIDC provider. c. Enable the [refresh token]({{< relref "#configure-a-refresh-token" >}}) at the Okta application settings. @@ -60,32 +66,51 @@ To integrate your Okta OAuth2 provider with Grafana using our Okta OAuth2 integr 1. Optional: [Configure team synchronization]({{< relref "#configure-team-synchronization-enterprise-only" >}}). 1. Restart Grafana. - You should now see a Okta OAuth2 login button on the login page and be able to log in or sign up with your OAuth2 provider. + You should now see a Okta OIDC login button on the login page and be able to log in or sign up with your OIDC provider. + +The following is an example of a minimally functioning integration when +configured with the instructions above: + +```ini +[auth.okta] +name = Okta +icon = okta +enabled = true +allow_sign_up = true +client_id = 0oads6ziaaiiz4zz45d7 +scopes = openid profile email offline_access +auth_url = https://.okta.com/oauth2/v1/authorize +token_url = https://.okta.com/oauth2/v1/token +api_url = https://.okta.com/oauth2/v1/userinfo +role_attribute_path = contains(groups[*], 'Example::DevOps') && 'Admin' || 'None' +role_attribute_strict = true +allowed_groups = "Example::DevOps" "Example::Dev" "Example::QA" +``` ## Configuration options -The following table outlines the various Okta OAuth2 configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. - -| Setting | Required | Description | Default | -| ----------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | -| `enabled` | No | Enables Okta OAuth2 authentication. | `false` | -| `name` | No | Name that refers to the Okta OAuth2 authentication from the Grafana user interface. | `Okta` | -| `icon` | No | Icon used for the Okta OAuth2 authentication in the Grafana user interface. | `okta` | -| `client_id` | Yes | Client ID provided by your Okta OAuth2 app. | | -| `client_secret` | Yes | Client secret provided by your Okta OAuth2 app. | | -| `auth_url` | Yes | Authorization endpoint of your Okta OAuth2 provider. | | -| `token_url` | Yes | Endpoint used to obtain the Okta OAuth2 access token. | | -| `api_url` | Yes | Endpoint used to obtain user information. | | -| `scopes` | No | List of comma- or space-separated Okta OAuth2 scopes. | `openid profile email groups` | -| `allow_sign_up` | No | Controls Grafana user creation through the Okta OAuth2 login. Only existing Grafana users can log in with Okta OAuth2 if set to `false`. | `true` | -| `auto_login` | No | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | -| `role_attribute_path` | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the Okta OAuth2 ID token. If no role is found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a valid Grafana role (`Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | | -| `role_attribute_strict` | No | Set to `true` to deny user login if the Grafana role cannot be extracted using `role_attribute_path`. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | -| `skip_org_role_sync` | No | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | -| `allowed_groups` | No | List of comma- or space-separated groups. The user should be a member of at least one group to log in. | | -| `allowed_domains` | No | List comma- or space-separated domains. The user should belong to at least one domain to log in. | | -| `use_pkce` | No | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `true` | -| `use_refresh_token` | No | Set to `true` to use refresh token and check access token expiration. The `accessTokenExpirationCheck` feature toggle should also be enabled to use refresh token. | `false` | +The following table outlines the various Okta OIDC configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. + +| Setting | Required | Description | Default | +| ----------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `enabled` | No | Enables Okta OIDC authentication. | `false` | +| `name` | No | Name that refers to the Okta OIDC authentication from the Grafana user interface. | `Okta` | +| `icon` | No | Icon used for the Okta OIDC authentication in the Grafana user interface. | `okta` | +| `client_id` | Yes | Client ID provided by your Okta OIDC app. | | +| `client_secret` | Yes | Client secret provided by your Okta OIDC app. | | +| `auth_url` | Yes | Authorization endpoint of your Okta OIDC provider. | | +| `token_url` | Yes | Endpoint used to obtain the Okta OIDC access token. | | +| `api_url` | Yes | Endpoint used to obtain user information. | | +| `scopes` | No | List of comma- or space-separated Okta OIDC scopes. | `openid profile email groups` | +| `allow_sign_up` | No | Controls Grafana user creation through the Okta OIDC login. Only existing Grafana users can log in with Okta OIDC if set to `false`. | `true` | +| `auto_login` | No | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | +| `role_attribute_path` | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the Okta OIDC ID token. If no role is found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a valid Grafana role (`Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | | +| `role_attribute_strict` | No | Set to `true` to deny user login if the Grafana role cannot be extracted using `role_attribute_path`. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | +| `skip_org_role_sync` | No | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | +| `allowed_groups` | No | List of comma- or space-separated groups. The user should be a member of at least one group to log in. | | +| `allowed_domains` | No | List comma- or space-separated domains. The user should belong to at least one domain to log in. | | +| `use_pkce` | No | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `true` | +| `use_refresh_token` | No | Set to `true` to use refresh token and check access token expiration. The `accessTokenExpirationCheck` feature toggle should also be enabled to use refresh token. | `false` | ### Configure a refresh token @@ -104,7 +129,7 @@ To enable the `Refresh Token` head over the Okta application settings and: At the configuration file, extend the `scopes` in `[auth.okta]` section with `offline_access`. -> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.2.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. +> **Note:** The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3.0 and the `use_refresh_token` configuration value will be used instead for configuring refresh token fetching and access token expiration check. ### Configure role mapping @@ -124,7 +149,7 @@ To learn about adding custom claims to the user info in Okta, refer to [add cust > **Note:** Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud]({{< relref "../../../../introduction/grafana-cloud" >}}). -By using Team Sync, you can link your OAuth2 groups to teams within Grafana. This will automatically assign users to the appropriate teams. +By using Team Sync, you can link your Okta groups to teams within Grafana. This will automatically assign users to the appropriate teams. Map your Okta groups to teams in Grafana so that your users will automatically be added to the correct teams. diff --git a/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md b/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md index 2817648ee0897..12e8707d459ed 100644 --- a/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md @@ -16,7 +16,7 @@ weight: 500 If you manage your secrets with [Hashicorp Vault](https://www.hashicorp.com/products/vault), you can use them for [Configuration]({{< relref "../../../configure-grafana" >}}) and [Provisioning]({{< relref "../../../../administration/provisioning" >}}). {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud). +Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}). {{% /admonition %}} {{% admonition type="note" %}} diff --git a/docs/sources/setup-grafana/configure-security/configure-team-sync.md b/docs/sources/setup-grafana/configure-security/configure-team-sync.md index 6bab7df0bd883..f7410d14c711d 100644 --- a/docs/sources/setup-grafana/configure-security/configure-team-sync.md +++ b/docs/sources/setup-grafana/configure-security/configure-team-sync.md @@ -42,7 +42,7 @@ If you have already grouped some users into a team, then you can synchronize tha {{< figure src="/static/img/docs/enterprise/team_add_external_group.png" class="docs-image--no-shadow docs-image--right" max-width= "600px" >}} -1. In Grafana, navigate to **Administration > Teams**. +1. In Grafana, navigate to **Administration > Users and access > Teams**. 1. Select a team. 1. Go to the External group sync tab, and click **Add group**. 1. Insert the value of the group you want to sync with. This becomes the Grafana `GroupID`. diff --git a/docs/sources/setup-grafana/image-rendering/_index.md b/docs/sources/setup-grafana/image-rendering/_index.md index 8639cb7f7d018..61fd88e13dcd6 100644 --- a/docs/sources/setup-grafana/image-rendering/_index.md +++ b/docs/sources/setup-grafana/image-rendering/_index.md @@ -229,6 +229,25 @@ ENABLE_METRICS=true } ``` +#### Enable detailed timing metrics + +With the [Prometheus metrics enabled](#enable-prometheus-metrics), you can also enable detailed metrics to get the duration of every rendering step. + +Default is `false`. + +```bash +# Available from v3.9.0+ +RENDERING_TIMING_METRICS=true +``` + +```json +{ + "rendering": { + "timingMetrics": true + } +} +``` + #### Log level Change the log level. Default is `info` and will include log messages with level `error`, `warning` and `info`. @@ -370,6 +389,11 @@ BROWSER_TZ=Europe/Stockholm Instruct headless browser instance to use a default language when not provided by Grafana, e.g. when rendering panel image of alert. Refer to the HTTP header Accept-Language to understand how to format this value. +```bash +# Available from v3.9.0+ +RENDERING_LANGUAGE="fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5" +``` + ```json { "rendering": { @@ -382,6 +406,11 @@ Refer to the HTTP header Accept-Language to understand how to format this value. Default viewport width when width is not specified in the rendering request. Default is `1000`. +```bash +# Available from v3.9.0+ +RENDERING_VIEWPORT_WIDTH=1000 +``` + ```json { "rendering": { @@ -394,6 +423,11 @@ Default viewport width when width is not specified in the rendering request. Def Default viewport height when height is not specified in the rendering request. Default is `500`. +```bash +# Available from v3.9.0+ +RENDERING_VIEWPORT_HEIGHT=500 +``` + ```json { "rendering": { @@ -406,6 +440,11 @@ Default viewport height when height is not specified in the rendering request. D Limit the maximum viewport width that can be requested. Default is `3000`. +```bash +# Available from v3.9.0+ +RENDERING_VIEWPORT_MAX_WIDTH=1000 +``` + ```json { "rendering": { @@ -418,6 +457,11 @@ Limit the maximum viewport width that can be requested. Default is `3000`. Limit the maximum viewport height that can be requested. Default is `3000`. +```bash +# Available from v3.9.0+ +RENDERING_VIEWPORT_MAX_HEIGHT=500 +``` + ```json { "rendering": { @@ -431,6 +475,11 @@ Limit the maximum viewport height that can be requested. Default is `3000`. Specify default device scale factor for rendering images. `2` is enough for monitor resolutions, `4` would be better for printed material. Setting a higher value affects performance and memory. Default is `1`. This can be overridden in the rendering request. +```bash +# Available from v3.9.0+ +RENDERING_VIEWPORT_DEVICE_SCALE_FACTOR=2 +``` + ```json { "rendering": { @@ -443,6 +492,11 @@ This can be overridden in the rendering request. Limit the maximum device scale factor that can be requested. Default is `4`. +```bash +# Available from v3.9.0+ +RENDERING_VIEWPORT_MAX_DEVICE_SCALE_FACTOR=4 +``` + ```json { "rendering": { diff --git a/docs/sources/setup-grafana/installation/docker/index.md b/docs/sources/setup-grafana/installation/docker/index.md index 31ae58ffe544e..40d8fca00dda1 100644 --- a/docs/sources/setup-grafana/installation/docker/index.md +++ b/docs/sources/setup-grafana/installation/docker/index.md @@ -15,6 +15,8 @@ weight: 400 This topic guides you through installing Grafana via the official Docker images. Specifically, it covers running Grafana via the Docker command line interface (CLI) and docker-compose. +{{< youtube id="FlDfcMbSLXs" >}} + Grafana Docker images come in two editions: - **Grafana Enterprise**: `grafana/grafana-enterprise` diff --git a/docs/sources/setup-grafana/set-up-grafana-live.md b/docs/sources/setup-grafana/set-up-grafana-live.md index 7540400027176..3c5e8385e76c3 100644 --- a/docs/sources/setup-grafana/set-up-grafana-live.md +++ b/docs/sources/setup-grafana/set-up-grafana-live.md @@ -137,7 +137,7 @@ cat /proc//limits The open files limit shows approximately how many user connections your server can currently handle. -To increase this limit, refer to [these instructions](https://docs.riak.com/riak/kv/2.2.3/using/performance/open-files-limit.1.html)for popular operating systems. +To increase this limit, refer to [these instructions](https://docs.riak.com/riak/kv/2.2.3/using/performance/open-files-limit.1.html) for popular operating systems. #### Ephemeral port exhaustion diff --git a/docs/sources/shared/datasources/tempo-editor-traceql.md b/docs/sources/shared/datasources/tempo-editor-traceql.md index d41fe3f770fba..24209ed6d6e44 100644 --- a/docs/sources/shared/datasources/tempo-editor-traceql.md +++ b/docs/sources/shared/datasources/tempo-editor-traceql.md @@ -46,6 +46,10 @@ To access the query editor, follow these steps: 1. Optional: Use the Time picker drop-down to change the time and range for the query (refer to the [documentation for instructions](https://grafana.com/docs/grafana/latest/dashboards/use-dashboards/#set-dashboard-time-range)). 1. Once you have finished your query, select **Run query**. +This video provides and example of creating a TraceQL query using the custom tag grouping. + +{{< youtube id="fraepWra00Y" >}} + ## Query by TraceID To query a particular trace by its trace ID: @@ -60,7 +64,7 @@ To query a particular trace by its trace ID: You can use the query editor’s autocomplete suggestions to write queries. The editor detects span sets to provide relevant autocomplete options. -It uses regular expressions (regex) to detect where it is inside a spanset and provide attribute names, scopes, intrinsic names, logic operators, or attribute values from Tempo's API, depending on what is expected for the current situation. +It uses regular expressions (regex) to detect where it's inside a spanset and provide attribute names, scopes, intrinsic names, logic operators, or attribute values from Tempo's API, depending on what's expected for the current situation. ![Query editor showing the auto-complete feature](/static/img/docs/tempo/screenshot-traceql-query-editor-auto-complete-v10.png) @@ -80,4 +84,16 @@ Query results for both the editor and the builder are returned in a table. Selec ![Query editor showing span results](/static/img/docs/tempo/screenshot-traceql-query-editor-results-v10.png) -Selecting the trace ID from the returned results will open a trace diagram. Selecting a span from the returned results opens a trace diagram and reveals the relevant span in the trace diagram (above, the highlighted blue line). +Selecting the trace ID from the returned results opens a trace diagram. Selecting a span from the returned results opens a trace diagram and reveals the relevant span in the trace diagram (above, the highlighted blue line). + +### Streaming results + +The Tempo data source supports streaming responses to TraceQL queries so you can see partial query results as they come in without waiting for the whole query to finish. + +{{% admonition type="note" %}} +To use this experimental feature, enable the `traceQLStreaming` feature toggle. If you’re using Grafana Cloud and would like to enable this feature, please contact customer support. +{{% /admonition %}} + +Streaming is available for both the **Search** and **TraceQL** query types, and you'll get immediate visibility of incoming traces on the results table. + +{{< video-embed src="/media/docs/grafana/data-sources/tempo-streaming-v2.mp4" >}} diff --git a/docs/sources/shared/datasources/tempo-search-traceql.md b/docs/sources/shared/datasources/tempo-search-traceql.md index 2547e15b42d10..15ce534aaa9ac 100644 --- a/docs/sources/shared/datasources/tempo-search-traceql.md +++ b/docs/sources/shared/datasources/tempo-search-traceql.md @@ -59,11 +59,11 @@ To access Search, use the following steps: 1. Sign into Grafana. 1. Select your Tempo data source. -1. From the menu, choose Explore and select Query type > Search. +1. From the menu, choose **Explore** and select **Query type > Search**. ## Define filters -Using filters, you refine the data returned from the query by selecting Resource Service Name, Span Name, or Duration. The **Duration** represents span time, calculated by subtracting the end time from the start time of the span. +Using filters, you refine the data returned from the query by selecting **Resource Service Name**, **Span Name**, or **Duration**. The **Duration** represents span time, calculated by subtracting the end time from the start time of the span. Grafana administrators can change the default filters using the Tempo data source configuration. Filters can be limited by the operators. The available operators are determined by the field type. @@ -110,6 +110,8 @@ Using **Aggregate by**, you can calculate RED metrics (total span count, percent This capability is based on the [metrics summary API](/docs/grafana-cloud/monitor-infrastructure/traces/metrics-summary-api/). Metrics summary only calculates summaries based on spans received within the last hour. +{{< youtube id="g97CjKOZqT4" >}} + When you use **Aggregate by**, the selections you make determine how the information is reported in the Table. Every combination that matches selections in your data is listed in the table. Each aggregate value, for example `intrinsic`:`name`, has a corresponding column in the results table. @@ -146,3 +148,15 @@ Select **Run query** to run the TraceQL query (1 in the screenshot). Queries can take a little while to return results. The results appear in a table underneath the query builder. Selecting a Trace ID (2 in the screenshot) displays more detailed information (3 in the screenshot). {{< figure src="/static/img/docs/queries/screenshot-tempods-query-results.png" class="docs-image--no-shadow" max-width="750px" caption="Tempo Search query type results" >}} + +#### Streaming results + +The Tempo data source supports streaming responses to TraceQL queries so you can see partial query results as they come in without waiting for the whole query to finish. + +{{% admonition type="note" %}} +To use this experimental feature, enable the `traceQLStreaming` feature toggle. If you’re using Grafana Cloud and would like to enable this feature, please contact customer support. +{{% /admonition %}} + +Streaming is available for both the **Search** and **TraceQL** query types, and you'll get immediate visibility of incoming traces on the results table. + +{{< video-embed src="/media/docs/grafana/data-sources/tempo-streaming-v2.mp4" >}} diff --git a/docs/sources/shared/datasources/tempo-traces-to-profiles.md b/docs/sources/shared/datasources/tempo-traces-to-profiles.md new file mode 100644 index 0000000000000..2a2d96581581e --- /dev/null +++ b/docs/sources/shared/datasources/tempo-traces-to-profiles.md @@ -0,0 +1,82 @@ +--- +headless: true +labels: + products: + - enterprise + - oss +--- + +[//]: # 'This file documents the Traces to profile configure and usage for the Tempo data source.' +[//]: # 'This shared file is included in these locations:' +[//]: # '/grafana/docs/sources/datasources/tempo/configure-tempo-data-source.md' +[//]: # '/website/docs/grafana-cloud/data-configuration/traces/traces-query-editor.md' +[//]: # +[//]: # 'If you make changes to this file, verify that the meaning and content are not changed in any place where the file is included.' +[//]: # 'Any links should be fully qualified and not relative: /docs/grafana/ instead of ../grafana/.' + + + +{{< docs/experimental product="Trace to profiles" featureFlag="traceToProfiles" >}} + +Using Trace to profiles, you can use Grafana’s ability to correlate different signals by adding the functionality to link between traces and profiles. + +**Trace to profiles** lets you link your Grafana Pyroscope data source to tracing data. +When configured, this connection lets you run queries from a trace span into the profile data. + +There are two ways to configure the trace to profiles feature: + +- Use a simplified configuration with default query, or +- Configure a custom query where you can use a template language to interpolate variables from the trace or span. + +To use trace to profiles, navigate to **Explore** and query a trace. Each span now links to your queries. Clicking a link runs the query in a split panel. If tags are configured, Grafana dynamically inserts the span attribute values into the query. The query runs over the time range of the (span start time - 60) to (span end time + 60 seconds). + +![Selecting a link in the span queries the profile data source](/static/img/docs/tempo/profiles/tempo-profiles-Span-link-profile-data-source.png) + +To use trace to profiles, you must have a configured Grafana Pyroscope data source. For more information, refer to the [Grafana Pyroscope data source documentation](/docs/grafana/latest/datasources/grafana-pyroscope/). + +## Use a simple configuration + +To use a simple configuration, follow these steps: + +1. Select a Pyroscope data source from the **Data source** drop-down. +1. Optional: Choose any tags to use in the query. If left blank, the default values of `service.name` and `service.namespace` are used. + + The tags you configure must be present in the spans attributes or resources for a trace to profiles span link to appear. You can optionally configure a new name for the tag. This is useful for example if the tag has dots in the name and the target data source doesn't allow using dots in labels. In that case you can for example remap `service.name` to `service_name`. + +1. Select one or more profile types to use in the query. Select the drop-down and choose options from the menu. + + The profile type or app must be selected for the query to be valid. Grafana doesn't show any data if the profile type or app isn’t selected when a query runs. + ![Traces to profile configuration options in the Tempo data source](/static/img/docs/tempo/profiles/Tempo-data-source-profiles-Settings.png) + +1. Do not select **Use custom query**. +1. Select **Save and Test**. + +## Configure a custom query + +To use a custom query with the configuration, follow these steps: + +1. Select a Pyroscope data source from the **Data source** drop-down. +1. Optional: Choose any tags that will be used in the query. If left blank, the default values of `service.name` and `service.namespace` are used. + + These tags can be used in the custom query with `${__tags}` variable. This variable interpolates the mapped tags as list in an appropriate syntax for the data source and will only include the tags that were present in the span omitting those that weren’t present. You can optionally configure a new name for the tag. This is useful in cases where the tag has dots in the name and the target data source doesn't allow using dots in labels. For example, you can remap `service.name` to `service_name` in such a case. If you don’t map any tags here, you can still use any tag in the query like this `method="${__span.tags.method}"`. + +1. Select one or more profile types to use in the query. Select the drop-down and choose options from the menu. +1. Switch on **Use custom query** to enter a custom query. +1. Specify a custom query to be used to query profile data. You can use various variables to make that query relevant for current span. The link is shown only if all the variables are interpolated with non-empty values to prevent creating an invalid query. You can interpolate the configured tags using the `$__tags` keyword. +1. Select **Save and Test**. + +## Variables that can be used in a custom query + +To use a variable you need to wrap it in `${}`. For example, `${__span.name}`. + +| Variable name | Description | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **\_\_tags** | This variable uses the tag mapping from the UI to create a label matcher string in the specific data source syntax. The variable only uses tags that are present in the span. The link is still created even if only one of those tags is present in the span. You can use this if all tags are not required for the query to be useful. | +| **\_\_span.spanId** | The ID of the span. | +| **\_\_span.traceId** | The ID of the trace. | +| **\_\_span.duration** | The duration of the span. | +| **\_\_span.name** | Name of the span. | +| **\_\_span.tags** | Namespace for the tags in the span. To access a specific tag named `version`, you would use `${__span.tags.version}`. In case the tag contains dot, you have to access it as `${__span.tags["http.status"]}`. | +| **\_\_trace.traceId** | The ID of the trace. | +| **\_\_trace.duration** | The duration of the trace. | +| **\_\_trace.name** | The name of the trace. | diff --git a/docs/sources/shared/visualizations/disconnect-values.md b/docs/sources/shared/visualizations/disconnect-values.md index 6786ba43c3083..63e6472c3636a 100644 --- a/docs/sources/shared/visualizations/disconnect-values.md +++ b/docs/sources/shared/visualizations/disconnect-values.md @@ -6,7 +6,7 @@ title: Disconnect values Choose whether to set a threshold above which values in the data should be disconnected. -{{< figure src="/media/docs/grafana/screenshot-grafana-10-1-disconnect-values.png" max-width="750px" >}} +{{< figure src="/media/docs/grafana/screenshot-grafana-10-1-disconnect-values.png" max-width="750px" alt="Disconnect values options" >}} - **Never:** Time series data points in the the data are never disconnected. - **Threshold:** Specify a threshold above which values in the data are disconnected. This can be useful when desired values in the data are of a known size and/or within a known range, and values outside this range should no longer be connected. diff --git a/docs/sources/shared/visualizations/legend-mode.md b/docs/sources/shared/visualizations/legend-mode.md index c8a127d5bee7f..df8d1a50ec21c 100644 --- a/docs/sources/shared/visualizations/legend-mode.md +++ b/docs/sources/shared/visualizations/legend-mode.md @@ -19,4 +19,4 @@ Choose where to display the legend. ### Legend values -Choose which of the [standard calculations]({{< relref "../../panels-visualizations/calculation-types/" >}}) to show in the legend. You can have more than one. +Choose which of the [standard calculations]({{< relref "../../panels-visualizations/query-transform-data/calculation-types/" >}}) to show in the legend. You can have more than one. diff --git a/docs/sources/tutorials/create-alerts-with-logs/index.md b/docs/sources/tutorials/create-alerts-with-logs/index.md index d62cd413fb492..faaad9a283981 100644 --- a/docs/sources/tutorials/create-alerts-with-logs/index.md +++ b/docs/sources/tutorials/create-alerts-with-logs/index.md @@ -44,7 +44,7 @@ In these steps you'll create an alert and define an expression to evaluate. Thes ### Create a Grafana-managed alert -1. Navigate in Grafana to **Alerting**, then to **Alert Rules** and click **+ Create alert rule**. +1. Navigate in Grafana to **Alerting**, then to **Alert Rules** and click **+ New alert rule**. 1. Choose **Grafana Managed Alert** to create an alert that uses expressions. 1. Select your Loki datasource from the drop-down. 1. Enter the alert query in the query editor, switch to **code** mode in the top right corner of the editor to paste the query below: diff --git a/docs/sources/tutorials/grafana-fundamentals/index.md b/docs/sources/tutorials/grafana-fundamentals/index.md index abff02d94afca..e2dd6d1ed8d28 100644 --- a/docs/sources/tutorials/grafana-fundamentals/index.md +++ b/docs/sources/tutorials/grafana-fundamentals/index.md @@ -328,7 +328,7 @@ We have now created a dummy webhook endpoint and created a new Alerting Contact Now that Grafana knows how to notify us, it's time to set up an alert rule: 1. In the sidebar, click **Alert rules**. -1. Click **Create alert rule**. +1. Click **New alert rule**. 1. In section **1**, name the rule `fundamentals-test`. 1. For section **2**, select **Grafana Managed Alert** as the rule type. Next, find query box **A**. Choose your Prometheus datasource and enter the same query that we used in our earlier panel: `sum(rate(tns_request_duration_seconds_count[5m])) by(route)`. Click **Run queries**. You should see some data in the graph. 1. Now scroll down to query box **B**. Change the operation from **Reduce** to **Classic condition**. [You can read more about classic and multi-dimensional conditions here](/docs/grafana/latest/alerting/unified-alerting/alerting-rules/create-grafana-managed-rule/#single-and-multi-dimensional-rule). For conditions enter the following: `WHEN last() OF A IS ABOVE 0.2`. Delete query **C**. diff --git a/docs/sources/tutorials/integrate-hubot/index.md b/docs/sources/tutorials/integrate-hubot/index.md index d6b769987f1f1..35299df80b60d 100644 --- a/docs/sources/tutorials/integrate-hubot/index.md +++ b/docs/sources/tutorials/integrate-hubot/index.md @@ -25,10 +25,7 @@ Grafana 2.0 shipped with a great feature that enables it to render any graph or No matter what data source you are using, the PNG image of the Graph will look the same as it does in your browser. -This guide will show you how to install and configure the [Hubot-Grafana](https://github.com/stephenyeargin/hubot-grafana) plugin. This plugin allows you to tell hubot to render any dashboard or graph right from a channel in Slack, Hipchat or Basecamp. The bot will respond with an image of the graph and a link that will take you to the graph. - -> _Amazon S3 Required_: The hubot-grafana script will upload the rendered graphs to Amazon S3. This -> is so Hipchat and Slack can show them reliably (they require the image to be publicly available). +This guide shows you how to install and configure the [Hubot-Grafana](https://github.com/stephenyeargin/hubot-grafana) plugin. This plugin allows you to tell Hubot to render any dashboard or graph right from a channel in Slack, Basecamp, or any other supported Hubot adapter. The bot will respond with an image of the graph and a link that will take you to the graph. {{< figure src="/static/img/docs/tutorials/hubot_grafana.png" max-width="800px" >}} @@ -40,7 +37,7 @@ This guide will show you how to install and configure the [Hubot-Grafana](https: Hubot is very easy to install and host. If you do not already have a bot up and running please read the official [Getting Started With Hubot](https://hubot.github.com/docs/) guide. -## Install Hubot-Grafana script +## Install the Hubot-Grafana script In your Hubot project repo install the Grafana plugin using `npm`: @@ -56,18 +53,15 @@ Edit the file external-scripts.json, and add hubot-grafana to the list of plugin ## Configure -The `hubot-grafana` plugin requires a number of environment variables to be set in order to work properly. +The Hubot-Grafana plugin requires two environment variables to be set in order to work properly. ```bash export HUBOT_GRAFANA_HOST=https://play.grafana.org export HUBOT_GRAFANA_API_KEY=abcd01234deadbeef01234 -export HUBOT_GRAFANA_S3_BUCKET=mybucket -export HUBOT_GRAFANA_S3_ACCESS_KEY_ID=ABCDEF123456XYZ -export HUBOT_GRAFANA_S3_SECRET_ACCESS_KEY=aBcD01234dEaDbEef01234 -export HUBOT_GRAFANA_S3_PREFIX=graphs -export HUBOT_GRAFANA_S3_REGION=us-standard ``` +There are [additional environment variables](https://github.com/stephenyeargin/hubot-grafana?tab=readme-ov-file#general-settings) that you can set to control the appearance of the graphs. + ### Grafana server side rendering The hubot plugin will take advantage of the Grafana server side rendering feature that can render any panel on the server using phantomjs. Grafana ships with a phantomjs binary (Linux only). @@ -80,9 +74,9 @@ To verify that this feature works try the `Direct link to rendered image` link i You need to set the environment variable `HUBOT_GRAFANA_API_KEY` to a Grafana API Key. You can add these from the API Keys page which you find in the Organization dropdown. -### Amazon S3 +### Image uploading -The `S3` options are optional but for the images to work properly in services like Slack and Hipchat they need to publicly available. By specifying the `S3` options the hubot-grafana script will publish the rendered panel to `S3` and it will use that URL when it posts to Slack or Hipchat. +There are several approaches to uploading the rendered graphs. If you are using Slack, Rocket.Chat, or Telegram, the adapter's native uploader will take care of sending it through their respective API. If your Hubot is hosted on a platform that doesn't support uploads (such as IRC), you can use the [built-in S3 uploader](https://github.com/stephenyeargin/hubot-grafana/wiki/Amazon-S3-Image-Hosting). Note if you configure S3, it will not use the adapter's upload features. ## Hubot commands diff --git a/docs/sources/upgrade-guide/upgrade-v10.2/index.md b/docs/sources/upgrade-guide/upgrade-v10.2/index.md index 17e706d64ef25..af9632df3cbb3 100644 --- a/docs/sources/upgrade-guide/upgrade-v10.2/index.md +++ b/docs/sources/upgrade-guide/upgrade-v10.2/index.md @@ -19,3 +19,5 @@ weight: 1500 {{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="" >}} ## Technical notes + +- From Grafana v10.2 onwards, `/api/datasources/:id/` is removed and replaced with `/api/access-control/datasources/:uid`. For more information about the new API endpoints for the data source permission API, refer to the [documentation](https://grafana.com/docs/grafana//developers/http_api/datasource_permissions/). diff --git a/docs/sources/whatsnew/whats-new-in-v10-2.md b/docs/sources/whatsnew/whats-new-in-v10-2.md index 70a99d1308cae..026d3cafb4b05 100644 --- a/docs/sources/whatsnew/whats-new-in-v10-2.md +++ b/docs/sources/whatsnew/whats-new-in-v10-2.md @@ -327,7 +327,7 @@ The **Add field from calculation** transformation has been updated. - **Floor (floor)** - Returns the largest integer less than or equal to a given expression. - **Ceiling (ceil)** - Returns the smallest integer greater than or equal to a given expression. -{{< figure src="/media/docs/grafana/transformations/unary-operation.png" >}} +{{< figure src="/media/docs/grafana/transformations/unary-operation.png" alt="Unary operation options" >}} Also, **Row index** can now show the index as a percentage. @@ -379,7 +379,7 @@ _Generally available in all editions of Grafana_ Use the Grafana Alerting - Grafana OnCall integration to effortlessly connect alerts generated by Grafana Alerting with Grafana OnCall. From there, you can route them according to defined escalation chains and schedules. -To learn more, refer to the [Grafana OnCall integration for Alerting documentation](https://grafana.com/docs/grafana//alerting/alerting-rules/manage-contact-points/configure-oncall/), as well as the following video demo. +To learn more, refer to the [Grafana OnCall integration for Alerting documentation](https://grafana.com/docs/grafana//alerting/alerting-rules/manage-contact-points/integrations/configure-oncall/), as well as the following video demo. {{< youtube id="abRn5I61hxs?rel=0" >}} diff --git a/docs/sources/whatsnew/whats-new-in-v7-2.md b/docs/sources/whatsnew/whats-new-in-v7-2.md index 06182f95b6807..45476bf7407e0 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-2.md +++ b/docs/sources/whatsnew/whats-new-in-v7-2.md @@ -132,7 +132,7 @@ A new layout option is available when rendering reports: the grid layout. With t The grid layout is also available for the [Export dashboard as PDF]({{< relref "../dashboards/share-dashboards-panels#export-dashboard-as-pdf" >}}) feature. -{{< figure src="/static/img/docs/enterprise/reports_grid_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" >}} +{{< figure src="/static/img/docs/enterprise/reports_grid_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" alt="Report in grid layout" >}} ### Report time range diff --git a/docs/sources/whatsnew/whats-new-in-v7-4.md b/docs/sources/whatsnew/whats-new-in-v7-4.md index b2de53898bfe0..90149af8e831c 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-4.md +++ b/docs/sources/whatsnew/whats-new-in-v7-4.md @@ -169,7 +169,7 @@ Many thanks to [mtanda](https://github.com/mtanda) this contribution! Google Cloud Monitoring data source ships with pre-configured dashboards for some of the most popular GCP services. These curated dashboards are based on similar dashboards in the GCP dashboard samples repository. In this release, we have expanded the set of pre-configured dashboards. -{{< figure src="/static/img/docs/google-cloud-monitoring/curated-dashboards-7-4.png" max-width= "650px" >}} +{{< figure src="/static/img/docs/google-cloud-monitoring/curated-dashboards-7-4.png" max-width= "650px" alt="Google Cloud Monitoring pre-configured dashboards" >}} If you want to customize a dashboard, we recommend that you save it under a different name. Otherwise the dashboard will be overwritten when a new version of the dashboard is released. diff --git a/docs/sources/whatsnew/whats-new-next/README.md b/docs/sources/whatsnew/whats-new-next/README.md index f7157457cdc5a..8ce45f6906c1f 100644 --- a/docs/sources/whatsnew/whats-new-next/README.md +++ b/docs/sources/whatsnew/whats-new-next/README.md @@ -1,88 +1,3 @@ -# Contribute to 'What's New in Grafana Cloud' +# Contribute to 'What's new in Grafana Cloud' -To have a feature presented in [What's New in Grafana Cloud](https://grafana.com/docs/grafana-cloud/whatsnew/), add an entry to the [`index.md`](./index.md) file in this directory. - -Use the following template, replace any `` with the appropriate text (explained after the template): - -```markdown -## - - - - - - -_Available in in Grafana _ - - -``` - -## _`CONTRIBUTOR`_ - -The name of the contributor of the feature. -The information is intentionally commented out so that it isn't displayed in the published page. - -## _`ON-PREMISE OFFERING`_ - -One or both of: - -- OSS -- Enterprise - -Intended availability of the feature when released outside of Grafana Cloud. -The information is intentionally commented out so that it isn't displayed in the published page. -If the feature is not going to be released outside of Grafana Cloud, omit the HTML comment entirely. - -## _`DATE`_ - -The release date of the feature, fully written out. For example: September 12, 2023. - -Add your feature in order by date. Dates are in descending order from the top of the page (that is, the top of the page has the most recently released features). - -## _`CLOUD AVAILABILITY`_ - -One of the following [release life cycle stages](https://grafana.com/docs/release-life-cycle/): - -- Generally available -- Available in public preview -- Available in private preview -- Experimental - -## _`CLOUD OFFERING`_ - -List the appropriate combination of: - -- Cloud Free -- Cloud Pro -- Cloud Advanced - -Or if all three: - -- Cloud - -## _`DESCRIPTION`_ - -Include an overview of the feature and problem it solves, and where to learn more. -Link to any appropriate documentation and, optionally, embed a video or image to illustrate the feature, following our [image and media guidelines](https://grafana.com/docs/writers-toolkit/write/image-guidelines/#image-diagram-and-screenshot-guidelines). -You must use relative path references when linking to documentation within the Grafana repository. -Use the Hugo `relref` shortcode for build time link checking. -For more information about the `relref` shortcode, refer to [Links and references](https://grafana.com/docs/writers-toolkit/writing-guide/references/). - -Grafana Cloud documentation uses the "next" version of Grafana documentation. -For consistency, links to Grafana OSS documentation should also link to the "next" version. -For example, using the partial URL `/docs/grafana/next/explore/` to link to the Grafana OSS explore documentation. - -## Example - -```markdown -## Updated navigation - - - - -September 12, 2023 - -_Available in public preview in Grafana Cloud Pro and Advanced_ - -The navigation in Grafana Cloud has been updated in the following ways... -``` +To contribute to [What's new in Grafana Cloud](https://grafana.com/docs/grafana-cloud/whatsnew/), refer to [Contribute to What’s new or release notes](https://grafana.com/docs/writers-toolkit/contribute-documentation/contribute-release-notes/). diff --git a/docs/sources/whatsnew/whats-new-next/index.md b/docs/sources/whatsnew/whats-new-next/index.md deleted file mode 100644 index 743f5457d0cae..0000000000000 --- a/docs/sources/whatsnew/whats-new-next/index.md +++ /dev/null @@ -1,528 +0,0 @@ ---- -canonical: https://grafana.com/docs/grafana/latest/whatsnew/whats-new-next/ -description: Feature and improvement highlights for Grafana Cloud -keywords: - - grafana - - new - - documentation - - cloud - - release notes -labels: - products: - - cloud -title: What's new in Grafana Cloud -weight: -37 ---- - -# What’s new in Grafana Cloud - -Welcome to Grafana Cloud! Read on to learn about the newest changes to Grafana Cloud. - -## Export alerting resources to Terraform - - - - -October 30, 2023 - -_Generally available in Grafana Cloud_ - -Export your alerting resources, such as alert rules, contact points, and notification policies as Terraform resources. A new “Modify export” mode for alert rules enables you to edit provisioned alert rules and export a modified version. - -## Alerting insights - - - -October 30, 2023 - -_Generally available in Grafana Cloud_ - -Use Alerting insights to monitor your alerting data, discover key trends about your organization’s alert management performance, and find patterns in why things go wrong. - -## Configure refresh token handling separately for OAuth providers - - - - -October 24, 2023 - -_Generally available in Grafana Cloud_ - -With Grafana v9.3, we introduced a feature toggle called `accessTokenExpirationCheck`. It improves the security of Grafana by checking the expiration of the access token and automatically refreshing the expired access token when a user is logged in using one of the OAuth providers. - -With the current release, we've introduced a new configuration option for each OAuth provider called `use_refresh_token` that allows you to configure whether the particular OAuth integration should use refresh tokens to automatically refresh access tokens when they expire. In addition, to further improve security and provide secure defaults, `use_refresh_token` is enabled by default for providers that support either refreshing tokens automatically or client-controlled fetching of refresh tokens. It's enabled by default for the following OAuth providers: `AzureAD`, `GitLab`, `Google`. - -For more information on how to set up refresh token handling, please refer to [the documentation of the particular OAuth provider.](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/). - -{{% admonition type="note" %}} -The `use_refresh_token` configuration must be used in conjunction with the `accessTokenExpirationCheck` feature toggle. If you disable the `accessTokenExpirationCheck` feature toggle, Grafana won't check the expiration of the access token and won't automatically refresh the expired access token, even if the `use_refresh_token` configuration is set to `true`. - -The `accessTokenExpirationCheck` feature toggle will be removed in Grafana v10.3. -{{% /admonition %}} - -## Use AI to generate dashboard titles, descriptions, and change summaries - - - - - -October 24, 2023 - -_Available in public preview in Grafana Cloud_ - -You can now use generative AI to assist you in your Grafana dashboards. So far generative AI can help you with the following tasks: - -- **Generate panel and dashboard titles and descriptions** - You can now generate a title and description for your panel or dashboard based on the data you've added to it. This is useful when you want to quickly visualize your data and don't want to spend time coming up with a title or description. -- **Generate dashboard save changes summary** - You can now generate a summary of the changes you've made to a dashboard when you save it. This is great for effortlessly tracking the history of a dashboard. - -To enable these features, you must first enable the `dashgpt` [feature toggle](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles). Then install and configure Grafana's LLM app plugin. For more information, refer to the [Grafana LLM app plugin documentation](https://grafana.com/docs/grafana-cloud/alerting-and-irm/machine-learning/llm-plugin/). - -When enabled, look for the **✨ Auto generate** option next to the **Title** and **Description** fields in your panels and dashboards, or when you press the **Save** button. - -{{< figure src="/media/docs/grafana/dashboards/auto-generate-description-10-2.gif" max-width="750px" caption="Auto-generate a panel description using AI" >}} - -## Create interactive buttons in canvas visualizations - - - - - -October 24, 2023 - -_Available in public preview in Grafana Cloud_ - -You can now add buttons to your canvas visualizations. Buttons can be configured to call an API endpoint. This pushes Grafana's capabilities to new heights, allowing you to create interactive dashboards that can be used to control external systems. - -To learn more, refer to our [Canvas button element documentation](https://grafana.com/docs/grafana//panels-visualizations/visualizations/canvas/#button). - -{{< video-embed src="/media/docs/grafana/2023-20-10-Canvas-Button-Element-Enablement-Video.mp4" max-width="750px" caption="Canvas button element demo" >}} - -## Zoom in on the y-axis of the time series and candlestick visualizations - - - - - -October 24, 2023 - -_Generally available in Grafana Cloud_ - -You can now zoom in on the y-axis of your time series and candlestick visualizations. This is useful when you want to focus on a specific range of values. To zoom in on the y-axis on supported visualizations, hold the Shift key while clicking and dragging; double-click to reset the zoom. - -{{< video-embed src="/media/docs/grafana/screen-recording-10-2-y-axis-zoom-demo.mp4" max-width="750px" caption="Y-axis zooming demo" >}} - -## Data visualization quality of life improvements - -We've made a number of smaller improvements to the data visualization experience in Grafana. - - - - - -October 24, 2023 - -_Generally available in Grafana Cloud_ - -**Geomap marker symbol alignment options** - -You can now offset geomap marker symbols from the underlying data point. - -{{< figure src="/media/docs/grafana/gif-grafana-10-2-geomap-marker-symbol-alignment.gif" max-width="750px" caption="Geomap marker symbol alignment" >}} - -**Gauge visualization overflow support** - -You can now visualize gauges in vertical and horizontal orientations with overflow. This resolves an issue where the design would break when the number of gauges exceeded the available space. - -{{< figure src="/media/docs/grafana/gif-grafana-10-2-gauge-overflow.gif" max-width="750px" caption="Gauge overflow" >}} - -**Bar chart axes improvements** - -You can now center bar chart axes on zero and configure axes border and color settings. - -{{< figure src="/media/docs/grafana/screenshot-grafana-10-2-bar-chart-axes-improvements.png" max-width="750px" caption="Bar chart improvements" >}} - -## Detect unusable transformations - - - - - -October 24, 2023 - -_Available in public preview in Grafana Cloud_ - -We've added initial support to detect situations in which various transformations won't work appropriately based on current data. Previously, selecting the appropriate transformation and configuring it correctly required a process of trial and error or already knowing how a given transformation worked. Now, transformations that we've detected can't be used are shaded in the interface to indicate this, along with a helpful message explaining why. - -{{< figure src="/media/docs/grafana/transformations/disabled-transformation.png" caption="Transformation that has been disabled because it doesn't have the necessary data" >}} - -## Tempo data source: "Aggregate By" Search option to compute RED metrics over spans aggregated by attribute - - - - -October 24, 2023 - -_Experimental in Grafana Cloud_ - -We've added an **Aggregate By** option to the [TraceQL query editor](https://grafana.com/docs/grafana//datasources/tempo/query-editor/traceql-search/#write-traceql-queries-using-search) to leverage Grafana Cloud Traces' [metrics summary API](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/traces/metrics-summary-api/). You can calculate RED metrics (total span count, percent erroring spans, and latency information) for spans of `kind=server` received in the last hour that match your filter criteria, grouped by whatever attributes you specify. - -This feature is disabled by default. To enable it, file contact Grafana Support. - -For more information, refer to the [documentation](https://grafana.com/docs/grafana//datasources/tempo/query-editor/traceql-search/#optional-use-aggregate-by). - -{{< figure src="/media/docs/tempo/metrics-summary-10-2.png" caption="Aggregate by" >}} - -## Support for dashboard variables in transformations - - - - -October 24, 2023 - -_Experimental in Grafana Cloud_ - -Previously, the only transformation that supported [dashboard variables](https://grafana.com/docs/grafana//dashboards/variables/) was the **Add field from calculation** transformation. We've now extended the support for variables to the **Filter by value**, **Create heatmap**, **Histogram**, **Sort by**, **Limit**, **Filter by name**, and **Join by field** transformations. - -We've also made it easier to find the correct dashboard variable by displaying available variables in the fields that support them, either in the drop-down or as a suggestion when you type **$** or press Ctrl + Space: - -{{< figure src="/media/docs/grafana/transformations/completion.png" caption="Input with dashboard variable suggestions" >}} - -## Role mapping support for Google OIDC - - - - -October 24, 2023 - -_Generally available in Grafana Cloud_ - -You can now map Google groups to Grafana organizational roles when using Google OIDC. -This is useful if you want to limit the access users have to your Grafana instance. - -We've also added support for controlling allowed groups when using Google OIDC. - -Refer to the [Google Authentication documentation](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/google/) to learn how to use these new options. - -## Multiple spansets per trace - - - - -October 24, 2023 - -_Generally available in Grafana Cloud_ - -The [TraceQL query editor](https://grafana.com/docs/tempo//traceql/#traceql-query-editor) has been improved to facilitate the grouping of multiple spans per trace in TraceQL queries. For example, when the following `by(resource.service.name)` is added to your TraceQL query, it will group the spans in each trace by `resource.service.name`. - -{{< figure src="/media/docs/tempo/multiple-spansets-per-trace-10-2.png" max-width="750px" caption="Multiple spansets per trace" >}} - -## Temporary credentials in CloudWatch data source - - - - -October 24, 2023 - -_Available in private preview in Grafana Cloud_ - -The Grafana Assume Role authentication provider lets Grafana Cloud users of the CloudWatch data source authenticate with AWS without having to create and maintain long term AWS Users. Using the new assume role authentication method, you no longer have to rotate access and secret keys in your CloudWatch data source. Instead, Grafana Cloud users can create an identity access and management (IAM) role that has a trust relationship with Grafana's AWS account; Grafana's AWS account will then use AWS Secure Token Service (STS) to create temporary credentials to access the user's AWS data. - -To learn more, refer to the [CloudWatch authentication documentation](/docs/grafana/next/datasources/aws-cloudwatch/aws-authentication). - -## No basic role - - - - -October 12, 2023 - -_Generally available in Grafana Cloud_ - -We're excited to introduce the "No basic role," a new basic role with no permissions. A basic role in Grafana dictates the set of actions a user or entity can perform, known as permissions. This new role is especially beneficial if you're aiming for tailored, customized RBAC permissions for your service accounts or users. You can set this as a basic role through the API or UI. - -Previously, permissions were granted based on predefined sets of capabilities. Now, with the "No basic role," you have the flexibility to be even more granular. - -For more details on basic roles and permissions, refer to the [documentation](https://grafana.com/docs/grafana//administration/roles-and-permissions/). - -To assign the "No basic role" in your Grafana Cloud stack, contact Grafana Support and ask them to enable the `skip_org_role_sync` feature toggle. You'll be able to change basic roles that are synced using GCom. - -## Content outline - - - - -October 12, 2023 - -_Generally Available in Grafana Cloud_ - -Introducing Content Outline in Grafana **Explore**. We recognized the challenges of complex mixed queries, as well as, lengthy logs and traces results, leading to time-consuming navigation and the loss of context. Content outline is our first step towards seamless navigation from log lines to traces and back to queries ensuring quicker searches while preserving context. Experience efficient, contextual investigations with this update in Grafana Explore. To learn more, refer to the [Content outline documentation](https://grafana.com/docs/grafana//explore/#content-outline), as well as the following video demo. - -{{< video-embed src="/media/docs/grafana/explore/content-outline-demo.mp4" >}} - -## Public dashboards - - - - -October 12, 2023 - -_Generally Available in Grafana Cloud_ - -Public dashboards allow you to share your visualizations and insights to a broader audience without the requirement of a login. You can effortlessly use our current sharing model and create a public dashboard URL to share with anyone using the generated public URL link. To learn more, refer to the [Public dashboards documentation](https://grafana.com/docs/grafana//dashboards/dashboard-public/), as well as the following video demo: - -{{< video-embed src="/media/docs/grafana/dashboards/public-dashboards-demo.mp4" >}} - -## Correlations editor in Explore - - - - - -October 3, 2023 - -_Available in public preview in Grafana Cloud_ - -Creating correlations has just become easier. Try out our new correlations editor in **Explore** by selecting the **+ Add > Add correlation** option from the top bar or from the command palette. The editor shows all possible places where you can place data links and guides you through building and testing target queries. For more information, refer to [the documentation](https://grafana.com/docs/grafana//administration/correlations/). - -To enable this feature, contact Grafana Support. - -## Improved TraceQL query editor - - - - -October 3, 2023 - -_Generally available in Grafana Cloud_ - -The [TraceQL query editor](https://grafana.com/docs/tempo/latest/traceql/#traceql-query-editor) has been improved to facilitate the creation of TraceQL queries. In particular, it now features improved autocompletion, syntax highlighting, and error reporting. - -{{< video-embed src="/media/docs/tempo/screen-recording-grafana-10.2-traceql-query-editor-improvements.mp4" >}} - -## Recorded queries: Record multiple metrics from a single query - - - - -October 3, 2023 - -_Generally available in Grafana Cloud_ - -With recorded queries, a single recorded query can now record multiple metrics. - -## Issues snapshot in Kubernetes Monitoring - - - -September 29, 2023 - -_Generally available in Grafana Cloud_ - -To provide quicker identification and troubleshooting, the home page contains a snapshot of issues that reach the following thresholds: - -- Pods that have been in a non-running state for more than 15 minutes -- Nodes with CPU usage above 90% for more than five minutes -- Nodes using more than 90% of memory for more than five minutes -- Persistent Volumes with capacity above 90% -- Node disks with capacity above 90% - -(Release 1.3.1) -{{< figure max-width="80%" src="/media/docs/grafana-cloud/k8s/K8smon-snapshotview.png" caption="Home page snapshot view" >}} - -## Tenant database instance name and number for SAP HANA® data source - - - - -September 25, 2023 - -_Generally available in Grafana Cloud_ - -The SAP HANA® data source now supports tenant databases connections by using the database name and/or instance number. For more information, refer to [SAP HANA® configuration](/docs/plugins/grafana-saphana-datasource/latest/#configuration). - -{{< video-embed src="/media/docs/sap-hana/tenant.mp4" >}} - -## Distributed tracing in Grafana Cloud k6 - - - -September 19, 2023 - -_Generally available in Grafana Cloud_ - -You can now use the Grafana Cloud Traces integration with Grafana Cloud k6 to quickly debug failed performance tests and proactively improve application reliability. - -Distributed tracing in Grafana Cloud k6 only requires two things: - -- An application instrumented for tracing with Grafana Cloud Traces. -- Adding a few lines of code to your existing k6 scripts. - -The integration works by having k6 inject tracing metadata into the requests it sends to your backend services when you run a test. The tracing data is then correlated with k6 test run data, so you can understand how your services and operations behaved during the whole test run. The collected tracing data is aggregated to generate real-time metrics—such as frequency of calls, error rates, and percentile latencies—that can help you narrow your search space and quickly spot anomalies. - -To learn more, refer to the [Integration with Grafana Cloud Traces documentation](/docs/grafana-cloud/k6/analyze-results/integration-with-grafana-cloud-traces/) and [Distributed Tracing in Grafana Cloud k6 blog post](https://grafana.com/blog/2023/09/19/troubleshoot-failed-performance-tests-faster-with-distributed-tracing-in-grafana-cloud-k6/). - -## New browse dashboards - - - - -September 19, 2023 - -_Generally available in Grafana Cloud_ - -The new browse dashboards interface features a more compact design, making it easier to navigate, search for, and manage for your folders and dashboards. The new interface also has many performance improvements, especially for instances with a large number of folders and dashboards. - -To make using folders easier and more consistent, there is no longer a special **General** folder. Dashboards without a folder, or dashboards previously in **General**, are now shown at the root level. - -To learn more, refer to the following video demo. - -{{< video-embed src="/media/docs/grafana/2023-09-11-New-Browse-Dashboards-Enablement-Video.mp4" >}} - -## Streamlined configuration of Kubernetes Monitoring - - - -September 15, 2023 - -_Generally available in Grafana Cloud_ - -Configure with [Grafana Kubernetes Monitoring Helm chart](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/kubernetes-monitoring/configuration/config-k8s-agent-flow) using a streamlined process. With this method, you can set on/off switches to gather metrics, logs, events, traces, and cost metrics. (Release 1.2.0) - -{{< figure max-width="60%" src="/media/docs/grafana-cloud/k8s/k8smon-config-wizard.png" caption="Configuration wizard" >}} - -## Tabs navigation in Kubernetes Monitoring - - - -September 14, 2023 - -_Generally available in Grafana Cloud_ - -Quickly switch between the Cluster, namespace, workload, and Node views on the **Cluster Navigation** page using tabs. (Release 1.3.0) - -{{< figure max-width="40%" src="/media/docs/grafana-cloud/k8s/k8smon-clusternav-tabs.png" caption="Tabs on **Cluster Navigation** page" >}} - -## Data source menu on Cost and Efficiency views in Kubernetes Monitoring - - - -September 14, 2023 - -_Generally available in Grafana Cloud_ - -You can change the data source you are viewing on the **Cost** and **Efficiency** views. (Release 1.2.1) - -## Predict namespace memory usage in Kubernetes Monitoring - - - -September 14, 2023 - -_Generally available in Grafana Cloud_ - -Click **Predict Memory usage** to predict namespace memory usage on the namespace detail page. (Release 1.2.1) - -{{< figure max-width="50%" src="/media/docs/grafana-cloud/k8s/k8smon-predict-memusage-namespace.png" caption="**Predict Memory usage** button" >}} - -## Traces collection with Kubernetes Monitoring - - - -September 14, 2023 - -_Generally available in Grafana Cloud_ - -Collect traces when you configure Kubernetes Monitoring, and then use Tempo to create search queries. Refer to [Navigate to traces](/docs/grafana-cloud/monitor-infrastructure/kubernetes-monitoring/navigate-k8s-monitoring/#navigate-to-traces) for more information. (Release 1.3.0) - -## Kafka integration in Kubernetes Monitoring - - - -September 14, 2023 - -_Generally available in Grafana Cloud_ - -The Kafka integration is available for use in Kubernetes Monitoring. (Release 1.3.6) - -## Create correlations for provisioned data sources - - - - - -September 13, 2023 - -_Available in public preview in Grafana Cloud_ - -You can now create correlations using either the **Administration** page or provisioning, regardless of whether a data source was provisioned or not. In previous versions of Grafana, if a data source was provisioned, the only way to add correlations to it was also with provisioning. Now, that's no longer the case, and you can easily create new correlations mixing both methods—using the **Administration** page or provisioning. - -To enable this feature, contact Grafana Support. - -## Grafana OnCall integration for Alerting - - - - -September 13, 2023 - -_Generally available in Grafana Cloud_ - -Use the Grafana Alerting - Grafana OnCall integration to effortlessly connect alerts generated by Grafana Alerting with Grafana OnCall. From there, you can route them according to defined escalation chains and schedules. - -To learn more, refer to the [Grafana OnCall integration for Alerting documentation](/docs/grafana/next/alerting/alerting-rules/manage-contact-points/configure-oncall/). - -## API throttling for Datadog data source - - - - -September 1, 2023 - -_Generally available in Grafana Cloud_ - -The Datadog data source supports blocking API requests based on upstream rate limits (for metric queries). With this update, you can set a rate limit percentage at which the plugin stops sending queries. - -To learn more, refer to [Datadog data source settings](/docs/plugins/grafana-datadog-datasource/latest#configure-the-data-source), as well as the following video demo. - -{{< video-embed src="/media/docs/datadog/datadog-rate-limit.mp4" >}} - -## Log aggregation for Datadog data source - - - - -August 31, 2023 - -_Generally available in Grafana Cloud_ - -The Datadog data source now supports log aggregation. This feature helps aggregate logs/events into buckets and compute metrics and time series. For more information, refer to [Datadog log aggregation](/docs/plugins/grafana-datadog-datasource/latest#logs-analytics--aggregation). - -{{< video-embed src="/media/docs/datadog/datadog-log-aggregation.mp4" >}} - -## Permission validation on custom role creation and update - - - - - - -August 25, 2023 - -_Generally available in Grafana Cloud_ - -With the current release, we enabled RBAC permission validation (`rbac.permission_validation_enabled` setting) by default. This means that the permissions provided in the request during custom role creation or update are validated against the list of [available permissions and their scopes](https://grafana.com/docs/grafana//administration/roles-and-permissions/access-control/custom-role-actions-scopes/#action-definitions). If the request contains a permission that is not available or the scope of the permission is not valid, the request is rejected with an error message. - -## Query-type template variables for Tempo data source - - - - -August 24, 2023 - -_Generally available in Grafana Cloud_ - -The Tempo data source now supports query-type template variables. With this update, you can create variables for which the values are a list of attribute names or attribute values seen on spans received by Tempo. - -To learn more, refer to the following video demo, as well as the [Grafana Variables documentation](/docs/grafana/next/dashboards/variables/). - -{{< video-embed src="/media/docs/tempo/screen-recording-grafana-10.2-tempo-query-type-template-variables.mp4" >}} diff --git a/e2e/cypress/plugins/compareScreenshots.js b/e2e/cypress/plugins/compareScreenshots.js deleted file mode 100644 index 426d12adac57e..0000000000000 --- a/e2e/cypress/plugins/compareScreenshots.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict'; -const BlinkDiff = require('blink-diff'); -const { resolve } = require('path'); - -// @todo use npmjs.com/pixelmatch or an available cypress plugin -const compareScreenshots = async ({ config, screenshotsFolder, specName }) => { - const name = config.name || config; // @todo use `??` - const threshold = config.threshold || 0.001; // @todo use `??` - - const imageAPath = `${screenshotsFolder}/${specName}/${name}.png`; - const imageBPath = resolve(`${screenshotsFolder}/../expected/${specName}/${name}.png`); - - const imageOutputPath = screenshotsFolder.endsWith('actual') ? imageAPath.replace('.png', '.diff.png') : undefined; - - const { code } = await new Promise((resolve, reject) => { - new BlinkDiff({ - imageAPath, - imageBPath, - imageOutputPath, - threshold, - thresholdType: BlinkDiff.THRESHOLD_PERCENT, - }).run((error, result) => { - if (error) { - reject(error); - } else { - resolve(result); - } - }); - }); - - if (code <= 1) { - let msg = `\nThe screenshot [${imageAPath}] differs from [${imageBPath}]`; - msg += '\n'; - msg += '\nCheck the Artifacts tab in the CircleCi build output for the actual screenshots.'; - msg += '\n'; - msg += '\n If the difference between expected and outcome is NOT acceptable then do the following:'; - msg += '\n - Check the code for changes that causes this difference, fix that and retry.'; - msg += '\n'; - msg += '\n If the difference between expected and outcome is acceptable then do the following:'; - msg += '\n - Replace the expected image with the outcome and retry.'; - msg += '\n'; - throw new Error(msg); - } else { - // Must return a value - return true; - } -}; - -module.exports = compareScreenshots; diff --git a/e2e/cypress/plugins/index.js b/e2e/cypress/plugins/index.js index 7ec85fecae132..596d58acca953 100644 --- a/e2e/cypress/plugins/index.js +++ b/e2e/cypress/plugins/index.js @@ -2,7 +2,6 @@ const fs = require('fs'); const path = require('path'); const benchmarkPlugin = require('./benchmark'); -const compareScreenshots = require('./compareScreenshots'); const extendConfig = require('./extendConfig'); const readProvisions = require('./readProvisions'); const typescriptPreprocessor = require('./typescriptPreprocessor'); @@ -13,7 +12,6 @@ module.exports = (on, config) => { } on('file:preprocessor', typescriptPreprocessor); - on('task', { compareScreenshots, readProvisions }); on('task', { log({ message, optional }) { optional ? console.log(message, optional) : console.log(message); diff --git a/e2e/cypress/support/commands.js b/e2e/cypress/support/commands.js index 27f72b2489062..c1be8c4413bac 100644 --- a/e2e/cypress/support/commands.js +++ b/e2e/cypress/support/commands.js @@ -1,13 +1,5 @@ import 'cypress-file-upload'; -Cypress.Commands.add('compareScreenshots', (config) => { - cy.task('compareScreenshots', { - config, - screenshotsFolder: Cypress.config('screenshotsFolder'), - specName: Cypress.spec.name, - }); -}); - Cypress.Commands.add('logToConsole', (message, optional) => { cy.task('log', { message: '(' + new Date().toISOString() + ') ' + message, optional }); }); diff --git a/e2e/cypress/support/index.d.ts b/e2e/cypress/support/index.d.ts index 40dcf83105e73..a62601e97c189 100644 --- a/e2e/cypress/support/index.d.ts +++ b/e2e/cypress/support/index.d.ts @@ -1,13 +1,7 @@ /// -interface CompareScreenshotsConfig { - name: string; - threshold?: number; -} - declare namespace Cypress { interface Chainable { - compareScreenshots(config: CompareScreenshotsConfig | string): Chainable; logToConsole(message: string, optional?: unknown): void; readProvisions(filePaths: string[]): Chainable; getJSONFilesFromDir(dirPath: string): Chainable; diff --git a/e2e/panels-suite/dashlist.spec.ts b/e2e/panels-suite/dashlist.spec.ts new file mode 100644 index 0000000000000..ec053d3e5e45f --- /dev/null +++ b/e2e/panels-suite/dashlist.spec.ts @@ -0,0 +1,37 @@ +import { e2e } from '../utils'; +const PAGE_UNDER_TEST = 'a6801696-cc53-4196-b1f9-2403e3909185/panel-tests-dashlist-variables'; + +describe('DashList panel', () => { + beforeEach(() => { + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); + }); + + // this is to prevent the fix for https://github.com/grafana/grafana/issues/76800 from regressing + it('should pass current variable values correctly when `Include current template variable values` is set', () => { + e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST }); + + // check the initial value of the urls contain the variable value correctly + e2e.components.Panels.Panel.title('Include time range and variables enabled') + .should('be.visible') + .within(() => { + cy.get('a').each(($el) => { + cy.wrap($el).should('have.attr', 'href').and('contain', 'var-server=A'); + }); + }); + + // update variable to b + e2e.pages.Dashboard.SubMenu.submenuItemLabels('server').click(); + e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('B').click(); + // blur the dropdown + cy.get('body').click(); + + // check the urls are updated with the new variable value + e2e.components.Panels.Panel.title('Include time range and variables enabled') + .should('be.visible') + .within(() => { + cy.get('a').each(($el) => { + cy.wrap($el).should('have.attr', 'href').and('contain', 'var-server=B'); + }); + }); + }); +}); diff --git a/e2e/datagrid-suite/datagrid-data-change.spec.ts b/e2e/panels-suite/datagrid-data-change.spec.ts similarity index 94% rename from e2e/datagrid-suite/datagrid-data-change.spec.ts rename to e2e/panels-suite/datagrid-data-change.spec.ts index 48c14f26ee39d..583f30e267f91 100644 --- a/e2e/datagrid-suite/datagrid-data-change.spec.ts +++ b/e2e/panels-suite/datagrid-data-change.spec.ts @@ -3,7 +3,8 @@ import { e2e } from '../utils'; const DASHBOARD_ID = 'c01bf42b-b783-4447-a304-8554cee1843b'; const DATAGRID_SELECT_SERIES = 'Datagrid Select series'; -describe('Datagrid data changes', () => { +//TODO enable this test when panel goes live +describe.skip('Datagrid data changes', () => { beforeEach(() => { e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); }); diff --git a/e2e/datagrid-suite/datagrid-editing-features.spec.ts b/e2e/panels-suite/datagrid-editing-features.spec.ts similarity index 98% rename from e2e/datagrid-suite/datagrid-editing-features.spec.ts rename to e2e/panels-suite/datagrid-editing-features.spec.ts index 60c5f73459ece..e3592f60388ca 100644 --- a/e2e/datagrid-suite/datagrid-editing-features.spec.ts +++ b/e2e/panels-suite/datagrid-editing-features.spec.ts @@ -3,7 +3,8 @@ import { e2e } from '../utils'; const DASHBOARD_ID = 'c01bf42b-b783-4447-a304-8554cee1843b'; const DATAGRID_CANVAS = 'data-grid-canvas'; -describe('Datagrid data changes', () => { +//TODO enable this test when panel goes live +describe.skip('Datagrid data changes', () => { beforeEach(() => { e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); }); diff --git a/e2e/panels-suite/geomap-spatial-operations-transform.spec.ts b/e2e/panels-suite/geomap-spatial-operations-transform.spec.ts index 79608bbce6871..52ca7ed0fac5d 100644 --- a/e2e/panels-suite/geomap-spatial-operations-transform.spec.ts +++ b/e2e/panels-suite/geomap-spatial-operations-transform.spec.ts @@ -10,6 +10,7 @@ describe('Geomap spatial operations', () => { it('Tests location auto option', () => { e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { editPanel: 1 } }); e2e.components.Tab.title('Transform data').should('be.visible').click(); + e2e.components.Transforms.addTransformationButton().scrollIntoView().should('be.visible').click(); e2e.components.TransformTab.newTransform('Spatial operations').scrollIntoView().should('be.visible').click(); e2e.components.Transforms.SpatialOperations.actionLabel().type('Prepare spatial field{enter}'); @@ -27,6 +28,7 @@ describe('Geomap spatial operations', () => { it('Tests location coords option', () => { e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { editPanel: 1 } }); e2e.components.Tab.title('Transform data').should('be.visible').click(); + e2e.components.Transforms.addTransformationButton().scrollIntoView().should('be.visible').click(); e2e.components.TransformTab.newTransform('Spatial operations').scrollIntoView().should('be.visible').click(); e2e.components.Transforms.SpatialOperations.actionLabel().type('Prepare spatial field{enter}'); @@ -50,6 +52,7 @@ describe('Geomap spatial operations', () => { it('Tests geoshash field column appears in table view', () => { e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { editPanel: 1 } }); e2e.components.Tab.title('Transform data').should('be.visible').click(); + e2e.components.Transforms.addTransformationButton().scrollIntoView().should('be.visible').click(); e2e.components.TransformTab.newTransform('Spatial operations').scrollIntoView().should('be.visible').click(); e2e.components.Transforms.SpatialOperations.actionLabel().type('Prepare spatial field{enter}'); @@ -72,6 +75,7 @@ describe('Geomap spatial operations', () => { it('Tests location lookup option', () => { e2e.flows.openDashboard({ uid: DASHBOARD_ID, queryParams: { editPanel: 1 } }); e2e.components.Tab.title('Transform data').should('be.visible').click(); + e2e.components.Transforms.addTransformationButton().scrollIntoView().should('be.visible').click(); e2e.components.TransformTab.newTransform('Spatial operations').scrollIntoView().should('be.visible').click(); e2e.components.Transforms.SpatialOperations.actionLabel().type('Prepare spatial field{enter}'); diff --git a/e2e/panels-suite/panelEdit_base.spec.ts b/e2e/panels-suite/panelEdit_base.spec.ts index f3792dae53222..744c41ed8ce43 100644 --- a/e2e/panels-suite/panelEdit_base.spec.ts +++ b/e2e/panels-suite/panelEdit_base.spec.ts @@ -39,7 +39,7 @@ describe('Panel edit tests', () => { e2e.components.Tab.active().within((li: JQuery) => { expect(li.text()).equals('Transform data0'); // there's no transform so therefore Transform + 0 }); - e2e.components.Transforms.card('Merge').scrollIntoView().should('be.visible'); + e2e.components.Transforms.addTransformationButton().scrollIntoView().should('be.visible'); e2e.components.QueryTab.content().should('not.exist'); e2e.components.AlertTab.content().should('not.exist'); e2e.components.PanelAlertTabContent.content().should('not.exist'); diff --git a/e2e/panels-suite/panelEdit_transforms.spec.ts b/e2e/panels-suite/panelEdit_transforms.spec.ts index 5cc191d000d17..c71f649791c61 100644 --- a/e2e/panels-suite/panelEdit_transforms.spec.ts +++ b/e2e/panels-suite/panelEdit_transforms.spec.ts @@ -9,7 +9,9 @@ describe('Panel edit tests - transformations', () => { e2e.flows.openDashboard({ uid: '5SdHCadmz', queryParams: { editPanel: 3 } }); e2e.components.Tab.title('Transform data').should('be.visible').click(); + e2e.components.Transforms.addTransformationButton().scrollIntoView().should('be.visible').click(); e2e.components.TransformTab.newTransform('Reduce').scrollIntoView().should('be.visible').click(); - e2e.components.Transforms.Reduce.calculationsLabel().should('be.visible'); + e2e.components.Transforms.Reduce.calculationsLabel().scrollIntoView().should('be.visible'); + e2e.components.Transforms.Reduce.modeLabel().should('be.visible'); }); }); diff --git a/e2e/utils/flows/configurePanel.ts b/e2e/utils/flows/configurePanel.ts index 20139f1876b4f..4aa6a6cc5ab65 100644 --- a/e2e/utils/flows/configurePanel.ts +++ b/e2e/utils/flows/configurePanel.ts @@ -21,9 +21,7 @@ interface ConfigurePanelDefault { route: string | RegExp; }; dashboardUid: string; - matchScreenshot: boolean; saveDashboard: boolean; - screenshotName: string; visitDashboardAtStart: boolean; // @todo remove when possible } @@ -60,9 +58,7 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC route: '/api/ds/query', }, dashboardUid: lastAddedDashboardUid, - matchScreenshot: false, saveDashboard: true, - screenshotName: 'panel-visualization', visitDashboardAtStart: true, ...config, }; @@ -72,10 +68,8 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC dashboardUid, dataSourceName, isEdit, - matchScreenshot, panelTitle, queriesForm, - screenshotName, timeRange, visitDashboardAtStart, visualizationName, @@ -157,15 +151,6 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC // Wait for RxJS cy.wait(timeout ?? Cypress.config().defaultCommandTimeout); - if (matchScreenshot) { - let visualization; - - visualization = e2e.components.Panels.Panel.containerByTitle(panelTitle).find('.panel-content'); - - visualization.scrollIntoView().screenshot(screenshotName); - cy.compareScreenshots(screenshotName); - } - // @todo remove `wrap` when possible return cy.wrap({ config: fullConfig }, { log: false }); }); diff --git a/e2e/various-suite/exemplars.spec.ts b/e2e/various-suite/exemplars.spec.ts index 97da7f3aabd22..62d1ce43ea887 100644 --- a/e2e/various-suite/exemplars.spec.ts +++ b/e2e/various-suite/exemplars.spec.ts @@ -55,7 +55,7 @@ describe('Exemplars', () => { cy.contains(dataSourceName).scrollIntoView().should('be.visible').click(); // Switch to code editor - cy.contains('label', 'Code').click(); + e2e.components.RadioButton.container().filter(':contains("Code")').click(); // we need to wait for the query-field being lazy-loaded, in two steps: // 1. first we wait for the text 'Loading...' to appear diff --git a/e2e/various-suite/loki-editor.spec.ts b/e2e/various-suite/loki-editor.spec.ts index 8ba7d4647f61b..189c9d5a131cb 100644 --- a/e2e/various-suite/loki-editor.spec.ts +++ b/e2e/various-suite/loki-editor.spec.ts @@ -37,7 +37,7 @@ describe('Loki Query Editor', () => { e2e.components.DataSourcePicker.container().should('be.visible').click(); cy.contains(dataSourceName).scrollIntoView().should('be.visible').click(); - cy.contains('Code').click(); + e2e.components.RadioButton.container().filter(':contains("Code")').click(); // Wait for lazy loading const monacoLoadingText = 'Loading...'; diff --git a/e2e/various-suite/loki-query-builder.spec.ts b/e2e/various-suite/loki-query-builder.spec.ts index 348a4d92ab5fb..40141bb7c2b13 100644 --- a/e2e/various-suite/loki-query-builder.spec.ts +++ b/e2e/various-suite/loki-query-builder.spec.ts @@ -78,7 +78,8 @@ describe('Loki query builder', () => { cy.contains(finalQuery).should('be.visible'); // Change to code editor - cy.contains('label', 'Code').click(); + e2e.components.RadioButton.container().filter(':contains("Code")').click(); + // We need to test this manually because the final query is split into separate DOM elements using cy.contains(finalQuery).should('be.visible'); does not detect the query. cy.contains('rate').should('be.visible'); cy.contains('instance1|instance2').should('be.visible'); diff --git a/e2e/various-suite/loki-table-explore-to-dash.spec.ts b/e2e/various-suite/loki-table-explore-to-dash.spec.ts new file mode 100644 index 0000000000000..5a6bb85dade50 --- /dev/null +++ b/e2e/various-suite/loki-table-explore-to-dash.spec.ts @@ -0,0 +1,214 @@ +import { e2e } from '../utils'; + +const dataSourceName = 'LokiEditor'; +const addDataSource = () => { + e2e.flows.addDataSource({ + type: 'Loki', + expectedAlertMessage: 'Unable to connect with Loki. Please check the server logs for more details.', + name: dataSourceName, + form: () => { + cy.get('#connection-url').type('http://loki-url:3100'); + }, + }); +}; + +const lokiQueryResult = { + status: 'success', + results: { + A: { + status: 200, + frames: [ + { + schema: { + refId: 'A', + meta: { + typeVersion: [0, 0], + custom: { + frameType: 'LabeledTimeValues', + }, + stats: [ + { + displayName: 'Summary: bytes processed per second', + unit: 'Bps', + value: 223921, + }, + { + displayName: 'Summary: total bytes processed', + unit: 'decbytes', + value: 4156, + }, + { + displayName: 'Summary: exec time', + unit: 's', + value: 0.01856, + }, + ], + executedQueryString: 'Expr: {targetLabelName="targetLabelValue"}', + }, + fields: [ + { + name: 'labels', + type: 'other', + typeInfo: { + frame: 'json.RawMessage', + }, + }, + { + name: 'Time', + type: 'time', + typeInfo: { + frame: 'time.Time', + }, + }, + { + name: 'Line', + type: 'string', + typeInfo: { + frame: 'string', + }, + }, + { + name: 'tsNs', + type: 'string', + typeInfo: { + frame: 'string', + }, + }, + { + name: 'id', + type: 'string', + typeInfo: { + frame: 'string', + }, + }, + ], + }, + data: { + values: [ + [ + { + targetLabelName: 'targetLabelValue', + instance: 'server\\1', + job: '"grafana/data"', + nonIndexed: 'value', + place: 'moon', + re: 'one.two$three^four', + source: 'data', + }, + ], + [1700077283237], + [ + '{"_entry":"log text with ANSI \\u001b[31mpart of the text\\u001b[0m [149702545]","counter":"22292","float":"NaN","wave":-0.5877852522916832,"label":"val3","level":"info"}', + ], + ['1700077283237000000'], + ['1700077283237000000_9b025d35'], + ], + }, + }, + ], + }, + }, +}; + +describe('Loki Query Editor', () => { + beforeEach(() => { + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); + }); + + afterEach(() => { + e2e.flows.revertAllChanges(); + }); + + beforeEach(() => { + cy.window().then((win) => { + win.localStorage.setItem('grafana.featureToggles', 'logsExploreTableVisualisation=1'); + }); + }); + it('Should be able to add explore table to dashboard', () => { + addDataSource(); + + cy.intercept(/labels?/, (req) => { + req.reply({ status: 'success', data: ['instance', 'job', 'source'] }); + }); + + cy.intercept(/series?/, (req) => { + req.reply({ status: 'success', data: [{ instance: 'instance1' }] }); + }); + + cy.intercept(/\/api\/ds\/query\?ds_type=loki?/, (req) => { + req.reply(lokiQueryResult); + }); + + // Go to Explore and choose Loki data source + e2e.pages.Explore.visit(); + e2e.components.DataSourcePicker.container().should('be.visible').click(); + cy.contains(dataSourceName).scrollIntoView().should('be.visible').click(); + + cy.contains('Code').click({ force: true }); + + // Wait for lazy loading + const monacoLoadingText = 'Loading...'; + + e2e.components.QueryField.container().should('be.visible').should('have.text', monacoLoadingText); + e2e.components.QueryField.container().should('be.visible').should('not.have.text', monacoLoadingText); + + // Write a simple query + e2e.components.QueryField.container().type('query').type('{instance="instance1"'); + cy.get('.monaco-editor textarea:first').should(($el) => { + expect($el.val()).to.eq('query{instance="instance1"}'); + }); + + // Submit the query + e2e.components.QueryField.container().type('{shift+enter}'); + // Assert the no-data message is not visible + cy.get('[data-testid="explore-no-data"]').should('not.exist'); + + // Click on the table toggle + cy.contains('Table').click({ force: true }); + + // One row with two cells + cy.get('[role="cell"]').should('have.length', 2); + + cy.contains('label', 'targetLabelName').should('be.visible'); + cy.contains('label', 'targetLabelName').click(); + cy.contains('label', 'targetLabelName').within(() => { + cy.get('input[type="checkbox"]').check({ force: true }); + }); + + cy.contains('label', 'targetLabelName').within(() => { + cy.get('input[type="checkbox"]').should('be.checked'); + }); + + const exploreCells = cy.get('[role="cell"]'); + + // Now we should have a row with 3 columns + exploreCells.should('have.length', 3); + // And a value of "targetLabelValue" + exploreCells.should('contain', 'targetLabelValue'); + + const addToDashboardButton = cy.get('[aria-label="Add to dashboard"]'); + + // Now let's add this to a dashboard + addToDashboardButton.should('be.visible'); + addToDashboardButton.click(); + + const addPanelToDashboardButton = cy.contains('Add panel to dashboard'); + addPanelToDashboardButton.should('be.visible'); + + const openDashboardButton = cy.contains('Open dashboard'); + openDashboardButton.should('be.visible'); + openDashboardButton.click(); + + const panel = cy.get('[data-panelid="1"]'); + panel.should('be.visible'); + + const cells = panel.find('[role="table"] [role="cell"]'); + // Should have 3 columns + cells.should('have.length', 3); + // Cells contain strings found in log line + cells.contains('"wave":-0.5877852522916832'); + + // column has correct value of "targetLabelValue", need to requery the DOM because of the .contains call above + cy.get('[data-panelid="1"]').find('[role="table"] [role="cell"]').contains('targetLabelValue'); + }); +}); diff --git a/e2e/various-suite/mysql.spec.ts b/e2e/various-suite/mysql.spec.ts index 6ef2502d87bb4..99746b008cada 100644 --- a/e2e/various-suite/mysql.spec.ts +++ b/e2e/various-suite/mysql.spec.ts @@ -9,10 +9,6 @@ const normalTableName = tablesResponse.results.tables.frames[0].data.values[0][0 describe('MySQL datasource', () => { beforeEach(() => { - e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); - }); - - it('code editor autocomplete should handle table name escaping/quoting', () => { cy.intercept('POST', '/api/ds/query', (req) => { if (req.body.queries[0].refId === 'datasets') { req.alias = 'datasets'; @@ -31,12 +27,16 @@ describe('MySQL datasource', () => { }); } }); - + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD')); e2e.pages.Explore.visit(); e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-mysql{enter}'); + cy.wait('@datasets'); + }); + + it('code editor autocomplete should handle table name escaping/quoting', () => { + e2e.components.RadioButton.container().filter(':contains("Code")').click(); - cy.get("label[for^='option-code']").should('be.visible').click(); cy.get('textarea').type('S{downArrow}{enter}'); cy.wait('@tables'); cy.get('.suggest-widget').contains(tableNameWithSpecialCharacter).should('be.visible'); @@ -60,4 +60,61 @@ describe('MySQL datasource', () => { cy.get('textarea').type('.'); cy.get('.suggest-widget').contains('No suggestions.').should('be.visible'); }); + + describe('visual query builder', () => { + it('should be able to add timeFilter macro', () => { + cy.get("[aria-label='Table selector']").should('be.visible').click(); + selectOption(normalTableName); + // Open column selector + cy.get("[id^='select-column-0']").should('be.visible').click(); + selectOption('createdAt'); + + // Toggle where row + cy.get("label[for^='sql-filter']").last().should('be.visible').click(); + + // Click add filter button + cy.get('button[title="Add filter"]').should('be.visible').click(); + cy.get('button[title="Add filter"]').should('be.visible').click(); // For some reason we need to click twice + + // Open field selector + cy.get("[aria-label='Field']").should('be.visible').click(); + selectOption('createdAt'); + + // Open operator selector + cy.get("[aria-label='Operator']").should('be.visible').click(); + selectOption('Macros'); + + // Open macros value selector + cy.get("[aria-label='Macros value selector']").should('be.visible').click(); + selectOption('timeFilter'); + + // Validate that the timeFilter macro was added + + e2e.components.CodeEditor.container() + .get('textarea') + .should( + 'have.value', + `SELECT\n createdAt\nFROM\n DataMaker.normalTable\nWHERE\n $__timeFilter(createdAt)\nLIMIT\n 50` + ); + + // Validate that the timeFilter macro was removed when changed to equals operator + + // For some reason the input is not visible the second time so we need to force the click + cy.get("[aria-label='Operator']").click({ force: true }); + selectOption('=='); + + e2e.components.DateTimePicker.input().should('be.visible').click().blur(); + + e2e.components.CodeEditor.container() + .get('textarea') + .should( + 'not.have.value', + `SELECT\n createdAt\nFROM\n DataMaker.normalTable\nWHERE\n $__timeFilter(createdAt)\nLIMIT\n 50` + ); + }); + }); }); + +function selectOption(option: string) { + cy.get("[aria-label='Select option']").contains(option).should('be.visible').click(); +} diff --git a/e2e/various-suite/navigation.spec.ts b/e2e/various-suite/navigation.spec.ts index 35ee5ee90f4ee..b068d56f3ad37 100644 --- a/e2e/various-suite/navigation.spec.ts +++ b/e2e/various-suite/navigation.spec.ts @@ -15,7 +15,7 @@ describe('Docked Navigation', () => { it('should remain docked when reloading the page', () => { // Expand, then dock the mega menu - cy.get('[aria-label="Toggle menu"]').click(); + cy.get('[aria-label="Open menu"]').click(); cy.get('[aria-label="Dock menu"]').click(); e2e.components.NavMenu.Menu().should('be.visible'); @@ -26,7 +26,7 @@ describe('Docked Navigation', () => { it('should remain docked when navigating to another page', () => { // Expand, then dock the mega menu - cy.get('[aria-label="Toggle menu"]').click(); + cy.get('[aria-label="Open menu"]').click(); cy.get('[aria-label="Dock menu"]').click(); cy.contains('a', 'Administration').click(); diff --git a/e2e/various-suite/query-editor.spec.ts b/e2e/various-suite/query-editor.spec.ts index de383f23940ad..2263f1ffacfeb 100644 --- a/e2e/various-suite/query-editor.spec.ts +++ b/e2e/various-suite/query-editor.spec.ts @@ -12,7 +12,7 @@ describe('Query editor', () => { cy.contains('gdev-prometheus').scrollIntoView().should('be.visible').click(); const queryText = `rate(http_requests_total{job="grafana"}[5m])`; - cy.contains('label', 'Code').click(); + e2e.components.RadioButton.container().filter(':contains("Code")').click(); // we need to wait for the query-field being lazy-loaded, in two steps: // it is a two-step process: diff --git a/e2e/various-suite/visualization-suggestions.spec.ts b/e2e/various-suite/visualization-suggestions.spec.ts index 100953980f5c9..aef309ea45221 100644 --- a/e2e/various-suite/visualization-suggestions.spec.ts +++ b/e2e/various-suite/visualization-suggestions.spec.ts @@ -10,7 +10,7 @@ describe('Visualization suggestions', () => { // Try visualization suggestions e2e.components.PanelEditor.toggleVizPicker().click(); - cy.contains('Suggestions').click(); + e2e.components.RadioButton.container().filter(':contains("Suggestions")').click(); // Verify we see suggestions e2e.components.VisualizationPreview.card('Line chart').should('be.visible'); diff --git a/go.mod b/go.mod index c2fb95f1d942f..9d32a2a06ce18 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/grafana/grafana -go 1.20 +go 1.21 // Override docker/docker to avoid: // go: github.com/drone-runners/drone-runner-docker@v1.8.2 requires @@ -13,10 +13,10 @@ replace cuelang.org/go => github.com/grafana/cue v0.0.0-20230926092038-971951014 // TODO: following otel replaces to pin the libraries so k8s.io/apiserver doesn't downgrade us inadvertantly // will need bumps as we upgrade otel in Grafana replace ( - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // @grafana/backend-platform - go.opentelemetry.io/otel => go.opentelemetry.io/otel v1.19.0 // @grafana/backend-platform - go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v1.19.0 // @grafana/backend-platform - go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v1.19.0 // @grafana/backend-platform + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // @grafana/backend-platform + go.opentelemetry.io/otel => go.opentelemetry.io/otel v1.21.0 // @grafana/backend-platform + go.opentelemetry.io/otel/metric => go.opentelemetry.io/otel/metric v1.21.0 // @grafana/backend-platform + go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v1.21.0 // @grafana/backend-platform ) // Override Prometheus version because Prometheus v2.X is tagged as v0.X for Go modules purposes and Go assumes @@ -25,8 +25,11 @@ replace ( replace github.com/prometheus/prometheus => github.com/prometheus/prometheus v0.43.0 // Includes https://github.com/kubernetes/kube-openapi/pull/420 -// This will not be required in the next k8s release -replace k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f => github.com/ryantxu/kube-openapi v0.0.0-20230824154605-fe0f3703fd8d // @grafana/grafana-app-platform-squad +// This will not be required in the next k8s release @v28-with-hook +replace k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 => github.com/ryantxu/kube-openapi v0.0.0-20231113051506-80b8e1dfdde6 // @grafana/grafana-app-platform-squad + +// The v0.120.0 is needed for now to be compatible with grafana/thema. +replace github.com/getkin/kin-openapi => github.com/getkin/kin-openapi v0.120.0 require ( cloud.google.com/go/storage v1.30.1 // @grafana/backend-platform @@ -45,7 +48,6 @@ require ( github.com/crewjam/saml v0.4.13 // @grafana/grafana-authnz-team github.com/fatih/color v1.15.0 // @grafana/backend-platform github.com/gchaincl/sqlhooks v1.3.0 // @grafana/backend-platform - github.com/go-git/go-git/v5 v5.4.2 // @grafana/grafana-app-platform-squad github.com/go-ldap/ldap/v3 v3.4.4 // @grafana/grafana-authnz-team github.com/go-openapi/strfmt v0.21.7 // @grafana/alerting-squad-backend github.com/go-redis/redis/v8 v8.11.5 // @grafana/backend-platform @@ -58,17 +60,17 @@ require ( github.com/golang/mock v1.6.0 // @grafana/alerting-squad-backend github.com/golang/snappy v0.0.4 // @grafana/alerting-squad-backend github.com/google/go-cmp v0.6.0 // @grafana/backend-platform - github.com/google/uuid v1.3.1 // @grafana/backend-platform + github.com/google/uuid v1.4.0 // @grafana/backend-platform github.com/google/wire v0.5.0 // @grafana/backend-platform github.com/gorilla/websocket v1.5.0 // @grafana/grafana-app-platform-squad - github.com/grafana/alerting v0.0.0-20231026192550-079966731bbe // @grafana/alerting-squad-backend - github.com/grafana/cuetsy v0.1.10 // @grafana/grafana-as-code + github.com/grafana/alerting v0.0.0-20231101090315-bf12694896a8 // @grafana/alerting-squad-backend + github.com/grafana/cuetsy v0.1.11 // @grafana/grafana-as-code github.com/grafana/grafana-aws-sdk v0.19.1 // @grafana/aws-datasources github.com/grafana/grafana-azure-sdk-go v1.9.0 // @grafana/backend-platform - github.com/grafana/grafana-plugin-sdk-go v0.187.0 // @grafana/plugins-platform-backend + github.com/grafana/grafana-plugin-sdk-go v0.196.0 // @grafana/plugins-platform-backend github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // @grafana/backend-platform github.com/hashicorp/go-hclog v1.5.0 // @grafana/plugins-platform-backend - github.com/hashicorp/go-plugin v1.4.9 // @grafana/plugins-platform-backend + github.com/hashicorp/go-plugin v1.6.0 // @grafana/plugins-platform-backend github.com/hashicorp/go-version v1.6.0 // @grafana/backend-platform github.com/hashicorp/hcl/v2 v2.17.0 // @grafana/alerting-squad-backend github.com/influxdata/influxdb-client-go/v2 v2.12.3 // @grafana/observability-metrics @@ -88,9 +90,9 @@ require ( github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/alertmanager v0.25.0 // @grafana/alerting-squad-backend - github.com/prometheus/client_golang v1.16.0 // @grafana/alerting-squad-backend - github.com/prometheus/client_model v0.4.0 // @grafana/backend-platform - github.com/prometheus/common v0.44.0 // @grafana/alerting-squad-backend + github.com/prometheus/client_golang v1.17.0 // @grafana/alerting-squad-backend + github.com/prometheus/client_model v0.5.0 // @grafana/backend-platform + github.com/prometheus/common v0.45.0 // @grafana/alerting-squad-backend github.com/prometheus/prometheus v1.8.2-0.20221021121301-51a44e6657c3 // @grafana/alerting-squad-backend github.com/robfig/cron/v3 v3.0.1 // @grafana/backend-platform github.com/russellhaering/goxmldsig v1.4.0 // @grafana/backend-platform @@ -103,27 +105,27 @@ require ( github.com/yalue/merged_fs v1.2.2 // @grafana/grafana-as-code github.com/yudai/gojsondiff v1.0.0 // @grafana/backend-platform go.opentelemetry.io/collector/pdata v1.0.0-rc8 // @grafana/backend-platform - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0 // @grafana/grafana-operator-experience-squad + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 // @grafana/grafana-operator-experience-squad go.opentelemetry.io/otel/exporters/jaeger v1.10.0 // @grafana/backend-platform - go.opentelemetry.io/otel/sdk v1.19.0 // @grafana/backend-platform - go.opentelemetry.io/otel/trace v1.19.0 // @grafana/backend-platform - golang.org/x/crypto v0.14.0 // @grafana/backend-platform + go.opentelemetry.io/otel/sdk v1.21.0 // @grafana/backend-platform + go.opentelemetry.io/otel/trace v1.21.0 // @grafana/backend-platform + golang.org/x/crypto v0.16.0 // @grafana/backend-platform golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // @grafana/alerting-squad-backend - golang.org/x/net v0.17.0 // @grafana/grafana-bi-squad - golang.org/x/oauth2 v0.13.0 // @grafana/grafana-authnz-team + golang.org/x/net v0.19.0 // @grafana/oss-big-tent @grafana/partner-datasources + golang.org/x/oauth2 v0.15.0 // @grafana/grafana-authnz-team golang.org/x/sync v0.4.0 // @grafana/alerting-squad-backend golang.org/x/time v0.3.0 // @grafana/backend-platform - golang.org/x/tools v0.12.0 // @grafana/grafana-as-code + golang.org/x/tools v0.13.0 // @grafana/grafana-as-code gonum.org/v1/gonum v0.12.0 // @grafana/observability-metrics google.golang.org/api v0.148.0 // @grafana/backend-platform - google.golang.org/grpc v1.58.3 // @grafana/plugins-platform-backend + google.golang.org/grpc v1.59.0 // @grafana/plugins-platform-backend google.golang.org/protobuf v1.31.0 // @grafana/plugins-platform-backend gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/ini.v1 v1.67.0 // @grafana/alerting-squad-backend gopkg.in/mail.v2 v2.3.1 // @grafana/backend-platform gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // @grafana/alerting-squad-backend - xorm.io/builder v0.3.6 // indirect; @grafana/backend-platform + xorm.io/builder v0.3.6 // @grafana/backend-platform xorm.io/core v0.7.3 // @grafana/backend-platform xorm.io/xorm v0.8.2 // @grafana/alerting-squad-backend ) @@ -164,7 +166,7 @@ require ( github.com/go-openapi/validate v0.22.1 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // @grafana/backend-platform github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect - github.com/golang/glog v1.1.0 // indirect + github.com/golang/glog v1.1.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // @grafana/backend-platform github.com/google/btree v1.1.2 // indirect @@ -175,7 +177,7 @@ require ( github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect; @grafana/alerting-squad + github.com/hashicorp/go-multierror v1.1.1 // @grafana/alerting-squad github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect @@ -199,9 +201,9 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/exporter-toolkit v0.10.0 // indirect - github.com/prometheus/procfs v0.11.0 // indirect + github.com/prometheus/procfs v0.11.1 // indirect github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b // indirect - github.com/rs/cors v1.9.0 // indirect + github.com/rs/cors v1.10.1 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/segmentio/encoding v0.3.6 // indirect github.com/sergi/go-diff v1.3.1 // indirect @@ -215,12 +217,12 @@ require ( go.mongodb.org/mongo-driver v1.11.3 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.11.0 // @grafana/alerting-squad-backend - go.uber.org/goleak v1.2.1 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // @grafana/backend-platform + go.uber.org/goleak v1.3.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // @grafana/backend-platform golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect; @grafana/backend-platform + google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a // indirect; @grafana/backend-platform ) require ( @@ -237,6 +239,7 @@ require ( github.com/drone/drone-cli v1.6.1 // @grafana/grafana-delivery github.com/getkin/kin-openapi v0.120.0 // @grafana/grafana-operator-experience-squad github.com/golang-migrate/migrate/v4 v4.7.0 // @grafana/backend-platform + github.com/google/go-github v17.0.0+incompatible // @grafana/grafana-delivery github.com/google/go-github/v45 v45.2.0 // @grafana/grafana-delivery github.com/grafana/codejen v0.0.3 // @grafana/dataviz-squad github.com/grafana/dskit v0.0.0-20230706162620-5081d8ed53e6 // @grafana/backend-platform @@ -244,10 +247,10 @@ require ( github.com/jmoiron/sqlx v1.3.5 // @grafana/backend-platform github.com/matryer/is v1.4.0 // @grafana/grafana-as-code github.com/urfave/cli v1.22.14 // @grafana/backend-platform - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 // @grafana/plugins-platform-backend - go.opentelemetry.io/contrib/propagators/jaeger v1.20.0 // @grafana/backend-platform - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // @grafana/backend-platform - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 // @grafana/backend-platform + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 // @grafana/plugins-platform-backend + go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 // @grafana/backend-platform + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // @grafana/backend-platform + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // @grafana/backend-platform gocloud.dev v0.25.0 // @grafana/grafana-app-platform-squad ) @@ -257,7 +260,7 @@ require ( github.com/Masterminds/semver/v3 v3.1.1 // @grafana/grafana-delivery github.com/alicebob/miniredis/v2 v2.30.1 // @grafana/alerting-squad-backend github.com/dave/dst v0.27.2 // @grafana/grafana-as-code - github.com/go-jose/go-jose/v3 v3.0.0 // @grafana/backend-platform + github.com/go-jose/go-jose/v3 v3.0.1 // @grafana/backend-platform github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics github.com/grafana/dataplane/sdata v0.0.6 // @grafana/observability-metrics github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482 // @grafana/grafana-as-code @@ -268,25 +271,26 @@ require ( github.com/redis/go-redis/v9 v9.0.2 // @grafana/alerting-squad-backend github.com/weaveworks/common v0.0.0-20230511094633-334485600903 // @grafana/alerting-squad-backend github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // @grafana/grafana-as-code - go.opentelemetry.io/contrib/samplers/jaegerremote v0.9.0 // @grafana/backend-platform + go.opentelemetry.io/contrib/samplers/jaegerremote v0.15.1 // @grafana/backend-platform golang.org/x/mod v0.12.0 // @grafana/backend-platform gopkg.in/square/go-jose.v2 v2.6.0 // @grafana/grafana-authnz-team k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // @grafana/partner-datasources ) require ( - go.opentelemetry.io/otel v1.19.0 // @grafana/backend-platform - k8s.io/apimachinery v0.27.1 // @grafana/grafana-app-platform-squad - k8s.io/apiserver v0.27.1 // @grafana/grafana-app-platform-squad - k8s.io/client-go v0.27.1 // @grafana/grafana-app-platform-squad - k8s.io/component-base v0.27.1 // @grafana/grafana-app-platform-squad - k8s.io/klog/v2 v2.90.1 // @grafana/grafana-app-platform-squad - k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // @grafana/grafana-app-platform-squad + github.com/spf13/cobra v1.7.0 // @grafana/grafana-app-platform-squad + go.opentelemetry.io/otel v1.21.0 // @grafana/backend-platform + k8s.io/apimachinery v0.28.4 // @grafana/grafana-app-platform-squad + k8s.io/apiserver v0.28.4 // @grafana/grafana-app-platform-squad + k8s.io/client-go v0.28.4 // @grafana/grafana-app-platform-squad + k8s.io/component-base v0.28.4 // @grafana/grafana-app-platform-squad + k8s.io/klog/v2 v2.100.1 // @grafana/grafana-app-platform-squad + k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // @grafana/grafana-app-platform-squad ) require github.com/grafana/gofpdf v0.0.0-20231002120153-857cc45be447 // @grafana/sharing-squad -require github.com/grafana/pyroscope/api v0.2.0 // @grafana/observability-traces-and-profiling +require github.com/grafana/pyroscope/api v0.3.0 // @grafana/observability-traces-and-profiling require github.com/apache/arrow/go/v13 v13.0.0 // @grafana/observability-metrics @@ -316,7 +320,7 @@ require ( github.com/cristalhq/jwt/v4 v4.0.2 // indirect github.com/dave/jennifer v1.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect @@ -328,7 +332,7 @@ require ( github.com/ecordell/optgen v0.0.6 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/getsentry/sentry-go v0.12.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.4 // indirect @@ -360,7 +364,7 @@ require ( github.com/mattn/go-ieproxy v0.0.3 // indirect github.com/mattn/goveralls v0.0.6 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 //@grafana/grafana-authnz-team github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect @@ -383,7 +387,6 @@ require ( github.com/shopspring/decimal v1.2.0 // indirect github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect @@ -399,19 +402,19 @@ require ( go.etcd.io/etcd/api/v3 v3.5.9 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.9 // indirect go.etcd.io/etcd/client/v3 v3.5.9 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect go.starlark.net v0.0.0-20221020143700-22309ac47eac // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/term v0.13.0 // indirect + golang.org/x/term v0.15.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - k8s.io/api v0.27.1 // indirect - k8s.io/kms v0.27.1 // indirect + k8s.io/api v0.28.4 // indirect + k8s.io/kms v0.28.4 // indirect lukechampine.com/uint128 v1.2.0 // indirect modernc.org/cc/v3 v3.40.0 // indirect modernc.org/ccgo/v3 v3.16.13 // indirect @@ -425,7 +428,7 @@ require ( sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.1.2 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // @grafana-app-platform-squad + sigs.k8s.io/yaml v1.3.0 // indirect; @grafana-app-platform-squad ) require ( @@ -439,7 +442,6 @@ require ( github.com/Microsoft/go-winio v0.6.0 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // @grafana/plugins-platform-backend github.com/RoaringBitmap/roaring v0.9.4 // indirect - github.com/acomagu/bufpipe v1.0.3 // indirect github.com/axiomhq/hyperloglog v0.0.0-20191112132149-a4c4c47bc57f // indirect github.com/bits-and-blooms/bitset v1.2.0 // indirect github.com/blevesearch/go-porterstemmer v1.0.3 // indirect @@ -454,35 +456,29 @@ require ( github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect github.com/docker/docker v23.0.4+incompatible // @grafana/grafana-delivery github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 // indirect - github.com/emirpasic/gods v1.12.0 // indirect github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect - github.com/go-git/gcfg v1.5.0 // indirect - github.com/go-git/go-billy/v5 v5.3.1 // indirect - github.com/go-logr/logr v1.2.4 // @grafana/grafana-app-platform-squad + github.com/go-logr/logr v1.3.0 // @grafana/grafana-app-platform-squad github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/go-github v17.0.0+incompatible // @grafana/grafana-app-platform-squad github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 // indirect github.com/hmarr/codeowners v1.1.2 // @grafana/grafana-as-code github.com/imdario/mergo v0.3.13 // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect github.com/klauspost/compress v1.16.5 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/labstack/echo/v4 v4.10.2 // indirect github.com/labstack/gommon v0.4.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/wk8/go-ordered-map v1.0.0 // @grafana/backend-platform - github.com/xanzy/ssh-agent v0.3.0 // indirect github.com/xlab/treeprint v1.2.0 // @grafana/observability-traces-and-profiling go.opentelemetry.io/proto/otlp v1.0.0 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect ) -require github.com/google/gnostic v0.6.9 // indirect +require ( + github.com/google/gnostic-models v0.6.8 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect +) // Use fork of crewjam/saml with fixes for some issues until changes get merged into upstream replace github.com/crewjam/saml => github.com/grafana/saml v0.4.15-0.20231025143828-a6c0e9b86a4c @@ -496,10 +492,11 @@ replace github.com/hashicorp/go-hclog => github.com/hashicorp/go-hclog v0.16.1 // happen, for example, during a read when the sqlite db is under heavy write load. // This patch cherry picks compatible fixes from upstream xorm PR#1998 and can be reverted on upgrade to xorm v1.2.0+. // This has also been patched to support the azuresql driver that is a thin wrapper for the mssql driver with azure authentication support. -replace xorm.io/xorm => github.com/grafana/xorm v0.8.3-0.20230627081928-d04aa38aa209 +//replace xorm.io/xorm => github.com/grafana/xorm v0.8.3-0.20230627081928-d04aa38aa209 +replace xorm.io/xorm => ./pkg/util/xorm // Use our fork of the upstream alertmanagers. // This is required in order to get notification delivery errors from the receivers API. -replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20230918083811-3513be6760b7 +replace github.com/prometheus/alertmanager => github.com/grafana/prometheus-alertmanager v0.25.1-0.20231027171310-70c52bf65758 exclude github.com/mattn/go-sqlite3 v2.0.3+incompatible diff --git a/go.sum b/go.sum index 37493c11f44a9..213daaa7ba3dd 100644 --- a/go.sum +++ b/go.sum @@ -644,7 +644,6 @@ github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmy github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -652,7 +651,6 @@ github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cq github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -670,8 +668,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f h1:HR5nRmUQgXrwqZOwZ2DAc/aCi3Bu3xENpspW935vxu0= github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3HiCrHjHBdcm6E83vGaXh1KomZMA2P6aeo3hKx/wg0= -github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= -github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= @@ -696,8 +692,6 @@ github.com/alicebob/miniredis/v2 v2.30.1 h1:HM1rlQjq1bm9yQcsawJqSZBJ9AYgxvjkMsNt github.com/alicebob/miniredis/v2 v2.30.1/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= @@ -722,7 +716,6 @@ github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -837,9 +830,13 @@ github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/bsm/ginkgo/v2 v2.5.0 h1:aOAnND1T40wEdAtkGSkvSICWeQ8L3UASX7YVCqQx+eQ= +github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.20.0 h1:JhAwLmtRzXFTx2AkALSLa8ijZafntmhSoU63Ok18Uq8= +github.com/bsm/gomega v1.20.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk= github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg= github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/buildkite/yaml v2.1.0+incompatible h1:xirI+ql5GzfikVNDmt+yeiXpf/v1Gt03qXTtT5WXdr8= github.com/buildkite/yaml v2.1.0+incompatible/go.mod h1:UoU8vbcwu1+vjZq01+KrpSeLBgQQIjL/H7Y6KwikUrI= @@ -902,6 +899,7 @@ github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230112175826-46e39c7b9b43/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= @@ -981,8 +979,6 @@ github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s= github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas= github.com/denisenkom/go-mssqldb v0.0.0-20190515213511-eb9f6a1743f3/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM= -github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= @@ -990,8 +986,8 @@ github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mz github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE= github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= @@ -1059,14 +1055,13 @@ github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027 h1:1L0aalTpPz7YlMx github.com/elazarl/goproxy v0.0.0-20230731152917-f99041a5c027/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/elazarl/goproxy/ext v0.0.0-20220115173737-adb46da277ac h1:9yrT5tmn9Zc0ytWPASlaPwQfQMQYnRf0RSDe1XvHw0Q= +github.com/elazarl/goproxy/ext v0.0.0-20220115173737-adb46da277ac/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/proto v1.10.0 h1:pDGyFRVV5RvV+nkBK9iy3q67FBy9Xa7vwrOTE+g5aGw= github.com/emicklei/proto v1.10.0/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -1080,10 +1075,12 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go. github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -1098,10 +1095,10 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -1133,8 +1130,6 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-asn1-ber/asn1-ber v1.5.4 h1:vXT6d/FNDiELJnLb6hGNa309LMsrCoYFvpwHDF0+Y1A= @@ -1148,21 +1143,12 @@ github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3 github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY= github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= -github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= -github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= -github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= -github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= -github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -1186,11 +1172,12 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= @@ -1312,7 +1299,9 @@ github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y= github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM= github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= @@ -1618,8 +1607,8 @@ github.com/golang/gddo v0.0.0-20180828051604-96d2a289f41e/go.mod h1:xEhNfoBDX1hz github.com/golang/gddo v0.0.0-20190904175337-72a348e765d2/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -1664,6 +1653,7 @@ github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219 h1:utua3L2IbQJmauC5IXdEA547bcoU5dozgQAfc8Onsg4= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -1677,8 +1667,9 @@ github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6 github.com/google/flatbuffers v23.1.21+incompatible h1:bUqzx/MXCDxuS0hRJL2EfjyZL3uQrPbMocUa8zGqsTA= github.com/google/flatbuffers v23.1.21+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= -github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -1747,8 +1738,8 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= @@ -1799,16 +1790,14 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gotestyourself/gotestyourself v1.3.0/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= -github.com/grafana/alerting v0.0.0-20231017091417-a53b5db2235d h1:fxHDUyKFc1mfyJAtW+Qxi66dMahYu+o5/lH+f8SoMHg= -github.com/grafana/alerting v0.0.0-20231017091417-a53b5db2235d/go.mod h1:6BES5CyEqz7fDAG3MYvJLe0hqGwvIoGDN8A1aNrLGus= -github.com/grafana/alerting v0.0.0-20231026192550-079966731bbe h1:6jY5mWR//GbYOjvqpnoncgkdxbeYImkTsy9rPvVFOlk= -github.com/grafana/alerting v0.0.0-20231026192550-079966731bbe/go.mod h1:6BES5CyEqz7fDAG3MYvJLe0hqGwvIoGDN8A1aNrLGus= +github.com/grafana/alerting v0.0.0-20231101090315-bf12694896a8 h1:uoaAgS743libLwhuQUQEDO2YpFaQI5viyY4NrcyibUg= +github.com/grafana/alerting v0.0.0-20231101090315-bf12694896a8/go.mod h1:lR9bhQrESIeOqKtC4Y+fK4mqtLmJFDffFt9q4cWRa8k= github.com/grafana/codejen v0.0.3 h1:tAWxoTUuhgmEqxJPOLtJoxlPBbMULFwKFOcRsPRPXDw= github.com/grafana/codejen v0.0.3/go.mod h1:zmwwM/DRyQB7pfuBjTWII3CWtxcXh8LTwAYGfDfpR6s= github.com/grafana/cue v0.0.0-20230926092038-971951014e3f h1:TmYAMnqg3d5KYEAaT6PtTguL2GjLfvr6wnAX8Azw6tQ= github.com/grafana/cue v0.0.0-20230926092038-971951014e3f/go.mod h1:okjJBHFQFer+a41sAe2SaGm1glWS8oEb6CmJvn5Zdws= -github.com/grafana/cuetsy v0.1.10 h1:+W9/7roI8LorL+D1RJhKGdhsTZ81adrK9dHS0r7qsXs= -github.com/grafana/cuetsy v0.1.10/go.mod h1:Ix97+CPD8ws9oSSxR3/Lf4ahU1I4Np83kjJmDVnLZvc= +github.com/grafana/cuetsy v0.1.11 h1:I3IwBhF+UaQxRM79HnImtrAn8REGdb5M3+C4QrYHoWk= +github.com/grafana/cuetsy v0.1.11/go.mod h1:Ix97+CPD8ws9oSSxR3/Lf4ahU1I4Np83kjJmDVnLZvc= github.com/grafana/dataplane/examples v0.0.1 h1:K9M5glueWyLoL4//H+EtTQq16lXuHLmOhb6DjSCahzA= github.com/grafana/dataplane/examples v0.0.1/go.mod h1:h5YwY8s407/17XF5/dS8XrUtsTVV2RnuW8+m1Mp46mg= github.com/grafana/dataplane/sdata v0.0.6 h1:Ejlj8d1Hvy/uDLeI4sOvL34Y8WLlVDd9iN270F+8aTw= @@ -1825,14 +1814,14 @@ github.com/grafana/grafana-google-sdk-go v0.1.0 h1:LKGY8z2DSxKjYfr2flZsWgTRTZ6HG github.com/grafana/grafana-google-sdk-go v0.1.0/go.mod h1:Vo2TKWfDVmNTELBUM+3lkrZvFtBws0qSZdXhQxRdJrE= github.com/grafana/grafana-plugin-sdk-go v0.94.0/go.mod h1:3VXz4nCv6wH5SfgB3mlW39s+c+LetqSCjFj7xxPC5+M= github.com/grafana/grafana-plugin-sdk-go v0.114.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk= -github.com/grafana/grafana-plugin-sdk-go v0.187.0 h1:lOwoFbbTs27KqR3F32GvOX9Et3Ek8p8qsFw+SUJtAAM= -github.com/grafana/grafana-plugin-sdk-go v0.187.0/go.mod h1:PHK8eQOz3ES28RmImdTHNOTxBZaH6mb/ytJGxk7VVJc= +github.com/grafana/grafana-plugin-sdk-go v0.196.0 h1:yDopQZ76Ug1UKZd2V4/MSi1k6SbeVz6o6ApwY6UP19U= +github.com/grafana/grafana-plugin-sdk-go v0.196.0/go.mod h1:YB/80C5jTFj2jGAZVuuwsU6EVr63jjKcMgEB1nlSgiY= github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482 h1:1YNoeIhii4UIIQpCPU+EXidnqf449d0C3ZntAEt4KSo= github.com/grafana/kindsys v0.0.0-20230508162304-452481b63482/go.mod h1:GNcfpy5+SY6RVbNGQW264gC0r336Dm+0zgQ5vt6+M8Y= -github.com/grafana/prometheus-alertmanager v0.25.1-0.20230918083811-3513be6760b7 h1:7gsywzIb39SYZEp9qOnNaxD4d9OOkAfJGvnRUQUtlTM= -github.com/grafana/prometheus-alertmanager v0.25.1-0.20230918083811-3513be6760b7/go.mod h1:0SOsbwZb277OdNdUR+376IxcAYV3Pp+igiAOJdr/98M= -github.com/grafana/pyroscope/api v0.2.0 h1:TzOxL0s6SiaLEy944ZAKgHcx/JDRJXu4O8ObwkqR6p4= -github.com/grafana/pyroscope/api v0.2.0/go.mod h1:nhH+xai9cYFgs6lMy/+L0pKj0d5yCMwji/QAiQFCP+U= +github.com/grafana/prometheus-alertmanager v0.25.1-0.20231027171310-70c52bf65758 h1:ATUhvJSJwzdzhnmzUI92fxVFqyqmcnzJ47wtHTK3LW4= +github.com/grafana/prometheus-alertmanager v0.25.1-0.20231027171310-70c52bf65758/go.mod h1:MmLemcsGjpbOwEeT3k7K+gnvIImXgkatCfVX6sOtx80= +github.com/grafana/pyroscope/api v0.3.0 h1:WcVKNZ8JlriJnD28wTkZray0wGo8dGkizSJXnbG7Gd8= +github.com/grafana/pyroscope/api v0.3.0/go.mod h1:JggA80ToAAUACYGfwL49XoFk5aN5ecHp4pNIZhlk9Uc= github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db h1:7aN5cccjIqCLTzedH7MZzRZt5/lsAHch6Z3L2ZGn5FA= github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= @@ -1844,8 +1833,6 @@ github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b h1:mDlkqgTEJuK7vjP github.com/grafana/tempo v1.5.1-0.20230524121406-1dc1bfe7085b/go.mod h1:UK7kTP5llPeRcGBOe5mm4QTNTd0k/mAqTVSOFdDH6AU= github.com/grafana/thema v0.0.0-20230712153715-375c1b45f3ed h1:TMtHc+B0SSNw2in6Ro1dAiBYSPRp4NzKgndFDfupt18= github.com/grafana/thema v0.0.0-20230712153715-375c1b45f3ed/go.mod h1:3zLJnssFRPCnebCBRlq53t5LgYv9P1mbj0XMozZMTww= -github.com/grafana/xorm v0.8.3-0.20230627081928-d04aa38aa209 h1:o0QTKP6oKduDIW8yA0fBSv5SjLZR6lTB116eBIeomg0= -github.com/grafana/xorm v0.8.3-0.20230627081928-d04aa38aa209/go.mod h1:ZkJLEYLoVyg7amJK/5r779bHyzs2AU8f8VMiP6BM7uY= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= @@ -1897,8 +1884,8 @@ github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.2.2/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0= -github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= -github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= +github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= +github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= @@ -1971,7 +1958,6 @@ github.com/igm/sockjs-go/v3 v3.0.2 h1:2m0k53w0DBiGozeQUIEPR6snZFmpFpYvVsGnfLPNXb github.com/igm/sockjs-go/v3 v3.0.2/go.mod h1:UqchsOjeagIBFHvd+RZpLaVRbCwGilEC08EDHsD1jYE= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= @@ -2048,8 +2034,6 @@ github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jandelgado/gcov2lcov v1.0.4-0.20210120124023-b83752c6dc08/go.mod h1:NnSxK6TMlg1oGDBfGelGbjgorT5/L3cchlbtgFYZSss= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= @@ -2059,8 +2043,9 @@ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJk github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -2120,8 +2105,6 @@ github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubc github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -2236,7 +2219,6 @@ github.com/markbates/safe v1.0.0/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kN github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/markbates/sigtx v1.0.0/go.mod h1:QF1Hv6Ic6Ca6W+T+DL0Y/ypborFKyvUY9HmuCD4VeTc= github.com/markbates/willie v1.0.9/go.mod h1:fsrFVWl91+gXpx/6dv715j7i11fYPfZ9ZGfH0DQzY7w= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattermost/xml-roundtrip-validator v0.1.0 h1:RXbVD2UAl7A7nOTR4u7E3ILa4IbtvKBHw64LDsmu9hU= @@ -2288,6 +2270,8 @@ github.com/mattn/goveralls v0.0.6/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKm github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= @@ -2342,6 +2326,7 @@ github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0Gq github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2/go.mod h1:TjQg8pa4iejrUrjiz0MCtMV38jdMNW4doKSiBrEvCQQ= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= +github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -2399,6 +2384,7 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oleiade/reflections v1.0.0/go.mod h1:RbATFBbKYkVdqmSFtx13Bb/tVhR0lgOBXunWTZKeL4w= github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= +github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= @@ -2412,12 +2398,14 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0= github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -2434,6 +2422,7 @@ github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8lu github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -2558,8 +2547,8 @@ github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrb github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= +github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -2567,8 +2556,10 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -2586,8 +2577,9 @@ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+ github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.41.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/common/assets v0.2.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= @@ -2608,9 +2600,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= -github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= +github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/prometheus/prometheus v0.43.0 h1:18iCSfrbAHbXvYFvR38U1Pt4uZmU9SmDcCpCrBKUiGg= github.com/prometheus/prometheus v0.43.0/go.mod h1:2BA14LgBeqlPuzObSEbh+Y+JwLH2GcqDlJKbF2sA6FM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= @@ -2649,8 +2640,8 @@ github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncj github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= -github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -2664,8 +2655,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w= github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk= -github.com/ryantxu/kube-openapi v0.0.0-20230824154605-fe0f3703fd8d h1:/aSzsDXklM83yExguLXwl/nMrW8/7Lgefg2q632YynY= -github.com/ryantxu/kube-openapi v0.0.0-20230824154605-fe0f3703fd8d/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= +github.com/ryantxu/kube-openapi v0.0.0-20231113051506-80b8e1dfdde6 h1:RL7MugW3Q+FV1cwyb8d+UgAayA5VW+tUHDRWKFf3Y8c= +github.com/ryantxu/kube-openapi v0.0.0-20231113051506-80b8e1dfdde6/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= @@ -2824,12 +2815,14 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y= github.com/tidwall/sjson v1.1.5/go.mod h1:VuJzsZnTowhSxWdOgsAnb886i4AjEyTkk7tNtsL7EYE= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= +github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f h1:A+MmlgpvrHLeUP8dkBVn4Pnf5Bp5Yk2OALm7SEJLLE8= github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f/go.mod h1:OBcG9bn7sHtXgarhUEb3OfCnNsgtGnkVf41ilSZ3K3E= @@ -2849,6 +2842,7 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI= github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8/go.mod h1:fVle4kNr08ydeohzYafr20oZzbAkhQT39gKK/pFQ5M4= github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= @@ -2883,8 +2877,6 @@ github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMU github.com/wk8/go-ordered-map v1.0.0 h1:BV7z+2PaK8LTSd/mWgY12HyMAo5CEgkHqbkVq2thqr8= github.com/wk8/go-ordered-map v1.0.0/go.mod h1:9ZIbRunKbuvfPKyBP1SIKLcXNlv74YCOZ3t3VTS6gRk= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= -github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= @@ -2935,7 +2927,6 @@ github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= go.elastic.co/apm v1.8.0/go.mod h1:tCw6CkOJgkWnzEthFN9HUP1uL3Gjc/Ur6m7gRPLaoH0= @@ -2944,7 +2935,8 @@ go.elastic.co/apm/module/apmot v1.8.0/go.mod h1:Q5Xzabte8G/fkvDjr1jlDuOSUt9hkVWN go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738 h1:VcrIfasaLFkyjk6KNlXQSzO+B0fZcnECiDrKJsfxka0= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -2957,14 +2949,18 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.9 h1:oidDC4+YEuSIQbsR94rY9gur91UPL6DnxDCIYd2I go.etcd.io/etcd/client/pkg/v3 v3.5.9/go.mod h1:y+CzeSmkMpWN2Jyu1npecjB9BBnABxGM4pN8cGuJeL4= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= -go.etcd.io/etcd/client/v2 v2.305.7 h1:AELPkjNR3/igjbO7CjyF1fPuVPjrblliiKj+Y6xSGOU= +go.etcd.io/etcd/client/v2 v2.305.9 h1:YZ2OLi0OvR0H75AcgSUajjd5uqKDKocQUqROTG11jIo= +go.etcd.io/etcd/client/v2 v2.305.9/go.mod h1:0NBdNx9wbxtEQLwAQtrDHwx58m02vXpDcgSYI2seohQ= go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.etcd.io/etcd/client/v3 v3.5.9 h1:r5xghnU7CwbUxD/fbUtRyJGaYNfDun8sp/gTr1hew6E= go.etcd.io/etcd/client/v3 v3.5.9/go.mod h1:i/Eo5LrZ5IKqpbtpPDuaUnDOUv471oDg8cjQaUr2MbA= -go.etcd.io/etcd/pkg/v3 v3.5.7 h1:obOzeVwerFwZ9trMWapU/VjDcYUJb5OfgC1zqEGWO/0= -go.etcd.io/etcd/raft/v3 v3.5.7 h1:aN79qxLmV3SvIq84aNTliYGmjwsW6NqJSnqmI1HLJKc= -go.etcd.io/etcd/server/v3 v3.5.7 h1:BTBD8IJUV7YFgsczZMHhMTS67XuA4KpRquL0MFOJGRk= +go.etcd.io/etcd/pkg/v3 v3.5.9 h1:6R2jg/aWd/zB9+9JxmijDKStGJAPFsX3e6BeJkMi6eQ= +go.etcd.io/etcd/pkg/v3 v3.5.9/go.mod h1:BZl0SAShQFk0IpLWR78T/+pyt8AruMHhTNNX73hkNVY= +go.etcd.io/etcd/raft/v3 v3.5.9 h1:ZZ1GIHoUlHsn0QVqiRysAm3/81Xx7+i2d7nSdWxlOiI= +go.etcd.io/etcd/raft/v3 v3.5.9/go.mod h1:WnFkqzFdZua4LVlVXQEGhmooLeyS7mqzS4Pf4BCVqXg= +go.etcd.io/etcd/server/v3 v3.5.9 h1:vomEmmxeztLtS5OEH7d0hBAg4cjVIu9wXuNzUZx2ZA0= +go.etcd.io/etcd/server/v3 v3.5.9/go.mod h1:GgI1fQClQCFIzuVjlvdbMxNbnISt90gdfYyqiAIt65g= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -2992,37 +2988,37 @@ go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/collector/pdata v1.0.0-rc8 h1:vBikWdZFsRiT5dVsLQhnE99w3edM7eem3Q9dSqMlStE= go.opentelemetry.io/collector/pdata v1.0.0-rc8/go.mod h1:BVCBhWgclYCh7Oi6BkMiQfRa6MXv1uRTlKXuL5oBby8= go.opentelemetry.io/contrib v0.18.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0 h1:RsQi0qJ2imFfCvZabqzM9cNXBG8k6gXMv1A0cXRmH6A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0/go.mod h1:vsh3ySueQCiKPxFLvjWC4Z135gIa34TQ/NSqkDTZYUM= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1 h1:SpGay3w+nEwMpfVnbqOLH5gY52/foP8RE8UzTZ1pdSE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.1/go.mod h1:4UoMYEZOC0yN/sPGH76KPkkU7zgiEWYWL9vwmbnTJPE= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.18.0/go.mod h1:iK1G0FgHurSJ/aYLg5LpnPI0pqdanM73S3dhyDp0Lk4= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0 h1:2ea0IkZBsWH+HA2GkD+7+hRw2u97jzdFyRtXuO14a1s= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.45.0/go.mod h1:4m3RnBBb+7dB9d21y510oO1pdB1V4J6smNf14WXcBFQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= -go.opentelemetry.io/contrib/propagators/jaeger v1.20.0 h1:iVhNKkMIpzyZqxk8jkDU2n4DFTD+FbpGacvooxEvyyc= -go.opentelemetry.io/contrib/propagators/jaeger v1.20.0/go.mod h1:cpSABr0cm/AH/HhbJjn+AudBVUMgZWdfN3Gb+ZqxSZc= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.9.0 h1:zRi6a8uX+cJGTPLXRPjFEzN27a26k5R7LiLK87ntXgg= -go.opentelemetry.io/contrib/samplers/jaegerremote v0.9.0/go.mod h1:pzJOLTppaPbiPjPZEwGRf0VWx6G07hhOqznjKXIMkEk= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1 h1:gbhw/u49SS3gkPWiYweQNJGm/uJN5GkI/FrosxSHT7A= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.46.1/go.mod h1:GnOaBaFQ2we3b9AGWJpsBa7v1S5RlQzlC3O7dRMxZhM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWVy+oGdjx3dNJ72YehmtY5k= +go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.15.1 h1:Qb+5A+JbIjXwO7l4HkRUhgIn4Bzz0GNS2q+qdmSx+0c= +go.opentelemetry.io/contrib/samplers/jaegerremote v0.15.1/go.mod h1:G4vNCm7fRk0kjZ6pGNLo5SpLxAUvOfSrcaegnT8TPck= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= go.opentelemetry.io/otel/exporters/jaeger v1.10.0 h1:7W3aVVjEYayu/GOqOVF4mbTvnCuxF1wWu3eRxFGQXvw= go.opentelemetry.io/otel/exporters/jaeger v1.10.0/go.mod h1:n9IGyx0fgyXXZ/i0foLHNxtET9CzXHzZeKCucvRBFgA= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0/go.mod h1:HrbCVv40OOLTABmOn1ZWty6CHXkU8DK/Urc43tHug70= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0 h1:3d+S281UTjM+AbF31XSOYn1qXn3BgIdWl8HNEpx08Jk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.19.0/go.mod h1:0+KuTDyKL4gjKCF75pHOX4wuzYDUZYfAQdSu43o+Z2I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.14.0/go.mod h1:+N7zNjIJv4K+DeX67XXET0P+eIciESgaFDBqh+ZJFS4= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/oteltest v0.18.0/go.mod h1:NyierCU3/G8DLTva7KRzGii2fdxdR89zXKH1bNWY7Bo= go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -3044,8 +3040,9 @@ go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -3083,7 +3080,6 @@ golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190102171810-8d7daa0c54b3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -3134,9 +3130,10 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= +golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -3269,7 +3266,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= @@ -3313,9 +3309,10 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -3350,8 +3347,8 @@ golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -3370,7 +3367,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -3422,7 +3418,6 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -3476,13 +3471,11 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -3532,6 +3525,7 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -3540,9 +3534,12 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -3555,9 +3552,10 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -3574,9 +3572,9 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -3714,8 +3712,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -3973,12 +3971,12 @@ google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoR google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA+oRzP9k7cSwJlvDFiROO72uwD6i0= -google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk= +google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a h1:fwgW9j3vHirt4ObdHoYNwuO24BEZjSzbh+zPaNWoiY8= +google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU= google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -4028,8 +4026,8 @@ google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200910201057-6591123024b3/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/examples v0.0.0-20210304020650-930c79186c99/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= @@ -4100,7 +4098,6 @@ gopkg.in/telebot.v3 v3.1.3/go.mod h1:GJKwwWqp9nSkIVN51eRKU78aB5f5OnQuWdwiIZfPbko gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/validator.v2 v2.0.0-20180514200540-135c24b11c19/go.mod h1:o4V0GXN9/CAmCsvJ0oXYZvrZOe7syiDZSN1GWGZTGzc= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -4137,27 +4134,28 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= -k8s.io/api v0.27.1 h1:Z6zUGQ1Vd10tJ+gHcNNNgkV5emCyW+v2XTmn+CLjSd0= -k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E= +k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= +k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= -k8s.io/apimachinery v0.27.1 h1:EGuZiLI95UQQcClhanryclaQE6xjg1Bts6/L3cD7zyc= -k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM= -k8s.io/apiserver v0.27.1 h1:phY+BtXjjzd+ta3a4kYbomC81azQSLa1K8jo9RBw7Lg= -k8s.io/apiserver v0.27.1/go.mod h1:UGrOjLY2KsieA9Fw6lLiTObxTb8Z1xEba4uqSuMY0WU= +k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= +k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= +k8s.io/apiserver v0.28.4 h1:BJXlaQbAU/RXYX2lRz+E1oPe3G3TKlozMMCZWu5GMgg= +k8s.io/apiserver v0.28.4/go.mod h1:Idq71oXugKZoVGUUL2wgBCTHbUR+FYTWa4rq9j4n23w= k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= -k8s.io/client-go v0.27.1 h1:oXsfhW/qncM1wDmWBIuDzRHNS2tLhK3BZv512Nc59W8= -k8s.io/client-go v0.27.1/go.mod h1:f8LHMUkVb3b9N8bWturc+EDtVVVwZ7ueTVquFAJb2vA= -k8s.io/component-base v0.27.1 h1:kEB8p8lzi4gCs5f2SPU242vOumHJ6EOsOnDM3tTuDTM= -k8s.io/component-base v0.27.1/go.mod h1:UGEd8+gxE4YWoigz5/lb3af3Q24w98pDseXcXZjw+E0= +k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= +k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= +k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo= +k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kms v0.27.1 h1:JTSQbJb+mcobScQwF0bOmZhIwP17k8GvBsiLlA6SQqw= -k8s.io/kms v0.27.1/go.mod h1:VuTsw0uHlSycKLCkypCGxfFCjLfzf/5YMeATECd/zJA= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kms v0.28.4 h1:PMgY/3CQTWP9eIKmNQiTgjLIZ0ns6O+voagzD2/4mSg= +k8s.io/kms v0.28.4/go.mod h1:HL4/lR/bhjAJPbqycKtfhWiKh1Sp21cpHOL8P4oo87w= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/kube-openapi v0.0.0-20230303024457-afdc3dddf62d/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -4218,12 +4216,14 @@ modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34= +modernc.org/tcl v1.15.0/go.mod h1:xRoGotBZ6dU+Zo2tca+2EqVEeMmOUBzHnhIwq4YrVnE= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE= +modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= @@ -4243,6 +4243,5 @@ sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= xorm.io/builder v0.3.6 h1:ha28mQ2M+TFx96Hxo+iq6tQgnkC9IZkM6D8w9sKHHF8= xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU= -xorm.io/core v0.7.2/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= xorm.io/core v0.7.3 h1:W8ws1PlrnkS1CZU1YWaYLMQcQilwAmQXU0BJDJon+H0= xorm.io/core v0.7.3/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM= diff --git a/hack/README.md b/hack/README.md new file mode 100644 index 0000000000000..226636e032e12 --- /dev/null +++ b/hack/README.md @@ -0,0 +1,25 @@ +# Kubernetes HACK Alert + +This is a hack folder for kubernetes codegen scripts. Oddly, a /hack/ folder seems to be standard kubernetes development practice ¯\_(ツ)\_/¯ + +The workflow is a WIP, however we are trying to leverage as many off-the-shelf patterns as possible. + +For these scripts to work, your local GOROOT/src/grafana/grafana must point to this git checkout. For my setup this is: + +``` +❯ pwd +/Users/ryan/go/src/github.com/grafana +❯ ls -l +total 0 +lrwxr-xr-x 1 ryan staff 37 Oct 5 09:34 grafana -> /Users/ryan/workspace/grafana/grafana +``` + +The current workflow (sorry!) is to: + +1. update the script to point to the group+version you want +2. run the `update-codegen.sh` script. This will produce a bunch of new files +3. move `pkg/generated/openapi/zz_generated.openapi.go` to `pkg/apis/{group/version}/zz_generated.openapi.go`. +4. edit the package name so it is {version} and remove the boilerplate k8s kinds +5. `rm -rf pkg/generated` -- we are not yet using most of the generated client stuff + +Once we are more comfortable with the outputs and process, we will build these steps into a more standard codegen pattern, but until then... happy hacking! diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 0000000000000..dd609cc5c9f07 --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,2 @@ +// SPDX-License-Identifier: AGPL-3.0-only + diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh new file mode 100755 index 0000000000000..115b201183a28 --- /dev/null +++ b/hack/update-codegen.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +# Copyright 2017 The Kubernetes Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo $GOPATH/pkg/mod/k8s.io/code-generator@v0.27.1)} + +OUTDIR="${HOME}/go/src" + +echo $OUTDIR + +CLIENTSET_NAME_VERSIONED=clientset \ +CLIENTSET_PKG_NAME=clientset \ +"${CODEGEN_PKG}/generate-groups.sh" "all" \ + github.com/grafana/grafana/pkg/generated \ + github.com/grafana/grafana/pkg/apis \ + "snapshots:v0alpha1" \ + --output-base "${OUTDIR}" \ + --go-header-file "${SCRIPT_ROOT}/hack/boilerplate.go.txt" + +CLIENTSET_NAME_VERSIONED=clientset \ +CLIENTSET_PKG_NAME=clientset \ +"${CODEGEN_PKG}/generate-internal-groups.sh" "deepcopy,defaulter,conversion,openapi" \ + github.com/grafana/grafana/pkg/generated \ + github.com/grafana/grafana/pkg/apis \ + github.com/grafana/grafana/pkg/apis \ + "snapshots:v0alpha1" \ + --output-base "${OUTDIR}" \ + --go-header-file "${SCRIPT_ROOT}/hack/boilerplate.go.txt" diff --git a/kinds/dashboard/dashboard_kind.cue b/kinds/dashboard/dashboard_kind.cue index 1fb8337316605..85e3a45040bdb 100644 --- a/kinds/dashboard/dashboard_kind.cue +++ b/kinds/dashboard/dashboard_kind.cue @@ -56,16 +56,7 @@ lineage: schemas: [{ } // Configuration of the time picker shown at the top of a dashboard. - timepicker?: { - // Whether timepicker is visible or not. - hidden: bool | *false - // Interval options available in the refresh picker dropdown. - refresh_intervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] - // Whether timepicker is collapsed or not. Has no effect on provisioned dashboard. - collapse: bool | *false - // Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. - time_options: [...string] | *["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] - } + timepicker?: #TimePickerConfig // The month that the fiscal year starts on. 0 = January, 11 = December fiscalYearStartMonth?: uint8 & <12 | *0 @@ -89,7 +80,7 @@ lineage: schemas: [{ version?: uint32 // List of dashboard panels - panels?: [...(#Panel | #RowPanel | #GraphPanel | #HeatmapPanel)] + panels?: [...(#Panel | #RowPanel)] // Configured template variables templating?: { @@ -243,7 +234,9 @@ lineage: schemas: [{ // `4`: Numerical DESC // `5`: Alphabetical Case Insensitive ASC // `6`: Alphabetical Case Insensitive DESC - #VariableSort: 0 | 1 | 2 | 3 | 4 | 5 | 6 @cuetsy(kind="enum",memberNames="disabled|alphabeticalAsc|alphabeticalDesc|numericalAsc|numericalDesc|alphabeticalCaseInsensitiveAsc|alphabeticalCaseInsensitiveDesc") + // `7`: Natural ASC + // `8`: Natural DESC + #VariableSort: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 @cuetsy(kind="enum",memberNames="disabled|alphabeticalAsc|alphabeticalDesc|numericalAsc|numericalDesc|alphabeticalCaseInsensitiveAsc|alphabeticalCaseInsensitiveDesc|naturalAsc|naturalDesc") // Ref to a DataSource instance #DataSourceRef: { @@ -265,7 +258,7 @@ lineage: schemas: [{ // Tooltip to display when the user hovers their mouse over it tooltip: string // Link URL. Only required/valid if the type is link - url: string + url?: string // List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards tags: [...string] // If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards @@ -450,6 +443,17 @@ lineage: schemas: [{ options: _ } @cuetsy(kind="interface") @grafana(TSVeneer="type") + // Time picker configuration + // It defines the default config for the time picker and the refresh picker for the specific dashboard. + #TimePickerConfig: { + // Whether timepicker is visible or not. + hidden: bool | *false + // Interval options available in the refresh picker dropdown. + refresh_intervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] + // Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. + time_options: [...string] | *["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + } @cuetsy(kind="interface") @grafana(TSVeneer="type") + // 0 for no shared crosshair or tooltip (default). // 1 for shared crosshair. // 2 for shared crosshair AND shared tooltip. @@ -711,31 +715,11 @@ lineage: schemas: [{ id: uint32 // List of panels in the row - panels: [...(#Panel | #GraphPanel | #HeatmapPanel)] + panels: [...#Panel] // Name of template variable to repeat for. repeat?: string } @cuetsy(kind="interface") @grafana(TSVeneer="type") - - // Support for legacy graph panel. - // @deprecated this a deprecated panel type - #GraphPanel: { - type: "graph" - // @deprecated this is part of deprecated graph panel - legend?: { - show: bool | *true - sort?: string - sortDesc?: bool - } - ... - } @cuetsy(kind="interface") - - // Support for legacy heatmap panel. - // @deprecated this a deprecated panel type - #HeatmapPanel: { - type: "heatmap" - ... - } @cuetsy(kind="interface") } }, ] diff --git a/kinds/preferences/preferences_kind.cue b/kinds/preferences/preferences_kind.cue index b6f189178c21c..0eddc16cbef49 100644 --- a/kinds/preferences/preferences_kind.cue +++ b/kinds/preferences/preferences_kind.cue @@ -8,6 +8,8 @@ description: "The user or team frontend preferences" lineage: schemas: [{ version: [0, 0] schema: { + // Spec defines user, team or org Grafana preferences + // swagger:model Preferences spec: { // UID for the home dashboard homeDashboardUID?: string diff --git a/latest.json b/latest.json index def63753f6392..0091c1bce5813 100644 --- a/latest.json +++ b/latest.json @@ -1,4 +1,4 @@ { - "stable": "10.2.0", - "testing": "10.2.0" + "stable": "10.2.2", + "testing": "10.2.2" } diff --git a/package.json b/package.json index 14ed107f5e2f9..9f0808582a9ee 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "plugin:build:dev": "lerna run dev --ignore=\"@grafana/*\" --ignore=\"@grafana-plugins/input-datasource\"" }, "grafana": { - "whatsNewUrl": "https://grafana.com/docs/grafana/next/whatsnew/whats-new-in-v10-1/", + "whatsNewUrl": "https://grafana.com/docs/grafana/next/whatsnew/whats-new-in-v10-3/", "releaseNotesUrl": "https://grafana.com/docs/grafana/next/release-notes/" }, "devDependencies": { @@ -96,7 +96,7 @@ "@swc/core": "1.3.38", "@swc/helpers": "0.4.14", "@testing-library/dom": "9.3.3", - "@testing-library/jest-dom": "5.16.5", + "@testing-library/jest-dom": "6.1.4", "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.5.1", "@types/angular": "1.8.5", @@ -124,7 +124,7 @@ "@types/lucene": "^2", "@types/marked": "5.0.1", "@types/mousetrap": "1.6.11", - "@types/node": "18.18.4", + "@types/node": "20.8.10", "@types/node-forge": "^1", "@types/ol-ext": "npm:@siedlerchr/types-ol-ext@3.2.0", "@types/papaparse": "5.3.7", @@ -151,6 +151,7 @@ "@types/testing-library__jest-dom": "5.14.8", "@types/tinycolor2": "1.4.3", "@types/uuid": "9.0.2", + "@types/webpack-assets-manifest": "^5", "@types/yargs": "17.0.24", "@typescript-eslint/eslint-plugin": "5.42.0", "@typescript-eslint/parser": "5.42.0", @@ -159,13 +160,13 @@ "babel-loader": "9.1.3", "babel-plugin-angularjs-annotate": "0.10.0", "babel-plugin-macros": "3.1.0", - "blink-diff": "1.0.13", "blob-polyfill": "7.0.20220408", "browserslist": "^4.21.4", "chance": "^1.0.10", "chrome-remote-interface": "0.33.0", "codeowners": "^5.1.1", "copy-webpack-plugin": "11.0.0", + "core-js": "3.33.0", "css-loader": "6.8.1", "css-minimizer-webpack-plugin": "5.0.1", "cypress": "13.1.0", @@ -226,7 +227,7 @@ "tracelib": "1.0.1", "ts-jest": "29.1.1", "ts-node": "10.9.1", - "typescript": "4.8.4", + "typescript": "5.2.2", "webpack": "5.89.0", "webpack-bundle-analyzer": "4.9.0", "webpack-cli": "5.1.4", @@ -243,7 +244,7 @@ "@fingerprintjs/fingerprintjs": "^3.4.2", "@glideapps/glide-data-grid": "^5.2.1", "@grafana-plugins/grafana-testdata-datasource": "workspace:*", - "@grafana/aws-sdk": "0.2.0", + "@grafana/aws-sdk": "0.3.1", "@grafana/data": "workspace:*", "@grafana/e2e-selectors": "workspace:*", "@grafana/experimental": "1.7.4", @@ -251,15 +252,15 @@ "@grafana/faro-web-sdk": "1.2.1", "@grafana/flamegraph": "workspace:*", "@grafana/google-sdk": "0.1.1", - "@grafana/lezer-logql": "0.2.1", - "@grafana/lezer-traceql": "0.0.8", + "@grafana/lezer-logql": "0.2.2", + "@grafana/lezer-traceql": "0.0.11", "@grafana/monaco-logql": "^0.0.7", "@grafana/runtime": "workspace:*", - "@grafana/scenes": "^1.20.1", + "@grafana/scenes": "1.27.0", "@grafana/schema": "workspace:*", "@grafana/ui": "workspace:*", "@kusto/monaco-kusto": "^7.4.0", - "@leeoniya/ufuzzy": "1.0.8", + "@leeoniya/ufuzzy": "1.0.13", "@lezer/common": "1.0.2", "@lezer/highlight": "1.1.3", "@lezer/lr": "1.3.3", @@ -310,7 +311,6 @@ "combokeys": "^3.0.0", "comlink": "4.4.1", "common-tags": "1.8.2", - "core-js": "3.33.0", "d3": "7.8.5", "d3-force": "3.0.0", "d3-scale-chromatic": "3.0.0", @@ -335,7 +335,7 @@ "json-markup": "^1.1.0", "json-source-map": "0.6.1", "jsurl": "^0.1.5", - "kbar": "0.1.0-beta.40", + "kbar": "0.1.0-beta.44", "lodash": "4.17.21", "logfmt": "^1.3.2", "lru-cache": "10.0.0", @@ -344,6 +344,8 @@ "marked": "5.1.1", "marked-mangle": "1.1.0", "memoize-one": "6.0.0", + "ml-regression-polynomial": "^3.0.0", + "ml-regression-simple-linear": "^3.0.0", "moment": "2.29.4", "moment-timezone": "0.5.43", "monaco-editor": "0.34.0", @@ -371,7 +373,6 @@ "react-dom": "18.2.0", "react-draggable": "4.4.5", "react-dropzone": "^14.2.3", - "react-enable": "^3.1.0", "react-grid-layout": "1.4.2", "react-highlight-words": "0.20.0", "react-hook-form": "7.5.3", @@ -417,6 +418,7 @@ "uuid": "9.0.0", "vendor": "link:./public/vendor", "visjs-network": "4.25.0", + "webpack-assets-manifest": "^5.1.0", "whatwg-fetch": "3.6.2", "xlsx": "https://cdn.sheetjs.com/xlsx-0.19.1/xlsx-0.19.1.tgz" }, diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json index baaa84f7208b5..9f966f93258d1 100644 --- a/packages/grafana-data/package.json +++ b/packages/grafana-data/package.json @@ -67,7 +67,7 @@ "@rollup/plugin-json": "6.0.0", "@rollup/plugin-node-resolve": "15.2.3", "@testing-library/dom": "9.3.3", - "@testing-library/jest-dom": "5.16.5", + "@testing-library/jest-dom": "6.1.4", "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.5.1", "@types/dompurify": "^2", @@ -76,7 +76,7 @@ "@types/jquery": "3.5.16", "@types/lodash": "4.14.195", "@types/marked": "5.0.1", - "@types/node": "18.18.4", + "@types/node": "20.8.10", "@types/papaparse": "5.3.7", "@types/react": "18.2.15", "@types/react-dom": "18.2.7", @@ -91,7 +91,7 @@ "rollup-plugin-dts": "^5.0.0", "rollup-plugin-esbuild": "5.0.0", "rollup-plugin-node-externals": "^5.0.0", - "typescript": "4.8.4" + "typescript": "5.2.2" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0", diff --git a/packages/grafana-data/src/context/plugins/usePluginContext.tsx b/packages/grafana-data/src/context/plugins/usePluginContext.tsx index 51723446b81fd..e2ea105662916 100644 --- a/packages/grafana-data/src/context/plugins/usePluginContext.tsx +++ b/packages/grafana-data/src/context/plugins/usePluginContext.tsx @@ -1,5 +1,7 @@ import { useContext } from 'react'; +import { PluginMeta } from '../../types'; + import { Context, PluginContextType } from './PluginContext'; export function usePluginContext(): PluginContextType { @@ -9,3 +11,21 @@ export function usePluginContext(): PluginContextType { } return context; } + +export function usePluginMeta(): PluginMeta { + const context = usePluginContext(); + + return context.meta; +} + +export function usePluginJsonData() { + const context = usePluginContext(); + + return context.meta.jsonData; +} + +export function usePluginVersion() { + const context = usePluginContext(); + + return context.meta.info.version; +} diff --git a/packages/grafana-data/src/dataframe/DataFrameJSON.ts b/packages/grafana-data/src/dataframe/DataFrameJSON.ts index c56842b33b60c..4b4e69cd5ae2c 100644 --- a/packages/grafana-data/src/dataframe/DataFrameJSON.ts +++ b/packages/grafana-data/src/dataframe/DataFrameJSON.ts @@ -143,7 +143,7 @@ export function decodeFieldValueEntities(lookup: FieldValueEntityLookup, values: */ export function decodeFieldValueEnums(lookup: string[], values: FieldValues) { for (let i = 0; i < values.length; i++) { - values[i] = lookup[values[i] as number]; + values[i] = lookup[Number(values[i])]; } } @@ -240,7 +240,9 @@ export function dataFrameToJSON(frame: DataFrame): DataFrameJSON { name: frame.name, fields: frame.fields.map((f) => { const { values, nanos, state, display, ...sfield } = f; - delete (sfield as any).entities; + if ('entities' in sfield) { + delete sfield.entities; + } data.values.push(values); if (nanos != null) { diff --git a/packages/grafana-data/src/dataframe/DataFrameView.test.ts b/packages/grafana-data/src/dataframe/DataFrameView.test.ts index 8975da7b24fc4..dca646c3ec0ee 100644 --- a/packages/grafana-data/src/dataframe/DataFrameView.test.ts +++ b/packages/grafana-data/src/dataframe/DataFrameView.test.ts @@ -46,7 +46,12 @@ describe('dataFrameView', () => { it('Should support array indexes', () => { expect(vector.length).toEqual(3); - const first = vector.get(0) as any; + const first = vector.get(0) as unknown as [ + MySpecialObject['time'], + MySpecialObject['name'], + MySpecialObject['value'], + MySpecialObject['more'], + ]; expect(first[0]).toEqual(100); expect(first[1]).toEqual('a'); expect(first[2]).toEqual(1); @@ -84,7 +89,10 @@ describe('dataFrameView', () => { }); it('Can handle fields with number name', () => { - const view = new DataFrameView( + const view = new DataFrameView<{ + '1': string; + '2': string; + }>( new MutableDataFrame({ fields: [ { name: '1', type: FieldType.string, values: ['a'] }, @@ -93,7 +101,7 @@ describe('dataFrameView', () => { }) ); - const obj = view.get(0) as any; + const obj = view.get(0); expect(obj['1']).toEqual('a'); expect(obj['2']).toEqual('b'); }); diff --git a/packages/grafana-data/src/dataframe/DataFrameView.ts b/packages/grafana-data/src/dataframe/DataFrameView.ts index 33cac6a514463..6d8b523140d6b 100644 --- a/packages/grafana-data/src/dataframe/DataFrameView.ts +++ b/packages/grafana-data/src/dataframe/DataFrameView.ts @@ -13,7 +13,7 @@ import { FunctionalVector } from '../vector/FunctionalVector'; * @typeParam T - Type of object stored in the DataFrame. * @beta */ -export class DataFrameView extends FunctionalVector { +export class DataFrameView extends FunctionalVector { private index = 0; private obj: T; readonly fields: { @@ -22,7 +22,7 @@ export class DataFrameView extends FunctionalVector { constructor(private data: DataFrame) { super(); - const obj = {} as unknown as T; + const obj = {} as T; const fields = {} as any; for (let i = 0; i < data.fields.length; i++) { @@ -34,14 +34,14 @@ export class DataFrameView extends FunctionalVector { fields[field.name] = field; const getter = () => field.values.get(this.index); // .get() to support all Vector types - if (!(obj as any).hasOwnProperty(field.name)) { + if (!obj.hasOwnProperty(field.name)) { Object.defineProperty(obj, field.name, { enumerable: true, // Shows up as enumerable property get: getter, }); } - if (!(obj as any).hasOwnProperty(i.toString())) { + if (!obj.hasOwnProperty(i.toString())) { Object.defineProperty(obj, i, { enumerable: false, // Don't enumerate array index get: getter, diff --git a/packages/grafana-data/src/dataframe/MutableDataFrame.ts b/packages/grafana-data/src/dataframe/MutableDataFrame.ts index 7d96a8f592c6d..84a02a33679f4 100644 --- a/packages/grafana-data/src/dataframe/MutableDataFrame.ts +++ b/packages/grafana-data/src/dataframe/MutableDataFrame.ts @@ -162,7 +162,7 @@ export class MutableDataFrame extends FunctionalVector implements Da return parser; } - private parseValue(field: Field, v: any): any { + private parseValue(field: Field, v: string) { let p = this.parsers?.get(field); if (!p) { p = this.setParser(field, makeFieldParser(v, field)); diff --git a/packages/grafana-data/src/dataframe/StreamingDataFrame.ts b/packages/grafana-data/src/dataframe/StreamingDataFrame.ts index d98b6b935788e..36fe7a77e22b4 100644 --- a/packages/grafana-data/src/dataframe/StreamingDataFrame.ts +++ b/packages/grafana-data/src/dataframe/StreamingDataFrame.ts @@ -123,7 +123,7 @@ export class StreamingDataFrame implements DataFrame { dataFrameDTO.fields = dataFrameDTO.fields.map((f) => ({ ...f, - values: (f.values as unknown[]).slice(numberOfItemsToRemove), + values: f.values?.slice(numberOfItemsToRemove), })); const length = dataFrameDTO.fields[0]?.values?.length ?? 0; @@ -488,7 +488,7 @@ export function getStreamingFrameOptions(opts?: Partial): // converts vertical insertion records with table keys in [0] and column values in [1...N] // to join()-able tables with column arrays -export function transpose(vrecs: any[][]) { +export function transpose(vrecs: unknown[][]) { let tableKeys = new Set(vrecs[0]); let tables = new Map(); diff --git a/packages/grafana-data/src/dataframe/index.ts b/packages/grafana-data/src/dataframe/index.ts index b1362fc3e3885..5c505a16670a8 100644 --- a/packages/grafana-data/src/dataframe/index.ts +++ b/packages/grafana-data/src/dataframe/index.ts @@ -7,5 +7,11 @@ export * from './dimensions'; export * from './ArrayDataFrame'; export * from './DataFrameJSON'; export * from './frameComparisons'; -export { anySeriesWithTimeField, isTimeSeriesFrame, isTimeSeriesFrames } from './utils'; +export { + anySeriesWithTimeField, + hasTimeField, + isTimeSeriesFrame, + isTimeSeriesFrames, + isTimeSeriesField, +} from './utils'; export { StreamingDataFrame, StreamingFrameAction, type StreamingFrameOptions, closestIdx } from './StreamingDataFrame'; diff --git a/packages/grafana-data/src/dataframe/processDataFrame.ts b/packages/grafana-data/src/dataframe/processDataFrame.ts index a0e95a773b6c8..e0b218c3d62c8 100644 --- a/packages/grafana-data/src/dataframe/processDataFrame.ts +++ b/packages/grafana-data/src/dataframe/processDataFrame.ts @@ -33,10 +33,11 @@ function convertTableToDataFrame(table: TableData): DataFrame { const fields = table.columns.map((c) => { // TODO: should be Column but type does not exists there so not sure whats up here. const { text, type, ...disp } = c as any; + const values: unknown[] = []; return { name: text?.length ? text : c, // rename 'text' to the 'name' field config: (disp || {}) as FieldConfig, - values: [] as unknown[], + values, type: type && Object.values(FieldType).includes(type as FieldType) ? (type as FieldType) : FieldType.other, }; }); diff --git a/packages/grafana-data/src/dataframe/utils.ts b/packages/grafana-data/src/dataframe/utils.ts index 6cd53545a4c3d..ea9dbd3432723 100644 --- a/packages/grafana-data/src/dataframe/utils.ts +++ b/packages/grafana-data/src/dataframe/utils.ts @@ -1,24 +1,70 @@ -import { DataFrame, FieldType } from '../types/dataFrame'; +import { DataFrame, Field, FieldType } from '../types/dataFrame'; import { getTimeField } from './processDataFrame'; +const MAX_TIME_COMPARISONS = 100; + export function isTimeSeriesFrame(frame: DataFrame) { // If we have less than two frames we can't have a timeseries if (frame.fields.length < 2) { return false; } - // In order to have a time series we need a time field - // and at least one number field - const timeField = frame.fields.find((field) => field.type === FieldType.time); + // Find a number field, as long as we have any number field this should work const numberField = frame.fields.find((field) => field.type === FieldType.number); - return timeField !== undefined && numberField !== undefined; + + // There are certain query types in which we will + // get times but they will be the same or not be + // in increasing order. To have a time-series the + // times need to be ordered from past to present + let timeFieldFound = false; + for (const field of frame.fields) { + if (isTimeSeriesField(field)) { + timeFieldFound = true; + break; + } + } + + return timeFieldFound && numberField !== undefined; } export function isTimeSeriesFrames(data: DataFrame[]) { return !data.find((frame) => !isTimeSeriesFrame(frame)); } +/** + * Determines if a field is a time field in ascending + * order within the sampling range specified by + * MAX_TIME_COMPARISONS + * + * @param field + * @returns boolean + */ +export function isTimeSeriesField(field: Field) { + if (field.type !== FieldType.time) { + return false; + } + + let greatestTime: number | null = null; + let testWindow = field.values.length > MAX_TIME_COMPARISONS ? MAX_TIME_COMPARISONS : field.values.length; + + // Test up to the test window number of values + for (let i = 0; i < testWindow; i++) { + const time = field.values[i]; + + // Check to see if the current time is greater than + // the last time. If we get to the end then we + // have a time series otherwise we return false + if (greatestTime === null || (time !== null && time > greatestTime)) { + greatestTime = time; + } else { + return false; + } + } + + return true; +} + /** * Indicates if there is any time field in the array of data frames * @param data @@ -32,3 +78,11 @@ export function anySeriesWithTimeField(data: DataFrame[]) { } return false; } + +/** + * Indicates if there is any time field in the data frame + * @param data + */ +export function hasTimeField(data: DataFrame): boolean { + return data.fields.some((field) => field.type === FieldType.time); +} diff --git a/packages/grafana-data/src/datetime/rangeutil.ts b/packages/grafana-data/src/datetime/rangeutil.ts index c4f514b67356d..7bb575e5f412e 100644 --- a/packages/grafana-data/src/datetime/rangeutil.ts +++ b/packages/grafana-data/src/datetime/rangeutil.ts @@ -214,7 +214,7 @@ export const convertRawToRange = ( return { from, to, raw: { from, to } }; }; -function isRelativeTime(v: DateTime | string) { +export function isRelativeTime(v: DateTime | string) { if (typeof v === 'string') { return v.indexOf('now') >= 0; } diff --git a/packages/grafana-data/src/events/common.ts b/packages/grafana-data/src/events/common.ts index 588b6a6d30d3f..6b480a834f36f 100644 --- a/packages/grafana-data/src/events/common.ts +++ b/packages/grafana-data/src/events/common.ts @@ -17,8 +17,8 @@ export interface DataHoverPayload { dataId?: string; // identifying string to correlate data between publishers and subscribers // When dragging, this will capture the point when the mouse was down - point: Record; // { time: 5678, lengthft: 456 } // each axis|scale gets a value - down?: Record; + point: Record; // { time: 5678, lengthft: 456 } // each axis|scale gets a value + down?: Record; } /** @alpha */ diff --git a/packages/grafana-data/src/field/displayProcessor.ts b/packages/grafana-data/src/field/displayProcessor.ts index 1f8e722641478..9cdef2760a69b 100644 --- a/packages/grafana-data/src/field/displayProcessor.ts +++ b/packages/grafana-data/src/field/displayProcessor.ts @@ -222,7 +222,7 @@ export function getRawDisplayProcessor(): DisplayProcessor { const getCircularReplacer = () => { const seen = new WeakSet(); - return (_key: any, value: object | null) => { + return (_key: string, value: object | null) => { if (typeof value === 'object' && value !== null) { if (seen.has(value)) { return; diff --git a/packages/grafana-data/src/field/fieldOverrides.ts b/packages/grafana-data/src/field/fieldOverrides.ts index 8316e1a735087..dcbd4fb97b334 100644 --- a/packages/grafana-data/src/field/fieldOverrides.ts +++ b/packages/grafana-data/src/field/fieldOverrides.ts @@ -238,7 +238,7 @@ export function applyFieldOverrides(options: ApplyFieldOverrideOptions): DataFra } function calculateRange( - config: FieldConfig, + config: FieldConfig, field: Field, globalRange: NumericRange | undefined, data: DataFrame[] @@ -269,7 +269,7 @@ function calculateRange( // 2. have the ability to selectively get display color or text (but not always both, which are each quite expensive) // 3. sufficently optimize text formatting and threshold color determinitation function cachingDisplayProcessor(disp: DisplayProcessor, maxCacheSize = 2500): DisplayProcessor { - type dispCache = Map; + type dispCache = Map; // decimals -> cache mapping, -1 is unspecified decimals const caches = new Map(); diff --git a/packages/grafana-data/src/field/fieldState.ts b/packages/grafana-data/src/field/fieldState.ts index 6f816ca5cf5be..04f1cc5abef2c 100644 --- a/packages/grafana-data/src/field/fieldState.ts +++ b/packages/grafana-data/src/field/fieldState.ts @@ -31,7 +31,7 @@ export function getFrameDisplayName(frame: DataFrame, index?: number) { } // list all the - if (index === undefined) { + if (index === undefined && frame.fields.length > 0) { return frame.fields .filter((f) => f.type !== FieldType.time) .map((f) => getFieldDisplayName(f, frame)) @@ -159,7 +159,7 @@ export function calculateFieldDisplayName(field: Field, frame?: DataFrame, allFr return displayName; } -function getUniqueFieldName(field: Field, frame?: DataFrame) { +export function getUniqueFieldName(field: Field, frame?: DataFrame) { let dupeCount = 0; let foundSelf = false; diff --git a/packages/grafana-data/src/field/index.ts b/packages/grafana-data/src/field/index.ts index b457d674034dc..e7b483bdd88fc 100644 --- a/packages/grafana-data/src/field/index.ts +++ b/packages/grafana-data/src/field/index.ts @@ -14,5 +14,5 @@ export { FieldConfigOptionsRegistry } from './FieldConfigOptionsRegistry'; export { sortThresholds, getActiveThreshold } from './thresholds'; export { applyFieldOverrides, validateFieldConfig, applyRawFieldOverrides, useFieldOverrides } from './fieldOverrides'; export { getFieldDisplayValuesProxy } from './getFieldDisplayValuesProxy'; -export { getFieldDisplayName, getFrameDisplayName, cacheFieldDisplayNames } from './fieldState'; +export { getFieldDisplayName, getFrameDisplayName, cacheFieldDisplayNames, getUniqueFieldName } from './fieldState'; export { getScaleCalculator, getFieldConfigWithMinMax, getMinMaxAndDelta } from './scale'; diff --git a/packages/grafana-data/src/field/overrides/processors.ts b/packages/grafana-data/src/field/overrides/processors.ts index d829f7963a9b5..5394c692cd597 100644 --- a/packages/grafana-data/src/field/overrides/processors.ts +++ b/packages/grafana-data/src/field/overrides/processors.ts @@ -8,7 +8,7 @@ import { ValueMapping, } from '../../types'; -export const identityOverrideProcessor = (value: T, _context: FieldOverrideContext, _settings: any) => { +export const identityOverrideProcessor = (value: T) => { return value; }; @@ -33,7 +33,7 @@ export const numberOverrideProcessor = ( }; export const displayNameOverrideProcessor = ( - value: any, + value: unknown, context: FieldOverrideContext, settings?: StringFieldConfigSettings ) => { @@ -100,14 +100,14 @@ export interface StringFieldConfigSettings { } export const stringOverrideProcessor = ( - value: any, + value: unknown, context: FieldOverrideContext, settings?: StringFieldConfigSettings ) => { if (value === null || value === undefined) { return value; } - if (settings && settings.expandTemplateVars && context.replaceVariables) { + if (settings && settings.expandTemplateVars && context.replaceVariables && typeof value === 'string') { return context.replaceVariables(value, context.field!.state!.scopedVars); } return `${value}`; diff --git a/packages/grafana-data/src/field/scale.ts b/packages/grafana-data/src/field/scale.ts index e97b01faf9462..c8624e6086fc6 100644 --- a/packages/grafana-data/src/field/scale.ts +++ b/packages/grafana-data/src/field/scale.ts @@ -9,7 +9,7 @@ import { getActiveThresholdForValue } from './thresholds'; export interface ColorScaleValue { percent: number; // 0-1 - threshold: Threshold; + threshold: Threshold | undefined; color: string; } @@ -49,13 +49,13 @@ function getBooleanScaleCalculator(field: Field, theme: GrafanaTheme2): ScaleCal const trueValue: ColorScaleValue = { color: theme.visualization.getColorByName('green'), percent: 1, - threshold: undefined as unknown as Threshold, + threshold: undefined, }; const falseValue: ColorScaleValue = { color: theme.visualization.getColorByName('red'), percent: 0, - threshold: undefined as unknown as Threshold, + threshold: undefined, }; const mode = getFieldColorModeForField(field); diff --git a/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts b/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts index 75f0a32f94d22..6f8beee78aeae 100644 --- a/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts +++ b/packages/grafana-data/src/field/standardFieldConfigEditorRegistry.ts @@ -19,10 +19,14 @@ export interface StandardEditorContext { export interface StandardEditorProps { value: TValue; onChange: (value?: TValue) => void; - item: StandardEditorsRegistryItem; context: StandardEditorContext; id?: string; + + item: RegistryItem & { + settings?: TSettings; + }; } + export interface StandardEditorsRegistryItem extends RegistryItem { editor: ComponentType>; settings?: TSettings; diff --git a/packages/grafana-data/src/geo/layer.ts b/packages/grafana-data/src/geo/layer.ts index c51750c36006f..bb65b01dcb353 100644 --- a/packages/grafana-data/src/geo/layer.ts +++ b/packages/grafana-data/src/geo/layer.ts @@ -42,7 +42,7 @@ export interface MapLayerHandler { */ registerOptionsUI?: ( builder: PanelOptionsEditorBuilder>, - context: StandardEditorContext + context: StandardEditorContext ) => void; } diff --git a/packages/grafana-data/src/panel/getPanelOptionsWithDefaults.ts b/packages/grafana-data/src/panel/getPanelOptionsWithDefaults.ts index 1061054d1d197..f3a8d44faf7c2 100644 --- a/packages/grafana-data/src/panel/getPanelOptionsWithDefaults.ts +++ b/packages/grafana-data/src/panel/getPanelOptionsWithDefaults.ts @@ -17,12 +17,12 @@ import { PanelPlugin } from './PanelPlugin'; export interface Props { plugin: PanelPlugin; currentFieldConfig: FieldConfigSource; - currentOptions: Record; + currentOptions: Record; isAfterPluginChange: boolean; } export interface OptionDefaults { - options: any; + options: Record; fieldConfig: FieldConfigSource; } @@ -111,11 +111,10 @@ export function filterFieldConfigOverrides( .filter((x) => x.properties.length > 0); } -function cleanProperties(obj: any, parentPath: string, fieldConfigRegistry: FieldConfigOptionsRegistry) { +function cleanProperties(obj: object, parentPath: string, fieldConfigRegistry: FieldConfigOptionsRegistry) { let found = false; - for (const propName of Object.keys(obj)) { - const value = obj[propName]; + for (const [propName, value] of Object.entries(obj)) { const fullPath = `${parentPath}${propName}`; const existsInRegistry = !!fieldConfigRegistry.getIfExists(fullPath); diff --git a/packages/grafana-data/src/panel/registryFactories.ts b/packages/grafana-data/src/panel/registryFactories.ts index 1cd6e8524d1ed..a312d0c128eb4 100644 --- a/packages/grafana-data/src/panel/registryFactories.ts +++ b/packages/grafana-data/src/panel/registryFactories.ts @@ -43,17 +43,17 @@ export function createFieldConfigRegistry( } for (let fieldConfigProp of standardConfigs) { + const id = fieldConfigProp.id as FieldConfigProperty; if (config.disableStandardOptions) { - const isDisabled = config.disableStandardOptions.indexOf(fieldConfigProp.id as FieldConfigProperty) > -1; + const isDisabled = config.disableStandardOptions.indexOf(id) > -1; if (isDisabled) { continue; } } if (config.standardOptions) { - const customHideFromDefaults = - config.standardOptions[fieldConfigProp.id as FieldConfigProperty]?.hideFromDefaults; - const customDefault = config.standardOptions[fieldConfigProp.id as FieldConfigProperty]?.defaultValue; - const customSettings = config.standardOptions[fieldConfigProp.id as FieldConfigProperty]?.settings; + const customHideFromDefaults = config.standardOptions[id]?.hideFromDefaults; + const customDefault = config.standardOptions[id]?.defaultValue; + const customSettings = config.standardOptions[id]?.settings; if (customHideFromDefaults) { fieldConfigProp = { diff --git a/packages/grafana-data/src/themes/colorManipulator.ts b/packages/grafana-data/src/themes/colorManipulator.ts index 0ab6eb2cca162..dcd0ce481e2a0 100644 --- a/packages/grafana-data/src/themes/colorManipulator.ts +++ b/packages/grafana-data/src/themes/colorManipulator.ts @@ -32,9 +32,15 @@ export function hexToRgb(color: string) { color = color.slice(1); const re = new RegExp(`.{1,${color.length >= 6 ? 2 : 1}}`, 'g'); - let colors = color.match(re); + let result = color.match(re); - if (colors && colors[0].length === 1) { + if (!result) { + return ''; + } + + let colors = Array.from(result); + + if (colors[0].length === 1) { colors = colors.map((n) => n + n); } diff --git a/packages/grafana-data/src/transformations/fieldReducer.ts b/packages/grafana-data/src/transformations/fieldReducer.ts index df2f690fbf301..dd8b1f98acfa9 100644 --- a/packages/grafana-data/src/transformations/fieldReducer.ts +++ b/packages/grafana-data/src/transformations/fieldReducer.ts @@ -39,7 +39,7 @@ type FieldReducer = (field: Field, ignoreNulls: boolean, nullAsZero: boolean) => export interface FieldReducerInfo extends RegistryItem { // Internal details - emptyInputResult?: any; // typically null, but some things like 'count' & 'sum' should be zero + emptyInputResult?: unknown; // typically null, but some things like 'count' & 'sum' should be zero standard: boolean; // The most common stats can all be calculated in a single pass reduce?: FieldReducer; } diff --git a/packages/grafana-data/src/transformations/index.ts b/packages/grafana-data/src/transformations/index.ts index 1fd3229f897d0..4cdd4ea2f8bfb 100644 --- a/packages/grafana-data/src/transformations/index.ts +++ b/packages/grafana-data/src/transformations/index.ts @@ -20,3 +20,6 @@ export type { RenameByRegexTransformerOptions } from './transformers/renameByReg export { joinDataFrames as outerJoinDataFrames, isLikelyAscendingVector } from './transformers/joinDataFrames'; export * from './transformers/histogram'; export { ensureTimeField } from './transformers/convertFieldType'; + +// Required for Sparklines util to work in @grafana/data, but ideally kept internal +export { applyNullInsertThreshold } from './transformers/nulls/nullInsertThreshold'; diff --git a/packages/grafana-data/src/transformations/transformers/calculateField.test.ts b/packages/grafana-data/src/transformations/transformers/calculateField.test.ts index 2ebb18c4aa547..a820514c95e8d 100644 --- a/packages/grafana-data/src/transformations/transformers/calculateField.test.ts +++ b/packages/grafana-data/src/transformations/transformers/calculateField.test.ts @@ -7,7 +7,13 @@ import { mockTransformationsRegistry } from '../../utils/tests/mockTransformatio import { ReducerID } from '../fieldReducer'; import { transformDataFrame } from '../transformDataFrame'; -import { CalculateFieldMode, calculateFieldTransformer, ReduceOptions } from './calculateField'; +import { + CalculateFieldMode, + calculateFieldTransformer, + ReduceOptions, + WindowSizeMode, + WindowAlignment, +} from './calculateField'; import { DataTransformerID } from './ids'; const seriesA = toDataFrame({ @@ -398,4 +404,548 @@ describe('calculateField transformer w/ timeseries', () => { `); }); }); + + it('calculates centered moving average on odd window size', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 1, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1.5); + expect(data.fields[1].values[1]).toEqual(2); + expect(data.fields[1].values[2]).toEqual(2.5); + }); + }); + + it('calculates centered moving average on even window size', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 0.5, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1.5); + expect(data.fields[1].values[2]).toEqual(2.5); + }); + }); + + it('calculates centered moving average when window size larger than dataset', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 5, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(2); + expect(data.fields[1].values[1]).toEqual(2); + expect(data.fields[1].values[2]).toEqual(2); + }); + }); + + it('calculates trailing moving average', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Trailing, + field: 'x', + windowSize: 1, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1.5); + expect(data.fields[1].values[2]).toEqual(2); + }); + }); + + it('throws error when calculating moving average if window size < 1', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Trailing, + field: 'x', + windowSize: 0, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const err = new Error('Add field from calculation transformation - Window size must be larger than 0'); + expect(received[0]).toEqual(err); + }); + }); + + it('calculates cumulative total', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.CumulativeFunctions, + cumulative: { + field: 'x', + reducer: ReducerID.sum, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(3); + expect(data.fields[1].values[2]).toEqual(6); + }); + }); + + it('calculates cumulative mean', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.CumulativeFunctions, + cumulative: { + field: 'x', + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1.5); + expect(data.fields[1].values[2]).toEqual(2); + }); + }); + it('calculates cumulative total with undefined values', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.CumulativeFunctions, + cumulative: { + field: 'x', + reducer: ReducerID.sum, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, undefined, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1); + expect(data.fields[1].values[2]).toEqual(3); + expect(data.fields[1].values[3]).toEqual(6); + }); + }); + + it('calculates cumulative total with nulls', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.CumulativeFunctions, + cumulative: { + field: 'x', + reducer: ReducerID.sum, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, null, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1); + expect(data.fields[1].values[2]).toEqual(3); + expect(data.fields[1].values[3]).toEqual(6); + }); + }); + + it('calculates trailing moving average with nulls', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Trailing, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, null, 2, 7] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1); + expect(data.fields[1].values[2]).toEqual(1.5); + expect(data.fields[1].values[3]).toEqual(4.5); + }); + }); + + it('calculates trailing moving variance', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Trailing, + field: 'x', + windowSize: 1, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.variance, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(0); + expect(data.fields[1].values[1]).toEqual(0.25); + expect(data.fields[1].values[2]).toBeCloseTo(0.6666666, 4); + }); + }); + + it('calculates centered moving stddev', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 1, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.stdDev, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(0.5); + expect(data.fields[1].values[1]).toBeCloseTo(0.8164, 2); + expect(data.fields[1].values[2]).toEqual(0.5); + }); + }); + + it('calculates centered moving stddev with null', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.stdDev, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, null, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(0); + expect(data.fields[1].values[1]).toEqual(0.5); + expect(data.fields[1].values[2]).toEqual(0.5); + expect(data.fields[1].values[3]).toEqual(0.5); + }); + }); + + it('calculates centered moving average with undefined values', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, undefined, 2, 7] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1.5); + expect(data.fields[1].values[2]).toEqual(4.5); + expect(data.fields[1].values[3]).toEqual(4.5); + }); + }); + + it('calculates centered moving average with nulls', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, null, 2, 7] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1); + expect(data.fields[1].values[1]).toEqual(1.5); + expect(data.fields[1].values[2]).toEqual(4.5); + expect(data.fields[1].values[3]).toEqual(4.5); + }); + }); + + it('calculates centered moving average with only nulls', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [null, null, null, null] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(0); + expect(data.fields[1].values[1]).toEqual(0); + expect(data.fields[1].values[2]).toEqual(0); + expect(data.fields[1].values[3]).toEqual(0); + }); + }); + + it('calculates centered moving average with 4 values', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Centered, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.mean, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, 2, 3, 4] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(1.5); + expect(data.fields[1].values[1]).toEqual(2); + expect(data.fields[1].values[2]).toEqual(3); + expect(data.fields[1].values[3]).toEqual(3.5); + }); + }); + + it('calculates trailing moving variance with null in the middle', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Trailing, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.variance, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [1, null, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(0); + expect(data.fields[1].values[1]).toEqual(0); + expect(data.fields[1].values[2]).toEqual(0.25); + expect(data.fields[1].values[3]).toEqual(0.25); + }); + }); + + it('calculates trailing moving variance with null in position 0', async () => { + const cfg = { + id: DataTransformerID.calculateField, + options: { + mode: CalculateFieldMode.WindowFunctions, + window: { + windowAlignment: WindowAlignment.Trailing, + field: 'x', + windowSize: 0.75, + windowSizeMode: WindowSizeMode.Percentage, + reducer: ReducerID.variance, + }, + }, + }; + + const series = toDataFrame({ + fields: [{ name: 'x', type: FieldType.number, values: [null, 1, 2, 3] }], + }); + + await expect(transformDataFrame([cfg], [series])).toEmitValuesWith((received) => { + const data = received[0][0]; + + expect(data.fields.length).toEqual(2); + expect(data.fields[1].values[0]).toEqual(0); + expect(data.fields[1].values[1]).toEqual(0); + expect(data.fields[1].values[2]).toEqual(0.25); + expect(data.fields[1].values[3]).toBeCloseTo(0.6666666, 4); + }); + }); }); diff --git a/packages/grafana-data/src/transformations/transformers/calculateField.ts b/packages/grafana-data/src/transformations/transformers/calculateField.ts index e749dfecf726c..e50dc3b268b1d 100644 --- a/packages/grafana-data/src/transformations/transformers/calculateField.ts +++ b/packages/grafana-data/src/transformations/transformers/calculateField.ts @@ -16,17 +16,40 @@ import { noopTransformer } from './noop'; export enum CalculateFieldMode { ReduceRow = 'reduceRow', + CumulativeFunctions = 'cumulativeFunctions', + WindowFunctions = 'windowFunctions', BinaryOperation = 'binary', UnaryOperation = 'unary', Index = 'index', } +export enum WindowSizeMode { + Percentage = 'percentage', + Fixed = 'fixed', +} + +export enum WindowAlignment { + Trailing = 'trailing', + Centered = 'centered', +} + export interface ReduceOptions { include?: string[]; // Assume all fields reducer: ReducerID; nullValueMode?: NullValueMode; } +export interface CumulativeOptions { + field?: string; + reducer: ReducerID; +} + +export interface WindowOptions extends CumulativeOptions { + windowSize?: number; + windowSizeMode?: WindowSizeMode; + windowAlignment?: WindowAlignment; +} + export interface UnaryOptions { operator: UnaryOperationID; fieldName: string; @@ -46,6 +69,13 @@ const defaultReduceOptions: ReduceOptions = { reducer: ReducerID.sum, }; +export const defaultWindowOptions: WindowOptions = { + reducer: ReducerID.mean, + windowAlignment: WindowAlignment.Trailing, + windowSizeMode: WindowSizeMode.Percentage, + windowSize: 0.1, +}; + const defaultBinaryOptions: BinaryOptions = { left: '', operator: BinaryOperationID.Add, @@ -64,6 +94,8 @@ export interface CalculateFieldTransformerOptions { // Only one should be filled reduce?: ReduceOptions; + window?: WindowOptions; + cumulative?: CumulativeOptions; binary?: BinaryOptions; unary?: UnaryOptions; index?: IndexOptions; @@ -104,39 +136,49 @@ export const calculateFieldTransformer: DataTransformerInfo { - const indexArr = [...Array(frame.length).keys()]; + creator = getBinaryCreator(defaults(binaryOptions, defaultBinaryOptions), data); + break; + case CalculateFieldMode.Index: + return data.map((frame) => { + const indexArr = [...Array(frame.length).keys()]; - if (options.index?.asPercentile) { - for (let i = 0; i < indexArr.length; i++) { - indexArr[i] = indexArr[i] / indexArr.length; + if (options.index?.asPercentile) { + for (let i = 0; i < indexArr.length; i++) { + indexArr[i] = indexArr[i] / indexArr.length; + } } - } - const f = { - name: options.alias ?? 'Row', - type: FieldType.number, - values: indexArr, - config: options.index?.asPercentile ? { unit: 'percentunit' } : {}, - }; - return { - ...frame, - fields: options.replaceFields ? [f] : [...frame.fields, f], - }; - }); + const f = { + name: options.alias ?? 'Row', + type: FieldType.number, + values: indexArr, + config: options.index?.asPercentile ? { unit: 'percentunit' } : {}, + }; + return { + ...frame, + fields: options.replaceFields ? [f] : [...frame.fields, f], + }; + }); } // Nothing configured @@ -180,6 +222,213 @@ export const calculateFieldTransformer: DataTransformerInfo { + const window = Math.ceil( + options.windowSize! * (options.windowSizeMode === WindowSizeMode.Percentage ? frame.length : 1) + ); + + // Find the columns that should be examined + let selectedField: Field | null = null; + for (const field of frame.fields) { + if (matcher(field, frame, allFrames)) { + selectedField = field; + break; + } + } + + if (!selectedField) { + return; + } + + if (![ReducerID.mean, ReducerID.stdDev, ReducerID.variance].includes(options.reducer)) { + throw new Error(`Add field from calculation transformation - Unsupported reducer: ${options.reducer}`); + } + + if (options.windowAlignment === WindowAlignment.Centered) { + return getCenteredWindowValues(frame, options.reducer, selectedField, window); + } else { + return getTrailingWindowValues(frame, options.reducer, selectedField, window); + } + }; +} + +function getTrailingWindowValues(frame: DataFrame, reducer: ReducerID, selectedField: Field, window: number) { + const vals: number[] = []; + let sum = 0; + let count = 0; + for (let i = 0; i < frame.length; i++) { + if (reducer === ReducerID.mean) { + const currentValue = selectedField.values[i]; + if (currentValue !== null && currentValue !== undefined) { + count++; + sum += currentValue; + + if (i > window - 1) { + sum -= selectedField.values[i - window]; + count--; + } + } + vals.push(count === 0 ? 0 : sum / count); + } else if (reducer === ReducerID.variance) { + const start = Math.max(0, i - window + 1); + const end = i + 1; + vals.push(calculateVariance(selectedField.values.slice(start, end))); + } else if (reducer === ReducerID.stdDev) { + const start = Math.max(0, i - window + 1); + const end = i + 1; + vals.push(calculateStdDev(selectedField.values.slice(start, end))); + } + } + return vals; +} + +function getCenteredWindowValues(frame: DataFrame, reducer: ReducerID, selectedField: Field, window: number) { + const vals: number[] = []; + let sum = 0; + let count = 0; + // Current value (i) is included in the leading part of the window. Which means if the window size is odd, + // the leading part of the window will be larger than the trailing part. + const leadingPartOfWindow = Math.ceil(window / 2) - 1; + const trailingPartOfWindow = Math.floor(window / 2); + for (let i = 0; i < frame.length; i++) { + const first = i - trailingPartOfWindow; + const last = i + leadingPartOfWindow; + if (reducer === ReducerID.mean) { + if (i === 0) { + // We're at the start and need to prime the leading part of the window + for (let x = 0; x < leadingPartOfWindow + 1 && x < selectedField.values.length; x++) { + if (selectedField.values[x] != null) { + sum += selectedField.values[x]; + count++; + } + } + } else { + if (last < selectedField.values.length) { + // Last is inside the data and should be added. + if (selectedField.values[last] != null) { + sum += selectedField.values[last]; + count++; + } + } + if (first > 0) { + // Remove values that have fallen outside of the window, if the start of the window isn't outside of the data. + if (selectedField.values[first - 1] != null) { + sum -= selectedField.values[first - 1]; + count--; + } + } + } + vals.push(count === 0 ? 0 : sum / count); + } else if (reducer === ReducerID.variance) { + const windowVals = selectedField.values.slice( + Math.max(0, first), + Math.min(last + 1, selectedField.values.length) + ); + vals.push(calculateVariance(windowVals)); + } else if (reducer === ReducerID.stdDev) { + const windowVals = selectedField.values.slice( + Math.max(0, first), + Math.min(last + 1, selectedField.values.length) + ); + vals.push(calculateStdDev(windowVals)); + } + } + return vals; +} + +function calculateVariance(vals: number[]): number { + if (vals.length < 1) { + return 0; + } + let squareSum = 0; + let runningMean = 0; + let nonNullCount = 0; + for (let i = 0; i < vals.length; i++) { + const currentValue = vals[i]; + if (currentValue != null) { + nonNullCount++; + let _oldMean = runningMean; + runningMean += (currentValue - _oldMean) / nonNullCount; + squareSum += (currentValue - _oldMean) * (currentValue - runningMean); + } + } + if (nonNullCount === 0) { + return 0; + } + const variance = squareSum / nonNullCount; + return variance; +} + +function calculateStdDev(vals: number[]): number { + return Math.sqrt(calculateVariance(vals)); +} + +function getCumulativeCreator(options: CumulativeOptions, allFrames: DataFrame[]): ValuesCreator { + let matcher = getFieldMatcher({ + id: FieldMatcherID.numeric, + }); + + if (options.field) { + matcher = getFieldMatcher({ + id: FieldMatcherID.byNames, + options: { + names: [options.field], + }, + }); + } + + if (![ReducerID.mean, ReducerID.sum].includes(options.reducer)) { + throw new Error(`Add field from calculation transformation - Unsupported reducer: ${options.reducer}`); + } + + return (frame: DataFrame) => { + // Find the columns that should be examined + let selectedField: Field | null = null; + for (const field of frame.fields) { + if (matcher(field, frame, allFrames)) { + selectedField = field; + break; + } + } + + if (!selectedField) { + return; + } + + const vals: number[] = []; + + let total = 0; + for (let i = 0; i < frame.length; i++) { + total += selectedField.values[i] ?? 0; + if (options.reducer === ReducerID.sum) { + vals.push(total); + } else if (options.reducer === ReducerID.mean) { + vals.push(total / (i + 1)); + } + } + + return vals; + }; +} + function getReduceRowCreator(options: ReduceOptions, allFrames: DataFrame[]): ValuesCreator { let matcher = getFieldMatcher({ id: FieldMatcherID.numeric, @@ -227,6 +476,7 @@ function getReduceRowCreator(options: ReduceOptions, allFrames: DataFrame[]): Va for (let j = 0; j < size; j++) { row.values[j] = columns[j][i]; } + vals.push(reducer(row, ignoreNulls, nullAsZero)[options.reducer]); } @@ -309,6 +559,16 @@ export function getNameFromOptions(options: CalculateFieldTransformerOptions) { } switch (options.mode) { + case CalculateFieldMode.CumulativeFunctions: { + const { cumulative } = options; + return `cumulative ${cumulative?.reducer ?? ''}${cumulative?.field ? `(${cumulative.field})` : ''}`; + } + case CalculateFieldMode.WindowFunctions: { + const { window } = options; + return `${window?.windowAlignment ?? ''} moving ${window?.reducer ?? ''}${ + window?.field ? `(${window.field})` : '' + }`; + } case CalculateFieldMode.UnaryOperation: { const { unary } = options; return `${unary?.operator ?? ''}${unary?.fieldName ? `(${unary.fieldName})` : ''}`; diff --git a/packages/grafana-data/src/transformations/transformers/convertFieldType.ts b/packages/grafana-data/src/transformations/transformers/convertFieldType.ts index f4ef713c709fa..b076ef4e6ee02 100644 --- a/packages/grafana-data/src/transformations/transformers/convertFieldType.ts +++ b/packages/grafana-data/src/transformations/transformers/convertFieldType.ts @@ -256,25 +256,24 @@ export function ensureTimeField(field: Field, dateFormat?: string): Field { return fieldToTimeField(field, dateFormat); } -function fieldToEnumField(field: Field, cfg?: EnumFieldConfig): Field { - const enumConfig = { ...cfg }; +function fieldToEnumField(field: Field, config?: EnumFieldConfig): Field { + const enumConfig = { ...config }; const enumValues = field.values.slice(); + + // Create lookup map based on existing enum config text values, if none exist return field as is const lookup = new Map(); - if (enumConfig.text) { + if (enumConfig.text && enumConfig.text.length > 0) { for (let i = 0; i < enumConfig.text.length; i++) { lookup.set(enumConfig.text[i], i); } } else { - enumConfig.text = []; + return field; } + // Convert field values to enum indexes for (let i = 0; i < enumValues.length; i++) { - const v = enumValues[i]; - if (!lookup.has(v)) { - enumConfig.text[lookup.size] = v; - lookup.set(v, lookup.size); - } - enumValues[i] = lookup.get(v); + const value = enumValues[i]; + enumValues[i] = lookup.get(value); } return { diff --git a/packages/grafana-data/src/transformations/transformers/groupBy.ts b/packages/grafana-data/src/transformations/transformers/groupBy.ts index e57d15ed9b303..3fd95db316b63 100644 --- a/packages/grafana-data/src/transformations/transformers/groupBy.ts +++ b/packages/grafana-data/src/transformations/transformers/groupBy.ts @@ -117,7 +117,7 @@ export const groupByTransformer: DataTransformerInfo const fields: Field[] = []; for (const field of groupByFields) { - const values: any[] = []; + const values: unknown[] = []; const fieldName = getFieldDisplayName(field); valuesByGroupKey.forEach((value) => { @@ -142,7 +142,7 @@ export const groupByTransformer: DataTransformerInfo const fieldName = getFieldDisplayName(field); const aggregations = options.fields[fieldName].aggregations; - const valuesByAggregation: Record = {}; + const valuesByAggregation: Record = {}; valuesByGroupKey.forEach((value) => { const fieldWithValuesForGroup = value[fieldName]; diff --git a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts index f600b5ee7ba10..bb1dcd445d4bf 100644 --- a/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts +++ b/packages/grafana-data/src/transformations/transformers/groupingToMatrix.ts @@ -89,7 +89,7 @@ export const groupingToMatrixTransformer: DataTransformerInfo a - b; export interface HistogramTransformerInputs { @@ -496,7 +496,7 @@ export function incrRoundDn(num: number, incr: number) { function histogram( vals: number[], getBucket: (v: number) => number, - filterOut?: any[] | null, + filterOut?: number[], sort?: ((a: number, b: number) => number) | null ): AlignedData { let hist = new Map(); diff --git a/packages/grafana-data/src/transformations/transformers/ids.ts b/packages/grafana-data/src/transformations/transformers/ids.ts index efcc57804c48e..4d5f7e2dd9e18 100644 --- a/packages/grafana-data/src/transformations/transformers/ids.ts +++ b/packages/grafana-data/src/transformations/transformers/ids.ts @@ -39,4 +39,5 @@ export enum DataTransformerID { timeSeriesTable = 'timeSeriesTable', formatTime = 'formatTime', formatString = 'formatString', + regression = 'regression', } diff --git a/packages/grafana-data/src/transformations/transformers/merge.ts b/packages/grafana-data/src/transformations/transformers/merge.ts index 5abf270b6e5c8..4c783acf42c59 100644 --- a/packages/grafana-data/src/transformations/transformers/merge.ts +++ b/packages/grafana-data/src/transformations/transformers/merge.ts @@ -73,7 +73,7 @@ export const mergeTransformer: DataTransformerInfo = { return dataFrames; } - const valuesByKey: Record>> = {}; + const valuesByKey: Record>> = {}; const valuesInOrder: ValuePointer[] = []; const keyFactory = createKeyFactory(data, fieldIndexByName, fieldNamesForKey); const valueMapper = createValueMapper(data, fieldNames, fieldIndexByName); @@ -157,7 +157,7 @@ const createValueMapper = ( fieldIndexByName: Record> ) => { return (frameIndex: number, valueIndex: number) => { - const value: Record = {}; + const value: Record = {}; const fieldNames = Array.from(fieldByName); for (const fieldName of fieldNames) { @@ -188,7 +188,7 @@ const createValueMapper = ( }; }; -const isMergable = (existing: Record, value: Record): boolean => { +const isMergable = (existing: Record, value: Record): boolean => { let mergable = true; for (const prop in value) { @@ -217,7 +217,7 @@ const fieldExistsInAllFrames = ( return Object.keys(fieldIndexByName[field.name]).length === data.length; }; -const createPointer = (key: string, valuesByKey: Record>>): ValuePointer => { +const createPointer = (key: string, valuesByKey: Record>>): ValuePointer => { return { key, index: valuesByKey[key].length - 1, diff --git a/packages/grafana-ui/src/components/GraphNG/nullInsertThreshold.test.ts b/packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.test.ts similarity index 100% rename from packages/grafana-ui/src/components/GraphNG/nullInsertThreshold.test.ts rename to packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.test.ts diff --git a/packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.ts b/packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.ts new file mode 100644 index 0000000000000..94d8dd2e3c0ce --- /dev/null +++ b/packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.ts @@ -0,0 +1,186 @@ +import { DataFrame, FieldType } from '../../../types'; + +type InsertMode = (prev: number, next: number, threshold: number) => number; + +const INSERT_MODES = { + threshold: (prev: number, next: number, threshold: number) => prev + threshold, + midpoint: (prev: number, next: number, threshold: number) => (prev + next) / 2, + // previous time + 1ms to prevent StateTimeline from forward-interpolating prior state + plusone: (prev: number, next: number, threshold: number) => prev + 1, +}; + +interface NullInsertOptions { + frame: DataFrame; + refFieldName?: string | null; + refFieldPseudoMax?: number; + refFieldPseudoMin?: number; + insertMode?: InsertMode; +} + +function getRefField(frame: DataFrame, refFieldName?: string | null) { + return frame.fields.find((field) => { + // note: getFieldDisplayName() would require full DF[] + return refFieldName != null ? field.name === refFieldName : field.type === FieldType.time; + }); +} + +/** @internal */ +export function applyNullInsertThreshold(opts: NullInsertOptions): DataFrame { + if (opts.frame.length === 0) { + return opts.frame; + } + + let thorough = true; + let { frame, refFieldName, refFieldPseudoMax, refFieldPseudoMin, insertMode } = opts; + + if (!insertMode) { + insertMode = INSERT_MODES.threshold; + } + + const refField = getRefField(frame, refFieldName); + + if (refField == null) { + return frame; + } + + refField.state = { + ...refField.state, + nullThresholdApplied: true, + }; + + const thresholds = frame.fields.map((field) => field.config.custom?.insertNulls || refField.config.interval || null); + + const uniqueThresholds = new Set(thresholds); + + uniqueThresholds.delete(null as any); + + if (uniqueThresholds.size === 0) { + return frame; + } + + if (uniqueThresholds.size === 1) { + const threshold = uniqueThresholds.values().next().value; + + if (threshold <= 0) { + return frame; + } + + const refValues = refField.values; + + const frameValues = frame.fields.map((field) => field.values); + + const filledFieldValues = nullInsertThreshold( + refValues, + frameValues, + threshold, + refFieldPseudoMin, + refFieldPseudoMax, + insertMode, + thorough + ); + + if (filledFieldValues === frameValues) { + return frame; + } + + return { + ...frame, + length: filledFieldValues[0].length, + fields: frame.fields.map((field, i) => ({ + ...field, + values: filledFieldValues[i], + })), + }; + } + + // TODO: unique threshold-per-field (via overrides) is unimplemented + // should be done by processing each (refField + thresholdA-field1 + thresholdA-field2...) + // as a separate nullInsertThreshold() dataset, then re-join into single dataset via join() + return frame; +} + +function nullInsertThreshold( + refValues: number[], + frameValues: any[][], + threshold: number, + refFieldPseudoMin: number | null = null, + // will insert a trailing null when refFieldPseudoMax > last datapoint + threshold + refFieldPseudoMax: number | null = null, + getInsertValue: InsertMode, + // will insert the value at every missing interval + thorough: boolean +) { + const len = refValues.length; + const refValuesNew: number[] = []; + + // Continuously subtract the threshold from the first data point, filling in insert values accordingly + if (refFieldPseudoMin != null && refFieldPseudoMin < refValues[0]) { + let preFillCount = Math.ceil((refValues[0] - refFieldPseudoMin) / threshold); + // this will be 0 or 1 threshold increment left of visible range + let prevSlot = refValues[0] - preFillCount * threshold; + + while (prevSlot < refValues[0]) { + // (prevSlot - threshold) is used to simulate the previous 'real' data point, as getInsertValue expects + refValuesNew.push(getInsertValue(prevSlot - threshold, prevSlot, threshold)); + prevSlot += threshold; + } + } + + // Insert initial value + refValuesNew.push(refValues[0]); + + let prevValue: number = refValues[0]; + + // Fill nulls when a value is greater than the threshold value + for (let i = 1; i < len; i++) { + const curValue = refValues[i]; + + while (curValue - prevValue > threshold) { + refValuesNew.push(getInsertValue(prevValue, curValue, threshold)); + + prevValue += threshold; + + if (!thorough) { + break; + } + } + + refValuesNew.push(curValue); + + prevValue = curValue; + } + + // At the end of the sequence + if (refFieldPseudoMax != null && refFieldPseudoMax > prevValue) { + while (prevValue + threshold < refFieldPseudoMax) { + refValuesNew.push(getInsertValue(prevValue, refFieldPseudoMax, threshold)); + prevValue += threshold; + } + } + + const filledLen = refValuesNew.length; + + if (filledLen === len) { + return frameValues; + } + + const filledFieldValues: any[][] = []; + + for (let fieldValues of frameValues) { + let filledValues; + + if (fieldValues !== refValues) { + filledValues = Array(filledLen); + + for (let i = 0, j = 0; i < filledLen; i++) { + filledValues[i] = refValues[j] === refValuesNew[i] ? fieldValues[j++] : null; + } + } else { + filledValues = refValuesNew; + } + + filledFieldValues.push(filledValues); + } + + return filledFieldValues; +} diff --git a/packages/grafana-ui/src/components/GraphNG/nullToUndefThreshold.ts b/packages/grafana-data/src/transformations/transformers/nulls/nullToUndefThreshold.ts similarity index 83% rename from packages/grafana-ui/src/components/GraphNG/nullToUndefThreshold.ts rename to packages/grafana-data/src/transformations/transformers/nulls/nullToUndefThreshold.ts index dacc82a63fa67..7003ede81abc7 100644 --- a/packages/grafana-ui/src/components/GraphNG/nullToUndefThreshold.ts +++ b/packages/grafana-data/src/transformations/transformers/nulls/nullToUndefThreshold.ts @@ -1,6 +1,6 @@ // mutates all nulls -> undefineds in the fieldValues array for value-less refValues ranges below maxThreshold // refValues is typically a time array and maxThreshold is the allowable distance between in time -export function nullToUndefThreshold(refValues: number[], fieldValues: any[], maxThreshold: number): any[] { +export function nullToUndefThreshold(refValues: number[], fieldValues: unknown[], maxThreshold: number) { let prevRef; let nullIdx; @@ -12,8 +12,8 @@ export function nullToUndefThreshold(refValues: number[], fieldValues: any[], ma nullIdx = i; } } else { - if (nullIdx != null) { - if (refValues[i] - (prevRef as number) < maxThreshold) { + if (nullIdx != null && prevRef != null) { + if (refValues[i] - prevRef < maxThreshold) { while (nullIdx < i) { fieldValues[nullIdx++] = undefined; } diff --git a/packages/grafana-ui/src/components/GraphNG/nullToValue.test.ts b/packages/grafana-data/src/transformations/transformers/nulls/nullToValue.test.ts similarity index 100% rename from packages/grafana-ui/src/components/GraphNG/nullToValue.test.ts rename to packages/grafana-data/src/transformations/transformers/nulls/nullToValue.test.ts diff --git a/packages/grafana-data/src/transformations/transformers/nulls/nullToValue.ts b/packages/grafana-data/src/transformations/transformers/nulls/nullToValue.ts new file mode 100644 index 0000000000000..4c3ba5a81e683 --- /dev/null +++ b/packages/grafana-data/src/transformations/transformers/nulls/nullToValue.ts @@ -0,0 +1,27 @@ +import { DataFrame } from '../../../types'; + +export function nullToValue(frame: DataFrame) { + return { + ...frame, + fields: frame.fields.map((field) => { + const noValue = +field.config?.noValue!; + + if (!Number.isNaN(noValue)) { + const transformedVals = field.values.slice(); + + for (let i = 0; i < transformedVals.length; i++) { + if (transformedVals[i] === null) { + transformedVals[i] = noValue; + } + } + + return { + ...field, + values: transformedVals, + }; + } else { + return field; + } + }), + }; +} diff --git a/packages/grafana-data/src/transformations/transformers/organize.test.ts b/packages/grafana-data/src/transformations/transformers/organize.test.ts index 712d9c17c1514..34a73672dc6f4 100644 --- a/packages/grafana-data/src/transformations/transformers/organize.test.ts +++ b/packages/grafana-data/src/transformations/transformers/organize.test.ts @@ -70,6 +70,33 @@ describe('OrganizeFields Transformer', () => { ]); }); }); + + it('should order and filter (inclusion) according to config', async () => { + const cfg: DataTransformerConfig = { + id: DataTransformerID.organize, + options: { + excludeByName: {}, + indexByName: {}, + includeByName: { + time: true, + }, + renameByName: {}, + }, + }; + + await expect(transformDataFrame([cfg], [data])).toEmitValuesWith((received) => { + const data = received[0]; + const organized = data[0]; + expect(organized.fields).toEqual([ + { + config: {}, + name: 'time', + type: FieldType.time, + values: [3000, 4000, 5000, 6000], + }, + ]); + }); + }); }); describe('when inconsistent data is received', () => { diff --git a/packages/grafana-data/src/transformations/transformers/organize.ts b/packages/grafana-data/src/transformations/transformers/organize.ts index 3eb8b04e709c1..dfda3a779b4a7 100644 --- a/packages/grafana-data/src/transformations/transformers/organize.ts +++ b/packages/grafana-data/src/transformations/transformers/organize.ts @@ -9,6 +9,7 @@ export interface OrganizeFieldsTransformerOptions extends OrderFieldsTransformerOptions, RenameFieldsTransformerOptions { excludeByName: Record; + includeByName?: Record; } export const organizeFieldsTransformer: DataTransformerInfo = { @@ -19,6 +20,7 @@ export const organizeFieldsTransformer: DataTransformerInfo { return data.length > 1 @@ -33,6 +35,7 @@ export const organizeFieldsTransformer: DataTransformerInfo { + it.each([ + // [value, expected] + + // These are objects + [{}, true], + [[], true], + [{ a: 1 }, true], + [new Date(), true], + [new Error(), true], + + // These are not! + [parseInt('blabla', 10), false], // NaN + [null, false], + [undefined, false], + [-Infinity, false], + [-42, false], + [0, false], + [-0, false], + [42, false], + [Infinity, false], + ['foo', false], + [true, false], + [Symbol(), false], + [() => {}, false], + ])('should return %p for %p', (input, expected) => { + expect(isObject(input)).toBe(expected); + }); +}); + +describe('isTruthy', () => { + it.each([ + // [value, expected] + + // These are truthy + [true, true], + [-Infinity, true], + [-42, true], + [42, true], + [Infinity, true], + ['foo', true], + [{}, true], + [[], true], + [() => {}, true], + [Symbol(), true], + [new Date(), true], + + // These are falsy + [false, false], + [0, false], + [-0, false], + ['', false], + [null, false], + [undefined, false], + [parseInt('blabla', 10), false], // NaN + ])('should return %p for %p', (input, expected) => { + expect(isTruthy(input)).toBe(expected); + }); +}); diff --git a/packages/grafana-data/src/types/data.ts b/packages/grafana-data/src/types/data.ts index 2785f6c799f4e..b8130318bcfa0 100644 --- a/packages/grafana-data/src/types/data.ts +++ b/packages/grafana-data/src/types/data.ts @@ -213,3 +213,27 @@ export interface DataConfigSource { type Truthy = T extends false | '' | 0 | null | undefined ? never : T; export const isTruthy = (value: T): value is Truthy => Boolean(value); + +/** + * Serves no runtime purpose - only used to make typescript check a value has been correctly + * narrowed to an object + */ +function identityObject(value: object): object { + return value; +} + +/** + * Utility type predicate to check if a value is typeof object, but excludes "null". + * + * We normally discourage the use of type predicates in favor of just inline typescript narrowing, + * but this is a special case to handle null annoyingly being typeof object + */ +export function isObject(value: unknown): value is object { + if (typeof value === 'object' && value !== null) { + identityObject(value); + + return true; + } + + return false; +} diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 855ec33a73af1..68faf1d72e35e 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -428,7 +428,10 @@ export interface QueryEditorProps< */ data?: PanelData; range?: TimeRange; - exploreId?: any; + /** + * @deprecated This is not used anymore and will be removed in a future release. + */ + exploreId?: string; history?: Array>; queries?: DataQuery[]; app?: CoreApp; @@ -547,6 +550,7 @@ export interface DataQueryRequest { cacheTimeout?: string | null; queryCachingTTL?: number | null; + skipQueryCache?: boolean; rangeRaw?: RawTimeRange; timeInfo?: string; // The query time description (blue text in the upper right) panelId?: number; @@ -579,11 +583,22 @@ export interface QueryFix { action?: QueryFixAction; } +export type QueryFixType = 'ADD_FILTER' | 'ADD_FILTER_OUT' | 'ADD_STRING_FILTER' | 'ADD_STRING_FILTER_OUT'; export interface QueryFixAction { - type: string; query?: string; preventSubmit?: boolean; + /** + * The type of action to perform. Will be passed to the data source to handle. + */ + type: QueryFixType | string; + /** + * A key value map of options that will be passed. Usually used to pass e.g. the label and value. + */ options?: KeyValue; + /** + * An optional single row data frame containing the row that triggered the the QueryFixAction. + */ + frame?: DataFrame; } export interface QueryHint { @@ -674,8 +689,6 @@ export interface DataSourceInstanceSettings; vars: Record; } @@ -48,6 +51,9 @@ export interface ExploreLogsPanelState { id?: string; columns?: Record; visualisationType?: 'table' | 'logs'; + labelFieldName?: string; + // Used for logs table visualisation, contains the refId of the dataFrame that is currently visualized + refId?: string; } export interface SplitOpenOptions { diff --git a/packages/grafana-data/src/types/featureToggles.gen.ts b/packages/grafana-data/src/types/featureToggles.gen.ts index 16ffae92325d5..737cc8ca7e0d1 100644 --- a/packages/grafana-data/src/types/featureToggles.gen.ts +++ b/packages/grafana-data/src/types/featureToggles.gen.ts @@ -18,7 +18,6 @@ * @public */ export interface FeatureToggles { - trimDefaults?: boolean; disableEnvelopeEncryption?: boolean; ['live-service-web-worker']?: boolean; queryOverLive?: boolean; @@ -33,10 +32,10 @@ export interface FeatureToggles { exploreContentOutline?: boolean; datasourceQueryMultiStatus?: boolean; traceToMetrics?: boolean; - newDBLibrary?: boolean; autoMigrateOldPanels?: boolean; disableAngular?: boolean; canvasPanelNesting?: boolean; + newVizTooltips?: boolean; scenes?: boolean; disableSecretsCompatibility?: boolean; logRequestsInstrumentedAsUnknown?: boolean; @@ -44,7 +43,7 @@ export interface FeatureToggles { topnav?: boolean; dockedMegaMenu?: boolean; grpcServer?: boolean; - entityStore?: boolean; + unifiedStorage?: boolean; cloudWatchCrossAccountQuerying?: boolean; redshiftAsyncQueryDataSupport?: boolean; athenaAsyncQueryDataSupport?: boolean; @@ -64,9 +63,9 @@ export interface FeatureToggles { lokiQuerySplitting?: boolean; lokiQuerySplittingConfig?: boolean; individualCookiePreferences?: boolean; - gcomOnlyExternalOrgRoleSync?: boolean; prometheusMetricEncyclopedia?: boolean; influxdbBackendMigration?: boolean; + influxqlStreamingParser?: boolean; clientTokenRotation?: boolean; prometheusDataplane?: boolean; lokiMetricDataplane?: boolean; @@ -74,7 +73,6 @@ export interface FeatureToggles { dataplaneFrontendFallback?: boolean; disableSSEDataplane?: boolean; alertStateHistoryLokiSecondary?: boolean; - alertingNotificationsPoliciesMatchingInstances?: boolean; alertStateHistoryLokiPrimary?: boolean; alertStateHistoryLokiOnly?: boolean; unifiedRequestLog?: boolean; @@ -86,7 +84,6 @@ export interface FeatureToggles { advancedDataSourcePicker?: boolean; faroDatasourceSelector?: boolean; enableDatagridEditing?: boolean; - dataSourcePageHeader?: boolean; extraThemes?: boolean; lokiPredefinedOperations?: boolean; pluginsFrontendSandbox?: boolean; @@ -108,10 +105,12 @@ export interface FeatureToggles { metricsSummary?: boolean; grafanaAPIServer?: boolean; grafanaAPIServerWithExperimentalAPIs?: boolean; + grafanaAPIServerEnsureKubectlAccess?: boolean; featureToggleAdminPage?: boolean; awsAsyncQueryCaching?: boolean; splitScopes?: boolean; - azureMonitorDataplane?: boolean; + traceToProfiles?: boolean; + tracesEmbeddedFlameGraph?: boolean; permissionsFilterRemoveSubquery?: boolean; prometheusConfigOverhaulAuth?: boolean; configurableSchedulerTick?: boolean; @@ -120,14 +119,12 @@ export interface FeatureToggles { angularDeprecationUI?: boolean; dashgpt?: boolean; reportingRetries?: boolean; - newBrowseDashboards?: boolean; sseGroupByDatasource?: boolean; requestInstrumentationStatusSource?: boolean; libraryPanelRBAC?: boolean; lokiRunQueriesInParallel?: boolean; wargamesTesting?: boolean; alertingInsights?: boolean; - alertingContactPointsV2?: boolean; externalCorePlugins?: boolean; pluginsAPIMetrics?: boolean; httpSLOLevels?: boolean; @@ -139,9 +136,10 @@ export interface FeatureToggles { formatString?: boolean; transformationsVariableSupport?: boolean; kubernetesPlaylists?: boolean; + kubernetesSnapshots?: boolean; cloudWatchBatchQueries?: boolean; - navAdminSubsections?: boolean; recoveryThreshold?: boolean; + lokiStructuredMetadata?: boolean; teamHttpHeaders?: boolean; awsDatasourcesNewFormStyling?: boolean; cachingOptimizeSerializationMemoryUsage?: boolean; @@ -150,8 +148,26 @@ export interface FeatureToggles { costManagementUi?: boolean; managedPluginsInstall?: boolean; prometheusPromQAIL?: boolean; + addFieldFromCalculationStatFunctions?: boolean; alertmanagerRemoteSecondary?: boolean; alertmanagerRemotePrimary?: boolean; alertmanagerRemoteOnly?: boolean; annotationPermissionUpdate?: boolean; + extractFieldsNameDeduplication?: boolean; + dashboardSceneForViewers?: boolean; + dashboardScene?: boolean; + panelFilterVariable?: boolean; + pdfTables?: boolean; + ssoSettingsApi?: boolean; + logsInfiniteScrolling?: boolean; + flameGraphItemCollapsing?: boolean; + alertingDetailsViewV2?: boolean; + datatrails?: boolean; + alertingSimplifiedRouting?: boolean; + logRowsPopoverMenu?: boolean; + pluginsSkipHostEnvVars?: boolean; + tableSharedCrosshair?: boolean; + regressionTransformation?: boolean; + displayAnonymousStats?: boolean; + alertStateHistoryAnnotationsFromLoki?: boolean; } diff --git a/packages/grafana-data/src/types/fieldOverrides.ts b/packages/grafana-data/src/types/fieldOverrides.ts index 8a3a9bf15d09e..dad3547523c42 100644 --- a/packages/grafana-data/src/types/fieldOverrides.ts +++ b/packages/grafana-data/src/types/fieldOverrides.ts @@ -73,18 +73,12 @@ export interface FieldOverrideContext extends StandardEditorContext { field?: Field; dataFrameIndex?: number; // The index for the selected field frame } -export interface FieldConfigEditorProps - extends Omit, 'item'> { - item: FieldConfigPropertyItem; // The property info - value: TValue; - context: FieldOverrideContext; - onChange: (value?: TValue) => void; -} -export interface FieldOverrideEditorProps extends Omit, 'item'> { - item: FieldConfigPropertyItem; - context: FieldOverrideContext; -} +/** @deprecated Use StandardEditorProps instead */ +export type FieldConfigEditorProps = StandardEditorProps; + +/** @deprecated Use StandardEditorProps instead */ +export type FieldOverrideEditorProps = StandardEditorProps; export interface FieldConfigEditorConfig extends OptionEditorConfig { @@ -102,9 +96,9 @@ export interface FieldConfigEditorConfig - extends OptionsEditorItem, TValue> { + extends OptionsEditorItem, TValue> { // An editor that can be filled in with context info (template variables etc) - override: ComponentType>; + override: ComponentType>; /** true for plugin field config properties */ isCustom?: boolean; diff --git a/packages/grafana-data/src/types/icon.ts b/packages/grafana-data/src/types/icon.ts index b75521182dba6..c1889cf1b6ff4 100644 --- a/packages/grafana-data/src/types/icon.ts +++ b/packages/grafana-data/src/types/icon.ts @@ -21,6 +21,7 @@ export const availableIconsIndex = { 'angle-up': true, 'align-left': true, 'align-right': true, + 'application-observability': true, apps: true, arrow: true, 'arrow-down': true, @@ -110,6 +111,7 @@ export const availableIconsIndex = { 'folder-plus': true, 'folder-upload': true, forward: true, + 'frontend-observability': true, 'gf-bar-alignment-after': true, 'gf-bar-alignment-before': true, 'gf-bar-alignment-center': true, diff --git a/packages/grafana-data/src/types/index.ts b/packages/grafana-data/src/types/index.ts index 96f3c8f7d3941..5ee1e8971a4e3 100644 --- a/packages/grafana-data/src/types/index.ts +++ b/packages/grafana-data/src/types/index.ts @@ -63,5 +63,6 @@ export { type PluginExtensionEventHelpers, type PluginExtensionPanelContext, type PluginExtensionDataSourceConfigContext, + type PluginExtensionCommandPaletteContext, type PluginExtensionOpenModalOptions, } from './pluginExtensions'; diff --git a/packages/grafana-data/src/types/logs.ts b/packages/grafana-data/src/types/logs.ts index ad9ef4a59316f..3518fa7844320 100644 --- a/packages/grafana-data/src/types/logs.ts +++ b/packages/grafana-data/src/types/logs.ts @@ -4,7 +4,7 @@ import { DataQuery } from '@grafana/schema'; import { KeyValue, Labels } from './data'; import { DataFrame } from './dataFrame'; -import { DataQueryRequest, DataQueryResponse } from './datasource'; +import { DataQueryRequest, DataQueryResponse, QueryFixAction, QueryFixType } from './datasource'; import { AbsoluteTimeRange } from './time'; export { LogsDedupStrategy, LogsSortOrder } from '@grafana/schema'; @@ -153,7 +153,7 @@ export interface DataSourceWithLogsContextSupport { - if (!datasource) { + if (!datasource || typeof datasource !== 'object') { return false; } @@ -253,7 +253,7 @@ export const hasSupplementaryQuerySupport = ( }; export const hasLogsContextUiSupport = (datasource: unknown): datasource is DataSourceWithLogsContextSupport => { - if (!datasource) { + if (!datasource || typeof datasource !== 'object') { return false; } @@ -264,6 +264,7 @@ export interface QueryFilterOptions extends KeyValue {} export interface ToggleFilterAction { type: 'FILTER_FOR' | 'FILTER_OUT'; options: QueryFilterOptions; + frame?: DataFrame; } /** * Data sources that support toggleable filters through `toggleQueryFilter`, and displaying the active @@ -292,9 +293,46 @@ export const hasToggleableQueryFiltersSupport = ( datasource: unknown ): datasource is DataSourceWithToggleableQueryFiltersSupport => { return ( - datasource !== null && + datasource != null && typeof datasource === 'object' && 'toggleQueryFilter' in datasource && 'queryHasFilter' in datasource ); }; + +/** + * Data sources that support query modification actions from Log Details (ADD_FILTER, ADD_FILTER_OUT), + * and Popover Menu (ADD_STRING_FILTER, ADD_STRING_FILTER_OUT) in Explore. + * @internal + * @alpha + */ +export interface DataSourceWithQueryModificationSupport { + /** + * Given a query, applies a query modification `action`, returning the updated query. + * Explore currently supports the following action types: + * - ADD_FILTER: adds a filter to the query. + * - ADD_FILTER_OUT: adds a negative filter to the query. + * - ADD_STRING_FILTER: adds a string filter to the query. + * - ADD_STRING_FILTER_OUT: adds a negative string filter to the query. + */ + modifyQuery(query: TQuery, action: QueryFixAction): TQuery; + + /** + * Returns a list of supported action types for `modifyQuery()`. + */ + getSupportedQueryModifications(): Array; +} + +/** + * @internal + */ +export const hasQueryModificationSupport = ( + datasource: unknown +): datasource is DataSourceWithQueryModificationSupport => { + return ( + datasource != null && + typeof datasource === 'object' && + 'modifyQuery' in datasource && + 'getSupportedQueryModifications' in datasource + ); +}; diff --git a/packages/grafana-data/src/types/navModel.ts b/packages/grafana-data/src/types/navModel.ts index c20ea94656ce4..0f6acfe430aee 100644 --- a/packages/grafana-data/src/types/navModel.ts +++ b/packages/grafana-data/src/types/navModel.ts @@ -34,6 +34,7 @@ export interface NavModelItem extends NavLinkDTO { parentItem?: NavModelItem; onClick?: () => void; tabSuffix?: ComponentType<{ className?: string }>; + tabCounter?: number; hideFromBreadcrumbs?: boolean; emptyMessage?: string; } diff --git a/packages/grafana-data/src/types/panel.ts b/packages/grafana-data/src/types/panel.ts index 0dd43826f6a64..00baaae768642 100644 --- a/packages/grafana-data/src/types/panel.ts +++ b/packages/grafana-data/src/types/panel.ts @@ -72,10 +72,10 @@ export interface PanelData { } export interface PanelProps { - /** ID of the panel within the current dashboard */ + /** Unique ID of the panel within the current dashboard */ id: number; - /** Result set of panel queries */ + /** Data available as result of running panel queries, includes dataframes and loading state **/ data: PanelData; /** Time range of the current dashboard */ @@ -84,19 +84,19 @@ export interface PanelProps { /** Time zone of the current dashboard */ timeZone: TimeZone; - /** Panel options */ + /** Panel options set by the user in the panel editor. Includes both default and custom panel options */ options: T; /** Indicates whether or not panel should be rendered transparent */ transparent: boolean; - /** Current width of the panel */ + /** Current width of the panel in pixels */ width: number; - /** Current height of the panel */ + /** Current height of the panel in pixels */ height: number; - /** Field options configuration */ + /** Field options configuration. Controls how field values are displayed (e.g., units, min, max, decimals, thresholds) */ fieldConfig: FieldConfigSource; /** @internal */ @@ -105,16 +105,16 @@ export interface PanelProps { /** Panel title */ title: string; - /** EventBus */ + /** Grafana EventBus */ eventBus: EventBus; - /** Panel options change handler */ + /** Handler for options change. Invoke it to update the panel custom options. */ onOptionsChange: (options: T) => void; - /** Field config change handler */ + /** Field config change handler. Invoke it to update the panel field config. */ onFieldConfigChange: (config: FieldConfigSource) => void; - /** Template variables interpolation function */ + /** Template variables interpolation function. Given a string containing template variables, it returns the string with interpolated values. */ replaceVariables: InterpolateFunction; /** Time range change handler */ diff --git a/packages/grafana-data/src/types/plugin.ts b/packages/grafana-data/src/types/plugin.ts index a0869666a4583..7d07e91f0189d 100644 --- a/packages/grafana-data/src/types/plugin.ts +++ b/packages/grafana-data/src/types/plugin.ts @@ -52,6 +52,11 @@ export interface PluginError { pluginType?: PluginType; } +export interface AngularMeta { + detected: boolean; + hideDeprecation: boolean; +} + export interface PluginMeta { id: string; name: string; @@ -82,7 +87,7 @@ export interface PluginMeta { signatureType?: PluginSignatureType; signatureOrg?: string; live?: boolean; - angularDetected?: boolean; + angular?: AngularMeta; } interface PluginDependencyInfo { @@ -198,7 +203,7 @@ export class GrafanaPlugin { /** * @deprecated -- this is no longer necessary and will be removed */ - setChannelSupport(support: any) { + setChannelSupport() { console.warn('[deprecation] plugin is using ignored option: setChannelSupport', this.meta); return this; } diff --git a/packages/grafana-data/src/types/pluginExtensions.ts b/packages/grafana-data/src/types/pluginExtensions.ts index f541c56f571cd..68fa3c7d1d889 100644 --- a/packages/grafana-data/src/types/pluginExtensions.ts +++ b/packages/grafana-data/src/types/pluginExtensions.ts @@ -117,9 +117,12 @@ export type PluginExtensionEventHelpers = { // Extension Points available in core Grafana export enum PluginExtensionPoints { + AlertInstanceAction = 'grafana/alerting/instance/action', + CommandPalette = 'grafana/commandpalette/action', DashboardPanelMenu = 'grafana/dashboard/panel/menu', DataSourceConfig = 'grafana/datasources/config', ExploreToolbarAction = 'grafana/explore/toolbar/action', + UserProfileTab = 'grafana/user/profile/tab', } export type PluginExtensionPanelContext = { @@ -152,6 +155,8 @@ export type PluginExtensionDataSourceConfigContext void; }; +export type PluginExtensionCommandPaletteContext = {}; + type Dashboard = { uid: string; title: string; diff --git a/packages/grafana-data/src/types/query.ts b/packages/grafana-data/src/types/query.ts index f335755a8cda1..30579b1e7dcfb 100644 --- a/packages/grafana-data/src/types/query.ts +++ b/packages/grafana-data/src/types/query.ts @@ -17,6 +17,7 @@ export interface DataSourceRef extends SchemaDataSourceRef {} */ export enum DataTopic { Annotations = 'annotations', + AlertStates = 'alertStates', } /** @@ -66,9 +67,10 @@ export interface DataSourceWithQueryExportSupport( datasource: unknown ): datasource is DataSourceWithQueryImportSupport => { - if (!datasource) { + if (!datasource || typeof datasource !== 'object') { return false; } + return 'importFromAbstractQueries' in datasource; }; @@ -78,7 +80,7 @@ export const hasQueryImportSupport = ( export const hasQueryExportSupport = ( datasource: unknown ): datasource is DataSourceWithQueryExportSupport => { - if (!datasource) { + if (!datasource || typeof datasource !== 'object') { return false; } return 'exportToAbstractQueries' in datasource; diff --git a/packages/grafana-data/src/types/templateVars.ts b/packages/grafana-data/src/types/templateVars.ts index d16daed9ea419..86d5c50594d61 100644 --- a/packages/grafana-data/src/types/templateVars.ts +++ b/packages/grafana-data/src/types/templateVars.ts @@ -36,6 +36,8 @@ export enum VariableSort { numericalDesc, alphabeticalCaseInsensitiveAsc, alphabeticalCaseInsensitiveDesc, + naturalAsc, + naturalDesc, } export enum VariableHide { diff --git a/packages/grafana-data/src/types/variables.ts b/packages/grafana-data/src/types/variables.ts index 8fbc7507db1cd..58f9fd5e23240 100644 --- a/packages/grafana-data/src/types/variables.ts +++ b/packages/grafana-data/src/types/variables.ts @@ -14,8 +14,6 @@ import { DataQuery } from './query'; /** * Enum with the different variable support types - * - * @alpha -- experimental */ export enum VariableSupportType { Legacy = 'legacy', @@ -26,8 +24,6 @@ export enum VariableSupportType { /** * Base class for VariableSupport classes - * - * @alpha -- experimental */ export abstract class VariableSupportBase< DSType extends DataSourceApi, @@ -44,8 +40,6 @@ export abstract class VariableSupportBase< /** * Extend this class in a data source plugin to use the standard query editor for Query variables - * - * @alpha -- experimental */ export abstract class StandardVariableSupport< DSType extends DataSourceApi, @@ -62,8 +56,6 @@ export abstract class StandardVariableSupport< /** * Extend this class in a data source plugin to use a customized query editor for Query variables - * - * @alpha -- experimental */ export abstract class CustomVariableSupport< DSType extends DataSourceApi, @@ -89,8 +81,6 @@ export abstract class CustomVariableSupport< /** * Extend this class in a data source plugin to use the query editor in the data source plugin for Query variables - * - * @alpha -- experimental */ export abstract class DataSourceVariableSupport< DSType extends DataSourceApi, @@ -104,8 +94,6 @@ export abstract class DataSourceVariableSupport< /** * Defines the standard DatQuery used by data source plugins that implement StandardVariableSupport - * - * @alpha -- experimental */ export interface StandardVariableQuery extends DataQuery { query: string; diff --git a/packages/grafana-data/src/utils/OptionsUIBuilders.ts b/packages/grafana-data/src/utils/OptionsUIBuilders.ts index e86b7683ad5c4..0743f1008e10f 100644 --- a/packages/grafana-data/src/utils/OptionsUIBuilders.ts +++ b/packages/grafana-data/src/utils/OptionsUIBuilders.ts @@ -16,8 +16,9 @@ import { StandardEditorContext, } from '../field'; import { PanelOptionsSupplier } from '../panel/PanelPlugin'; +import { isObject } from '../types'; import { OptionsEditorItem, OptionsUIRegistryBuilder } from '../types/OptionsUIRegistryBuilder'; -import { FieldConfigEditorProps, FieldConfigPropertyItem, FieldConfigEditorConfig } from '../types/fieldOverrides'; +import { FieldConfigPropertyItem, FieldConfigEditorConfig } from '../types/fieldOverrides'; import { PanelOptionsEditorConfig, PanelOptionsEditorItem } from '../types/panel'; /** @@ -25,15 +26,15 @@ import { PanelOptionsEditorConfig, PanelOptionsEditorItem } from '../types/panel */ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder< TOptions, - FieldConfigEditorProps, + StandardEditorProps, FieldConfigPropertyItem > { addNumberInput(config: FieldConfigEditorConfig) { return this.addCustomEditor({ ...config, id: config.path, - override: standardEditorsRegistry.get('number').editor as any, - editor: standardEditorsRegistry.get('number').editor as any, + override: standardEditorsRegistry.get('number').editor, + editor: standardEditorsRegistry.get('number').editor, process: numberOverrideProcessor, shouldApply: config.shouldApply ?? (() => true), settings: config.settings || {}, @@ -44,8 +45,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - override: standardEditorsRegistry.get('slider').editor as any, - editor: standardEditorsRegistry.get('slider').editor as any, + override: standardEditorsRegistry.get('slider').editor, + editor: standardEditorsRegistry.get('slider').editor, process: numberOverrideProcessor, shouldApply: config.shouldApply ?? (() => true), settings: config.settings || {}, @@ -56,8 +57,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - override: standardEditorsRegistry.get('text').editor as any, - editor: standardEditorsRegistry.get('text').editor as any, + override: standardEditorsRegistry.get('text').editor, + editor: standardEditorsRegistry.get('text').editor, process: stringOverrideProcessor, shouldApply: config.shouldApply ?? (() => true), settings: config.settings || {}, @@ -70,8 +71,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - override: standardEditorsRegistry.get('select').editor as any, - editor: standardEditorsRegistry.get('select').editor as any, + override: standardEditorsRegistry.get('select').editor, + editor: standardEditorsRegistry.get('select').editor, process: selectOverrideProcessor, // ??? shouldApply: config.shouldApply ? config.shouldApply : () => true, @@ -83,8 +84,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - override: standardEditorsRegistry.get('radio').editor as any, - editor: standardEditorsRegistry.get('radio').editor as any, + override: standardEditorsRegistry.get('radio').editor, + editor: standardEditorsRegistry.get('radio').editor, process: selectOverrideProcessor, // ??? shouldApply: config.shouldApply ? config.shouldApply : () => true, @@ -96,8 +97,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('boolean').editor as any, - override: standardEditorsRegistry.get('boolean').editor as any, + editor: standardEditorsRegistry.get('boolean').editor, + override: standardEditorsRegistry.get('boolean').editor, process: booleanOverrideProcessor, shouldApply: config.shouldApply ? config.shouldApply : () => true, settings: config.settings || {}, @@ -108,8 +109,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('color').editor as any, - override: standardEditorsRegistry.get('color').editor as any, + editor: standardEditorsRegistry.get('color').editor, + override: standardEditorsRegistry.get('color').editor, process: identityOverrideProcessor, shouldApply: config.shouldApply ? config.shouldApply : () => true, settings: config.settings || {}, @@ -122,8 +123,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('unit').editor as any, - override: standardEditorsRegistry.get('unit').editor as any, + editor: standardEditorsRegistry.get('unit').editor, + override: standardEditorsRegistry.get('unit').editor, process: unitOverrideProcessor, shouldApply: config.shouldApply ? config.shouldApply : () => true, settings: config.settings || {}, @@ -136,8 +137,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('field-name').editor as any, - override: standardEditorsRegistry.get('field-name').editor as any, + editor: standardEditorsRegistry.get('field-name').editor, + override: standardEditorsRegistry.get('field-name').editor, process: identityOverrideProcessor, shouldApply: config.shouldApply ? config.shouldApply : () => true, settings: config.settings || {}, @@ -151,8 +152,8 @@ export class FieldConfigEditorBuilder extends OptionsUIRegistryBuilder return this.addCustomEditor({ ...config, id: config.path, - editor: editor as any, - override: editor as any, + editor: editor, + override: editor, process: identityOverrideProcessor, shouldApply: config.shouldApply ? config.shouldApply : () => true, settings: config.settings || {}, @@ -204,8 +205,8 @@ export class NestedPanelOptionsBuilder implements OptionsEditorItem< }; } -export function isNestedPanelOptions(item: any): item is NestedPanelOptionsBuilder { - return item.id === 'nested-panel-options'; +export function isNestedPanelOptions(item: unknown): item is NestedPanelOptionsBuilder { + return isObject(item) && 'id' in item && item.id === 'nested-panel-options'; } /** @@ -225,7 +226,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('number').editor as any, + editor: standardEditorsRegistry.get('number').editor, }); } @@ -233,7 +234,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('slider').editor as any, + editor: standardEditorsRegistry.get('slider').editor, }); } @@ -241,7 +242,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('text').editor as any, + editor: standardEditorsRegistry.get('text').editor, }); } @@ -251,7 +252,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('strings').editor as any, + editor: standardEditorsRegistry.get('strings').editor, }); } @@ -261,7 +262,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('select').editor as any, + editor: standardEditorsRegistry.get('select').editor, }); } @@ -271,7 +272,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('multi-select').editor as any, + editor: standardEditorsRegistry.get('multi-select').editor, }); } @@ -281,7 +282,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('radio').editor as any, + editor: standardEditorsRegistry.get('radio').editor, }); } @@ -289,7 +290,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('boolean').editor as any, + editor: standardEditorsRegistry.get('boolean').editor, }); } @@ -297,7 +298,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('color').editor as any, + editor: standardEditorsRegistry.get('color').editor, settings: config.settings || {}, }); } @@ -306,7 +307,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('timezone').editor as any, + editor: standardEditorsRegistry.get('timezone').editor, settings: config.settings || {}, }); } @@ -317,7 +318,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('unit').editor as any, + editor: standardEditorsRegistry.get('unit').editor, }); } @@ -327,7 +328,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('field-name').editor as any, + editor: standardEditorsRegistry.get('field-name').editor, }); } @@ -337,7 +338,7 @@ export class PanelOptionsEditorBuilder extends OptionsUIRegistryBuilde return this.addCustomEditor({ ...config, id: config.path, - editor: standardEditorsRegistry.get('dashboard-uid').editor as any, // added at runtime + editor: standardEditorsRegistry.get('dashboard-uid').editor, // added at runtime }); } } diff --git a/packages/grafana-data/src/utils/datasource.ts b/packages/grafana-data/src/utils/datasource.ts index 42f8811cce9f0..19d7971986a6d 100644 --- a/packages/grafana-data/src/utils/datasource.ts +++ b/packages/grafana-data/src/utils/datasource.ts @@ -94,7 +94,7 @@ export const onUpdateDatasourceResetOption = export function updateDatasourcePluginOption( props: DataSourcePluginOptionsEditorProps, key: keyof DataSourceSettings, - val: any + val: unknown ) { const config = props.options; @@ -107,7 +107,7 @@ export function updateDatasourcePluginOption( props: DataSourcePluginOptionsEditorProps, key: K, - val: any + val: unknown ) => { const config = props.options; @@ -123,7 +123,7 @@ export const updateDatasourcePluginJsonDataOption = ( props: DataSourcePluginOptionsEditorProps, key: string, - val: any + val: unknown ) => { const config = props.options; diff --git a/packages/grafana-data/src/utils/fieldParser.ts b/packages/grafana-data/src/utils/fieldParser.ts index fd1b07ec519bf..c6ab0183be186 100644 --- a/packages/grafana-data/src/utils/fieldParser.ts +++ b/packages/grafana-data/src/utils/fieldParser.ts @@ -1,7 +1,7 @@ import { guessFieldTypeFromValue } from '../dataframe/processDataFrame'; import { Field, FieldType } from '../types/dataFrame'; -export function makeFieldParser(value: unknown, field: Field): (value: string) => any { +export function makeFieldParser(value: unknown, field: Field) { if (!field.type) { if (field.name === 'time' || field.name === 'Time') { field.type = FieldType.time; diff --git a/packages/grafana-data/src/utils/index.ts b/packages/grafana-data/src/utils/index.ts index 41909d9b64f6b..e56ef12c01014 100644 --- a/packages/grafana-data/src/utils/index.ts +++ b/packages/grafana-data/src/utils/index.ts @@ -26,3 +26,4 @@ export { withLoadingIndicator, type WithLoadingIndicatorOptions } from './withLo export { convertOldAngularValueMappings, LegacyMappingType } from './valueMappings'; export { containsSearchFilter, type SearchFilterOptions, getSearchFilterScopedVar } from './variables'; export { renderLegendFormat } from './legend'; +export { matchPluginId } from './matchPluginId'; diff --git a/packages/grafana-data/src/utils/location.ts b/packages/grafana-data/src/utils/location.ts index 7897e860c5209..44d42f247a5ce 100644 --- a/packages/grafana-data/src/utils/location.ts +++ b/packages/grafana-data/src/utils/location.ts @@ -69,7 +69,7 @@ const assureBaseUrl = (url: string): string => { * @param searchParamsToUpdate * @returns */ -const getUrlForPartial = (location: Location, searchParamsToUpdate: Record) => { +const getUrlForPartial = (location: Location, searchParamsToUpdate: UrlQueryMap) => { const searchParams = urlUtil.parseKeyValue( location.search.startsWith('?') ? location.search.substring(1) : location.search ); diff --git a/packages/grafana-data/src/utils/matchPluginId.ts b/packages/grafana-data/src/utils/matchPluginId.ts new file mode 100644 index 0000000000000..d21a0654215c1 --- /dev/null +++ b/packages/grafana-data/src/utils/matchPluginId.ts @@ -0,0 +1,13 @@ +import { PluginMeta } from '../types'; + +export function matchPluginId(idToMatch: string, pluginMeta: PluginMeta) { + if (pluginMeta.id === idToMatch) { + return true; + } + + if (pluginMeta.aliasIDs) { + return pluginMeta.aliasIDs.includes(idToMatch); + } + + return false; +} diff --git a/packages/grafana-data/src/utils/url.test.ts b/packages/grafana-data/src/utils/url.test.ts index b486564587f52..58e2073359312 100644 --- a/packages/grafana-data/src/utils/url.test.ts +++ b/packages/grafana-data/src/utils/url.test.ts @@ -33,6 +33,36 @@ describe('toUrlParams', () => { }); expect(url).toBe('datasource=testDs%5B%21%27%28%29%2A%5D'); }); + it('should encode object properties as url parameters', () => { + const params = urlUtil.serializeParams({ + server: 'backend-01', + hasSpace: 'has space', + many: ['1', '2', '3'], + true: true, + number: 20, + isNull: null, + isUndefined: undefined, + oneMore: false, + }); + expect(params).toBe( + 'server=backend-01&hasSpace=has%20space&many=1&many=2&many=3&true&number=20&isNull=&isUndefined=&oneMore=false' + ); + }); + + it('should not encode special character the same way as angular js', () => { + const params = urlUtil.serializeParams({ + server: ':@', + }); + expect(params).not.toBe('server=:@'); + }); + + it('should keep booleans', () => { + const url = urlUtil.serializeParams({ + bool1: true, + bool2: false, + }); + expect(url).toBe('bool1&bool2=false'); + }); }); describe('parseKeyValue', () => { diff --git a/packages/grafana-data/src/utils/url.ts b/packages/grafana-data/src/utils/url.ts index f3f6449e0d44d..2ee35d9f449bb 100644 --- a/packages/grafana-data/src/utils/url.ts +++ b/packages/grafana-data/src/utils/url.ts @@ -27,7 +27,7 @@ function renderUrl(path: string, query: UrlQueryMap | undefined): string { return path; } -function encodeURIComponentAsAngularJS(val: string, pctEncodeSpaces?: boolean) { +function encodeURIComponentAsAngularJS(val: EncodeURIComponentParams, pctEncodeSpaces?: boolean) { return encodeURIComponent(val) .replace(/%40/gi, '@') .replace(/%3A/gi, ':') @@ -40,21 +40,31 @@ function encodeURIComponentAsAngularJS(val: string, pctEncodeSpaces?: boolean) { }); } -function toUrlParams(a: any) { +type EncodeURIComponentParams = Parameters[0]; +/** + * Encodes URL parameters in the style of AngularJS. + * Use `serializeParams` to encode parameters using `encodeURIComponent` instead. + */ +function toUrlParams(a: any, encodeAsAngularJS = true) { const s: any[] = []; const rbracket = /\[\]$/; - const isArray = (obj: any) => { + const encodingFunction = encodeAsAngularJS + ? (value: EncodeURIComponentParams, pctEncodeSpaces?: boolean) => + encodeURIComponentAsAngularJS(value, pctEncodeSpaces) + : (value: EncodeURIComponentParams, _: boolean) => encodeURIComponent(value); + + const isArray = (obj: unknown) => { return Object.prototype.toString.call(obj) === '[object Array]'; }; const add = (k: string, v: any) => { v = typeof v === 'function' ? v() : v === null ? '' : v === undefined ? '' : v; if (typeof v !== 'boolean') { - s[s.length] = encodeURIComponentAsAngularJS(k, true) + '=' + encodeURIComponentAsAngularJS(v, true); + s[s.length] = encodingFunction(k, true) + '=' + encodingFunction(v, true); } else { - const valueQueryPart = v ? '' : '=' + encodeURIComponentAsAngularJS('false', true); - s[s.length] = encodeURIComponentAsAngularJS(k, true) + valueQueryPart; + const valueQueryPart = v ? '' : '=' + encodingFunction('false', true); + s[s.length] = encodingFunction(k, true) + valueQueryPart; } }; @@ -92,6 +102,16 @@ function toUrlParams(a: any) { return buildParams('', a).join('&'); } +/** + * Converts params into a URL-encoded query string. + * + * @param params data to serialize + * @returns A URL-encoded string representing the provided data. + */ +function serializeParams(params: unknown): string { + return toUrlParams(params, false); +} + function appendQueryToUrl(url: string, stringToAppend: string) { if (stringToAppend !== undefined && stringToAppend !== null && stringToAppend !== '') { const pos = url.indexOf('?'); @@ -198,6 +218,7 @@ export const urlUtil = { appendQueryToUrl, getUrlSearchParams, parseKeyValue, + serializeParams, }; /** diff --git a/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts b/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts index d61beabce0d21..8537fed6c6be4 100644 --- a/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts +++ b/packages/grafana-data/src/valueFormats/dateTimeFormatters.test.ts @@ -350,19 +350,25 @@ describe('to nanoseconds', () => { it('should correctly display as minutes', () => { const eightMinutes = toNanoSeconds(480000000000); expect(eightMinutes.text).toBe('8'); + expect(eightMinutes.suffix).toBe(' mins'); + }); + + it('should correctly display as minute', () => { + const eightMinutes = toNanoSeconds(60000000000); + expect(eightMinutes.text).toBe('1'); expect(eightMinutes.suffix).toBe(' min'); }); it('should correctly display as hours', () => { const nineHours = toNanoSeconds(32400000000000); expect(nineHours.text).toBe('9'); - expect(nineHours.suffix).toBe(' hour'); + expect(nineHours.suffix).toBe(' hours'); }); it('should correctly display as days', () => { const tenDays = toNanoSeconds(864000000000000); expect(tenDays.text).toBe('10'); - expect(tenDays.suffix).toBe(' day'); + expect(tenDays.suffix).toBe(' days'); }); }); diff --git a/packages/grafana-data/src/valueFormats/valueFormats.test.ts b/packages/grafana-data/src/valueFormats/valueFormats.test.ts index 2b2e8d0ed63ac..b0776ae4b4103 100644 --- a/packages/grafana-data/src/valueFormats/valueFormats.test.ts +++ b/packages/grafana-data/src/valueFormats/valueFormats.test.ts @@ -25,7 +25,8 @@ describe('valueFormats', () => { ${'ms'} | ${4} | ${0.0024} | ${'0.0024 ms'} ${'ms'} | ${0} | ${100} | ${'100 ms'} ${'ms'} | ${2} | ${1250} | ${'1.25 s'} - ${'ms'} | ${1} | ${10000086.123} | ${'2.8 hour'} + ${'ms'} | ${1} | ${10000086.123} | ${'2.8 hours'} + ${'ms'} | ${1} | ${-10000086.123} | ${'-2.8 hours'} ${'ms'} | ${undefined} | ${1000} | ${'1 s'} ${'ms'} | ${0} | ${1200} | ${'1 s'} ${'short'} | ${undefined} | ${1000} | ${'1 K'} @@ -69,8 +70,9 @@ describe('valueFormats', () => { ${'dateTimeAsUS'} | ${0} | ${dateTime(new Date(2010, 6, 2)).valueOf()} | ${'07/02/2010 12:00:00 am'} ${'dateTimeAsSystem'} | ${0} | ${dateTime(new Date(2010, 6, 2)).valueOf()} | ${'2010-07-02 00:00:00'} ${'dtdurationms'} | ${undefined} | ${100000} | ${'1 minute'} + ${'dtdurationms'} | ${undefined} | ${150000} | ${'2 minutes'} `( - 'With format=$format decimals=$decimals and value=$value then result shoudl be = $expected', + 'With format=$format decimals=$decimals and value=$value then result should be = $expected', async ({ format, value, decimals, expected }) => { const result = getValueFormat(format)(value, decimals, undefined, undefined); const full = formattedValueToString(result); diff --git a/packages/grafana-data/src/valueFormats/valueFormats.ts b/packages/grafana-data/src/valueFormats/valueFormats.ts index f8753bad0e20f..e4d99adcc91b0 100644 --- a/packages/grafana-data/src/valueFormats/valueFormats.ts +++ b/packages/grafana-data/src/valueFormats/valueFormats.ts @@ -102,10 +102,27 @@ function getDecimalsForValue(value: number): number { export function toFixedScaled(value: number, decimals: DecimalCount, ext?: string): FormattedValue { return { text: toFixed(value, decimals), - suffix: ext, + suffix: appendPluralIf(ext, Math.abs(value) > 1), }; } +function appendPluralIf(ext: string | undefined, condition: boolean): string | undefined { + if (!condition) { + return ext; + } + + switch (ext) { + case ' min': + case ' hour': + case ' day': + case ' week': + case ' year': + return `${ext}s`; + default: + return ext; + } +} + export function toFixedUnit(unit: string, asPrefix?: boolean): ValueFormatter { return (size: number, decimals?: DecimalCount) => { if (size === null) { diff --git a/packages/grafana-data/src/vector/CircularVector.ts b/packages/grafana-data/src/vector/CircularVector.ts index aa70ae27578d0..fa3bd2503a8a2 100644 --- a/packages/grafana-data/src/vector/CircularVector.ts +++ b/packages/grafana-data/src/vector/CircularVector.ts @@ -122,7 +122,7 @@ export class CircularVector extends FunctionalVector { return this.buffer[(index + this.index) % this.buffer.length]; } - set(index: number, value: any) { + set(index: number, value: T) { this.buffer[(index + this.index) % this.buffer.length] = value; } diff --git a/packages/grafana-data/src/vector/FunctionalVector.ts b/packages/grafana-data/src/vector/FunctionalVector.ts index 62782fe718fa0..5c2984c4b7234 100644 --- a/packages/grafana-data/src/vector/FunctionalVector.ts +++ b/packages/grafana-data/src/vector/FunctionalVector.ts @@ -18,7 +18,7 @@ export abstract class FunctionalVector implements Vector { } } - set(index: number, value: any): void { + set(index: number, value: T): void { throw 'unsupported operation'; } @@ -101,18 +101,8 @@ export abstract class FunctionalVector implements Vector { copyWithin(target: number, start: number, end?: number | undefined): this { throw new Error('Method not implemented.'); } - - [Symbol.unscopables](): { - copyWithin: boolean; - entries: boolean; - fill: boolean; - find: boolean; - findIndex: boolean; - keys: boolean; - values: boolean; - } { - throw new Error('Method not implemented.'); - } + // Object not implemented + [Symbol.unscopables] = {}; //-------------------------------------------------------------------------------- // Delegated Array function -- these will not be efficient :grimmice: diff --git a/packages/grafana-e2e-selectors/package.json b/packages/grafana-e2e-selectors/package.json index a14c3e70282ed..97046a3d053c0 100644 --- a/packages/grafana-e2e-selectors/package.json +++ b/packages/grafana-e2e-selectors/package.json @@ -41,7 +41,7 @@ "devDependencies": { "@rollup/plugin-commonjs": "25.0.2", "@rollup/plugin-node-resolve": "15.2.3", - "@types/node": "18.18.4", + "@types/node": "20.8.10", "esbuild": "0.18.12", "rimraf": "5.0.1", "rollup": "2.79.1", @@ -52,6 +52,6 @@ "dependencies": { "@grafana/tsconfig": "^1.2.0-rc1", "tslib": "2.6.0", - "typescript": "4.8.4" + "typescript": "5.2.2" } } diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts index d8599280e4e72..5814e805b3047 100644 --- a/packages/grafana-e2e-selectors/src/selectors/components.ts +++ b/packages/grafana-e2e-selectors/src/selectors/components.ts @@ -10,18 +10,22 @@ * @alpha */ export const Components = { + RadioButton: { + container: 'data-testid radio-button', + }, Breadcrumbs: { breadcrumb: (title: string) => `data-testid ${title} breadcrumb`, }, TimePicker: { openButton: 'data-testid TimePicker Open Button', - fromField: 'Time Range from field', - toField: 'Time Range to field', + overlayContent: 'data-testid TimePicker Overlay Content', + fromField: 'data-testid Time Range from field', + toField: 'data-testid Time Range to field', applyTimeRange: 'data-testid TimePicker submit button', calendar: { - label: 'Time Range calendar', - openButton: 'Open time range calendar', - closeButton: 'Close time range Calendar', + label: 'data-testid Time Range calendar', + openButton: 'data-testid Open time range calendar', + closeButton: 'data-testid Close time range Calendar', }, absoluteTimeRangeTitle: 'data-testid-absolute-time-range-narrow', }, @@ -31,6 +35,9 @@ export const Components = { rolePicker: 'Built-in role picker', permissionLevel: 'Permission Level', }, + DateTimePicker: { + input: 'data-testid date-time-input', + }, DataSource: { TestData: { QueryTab: { @@ -207,7 +214,7 @@ export const Components = { container: (refId: string) => `Query editor row ${refId}`, }, AlertTab: { - content: 'Alert editor tab content', + content: 'data-testid Alert editor tab content', }, Alert: { /** @@ -225,8 +232,8 @@ export const Components = { Transforms: { card: (name: string) => `data-testid New transform ${name}`, Reduce: { - modeLabel: 'Transform mode label', - calculationsLabel: 'Transform calculations label', + modeLabel: 'data-testid Transform mode label', + calculationsLabel: 'data-testid Transform calculations label', }, SpatialOperations: { actionLabel: 'root Action field property editor', @@ -249,7 +256,8 @@ export const Components = { }, }, }, - searchInput: 'search transformations', + searchInput: 'data-testid search transformations', + noTransformationsMessage: 'data-testid no transformations message', addTransformationButton: 'data-testid add transformation button', }, NavBar: { @@ -257,7 +265,7 @@ export const Components = { button: 'Configuration', }, Toggle: { - button: 'Toggle menu', + button: 'data-testid Toggle menu', }, Reporting: { button: 'Reporting', @@ -398,7 +406,7 @@ export const Components = { submit: 'data-testid-import-dashboard-submit', }, PanelAlertTabContent: { - content: 'Unified alert editor tab content', + content: 'data-testid Unified alert editor tab content', }, VisualizationPreview: { card: (name: string) => `data-testid suggestion-${name}`, @@ -414,6 +422,8 @@ export const Components = { preferencesSaveButton: 'data-testid-shared-prefs-save', orgsTable: 'data-testid-user-orgs-table', sessionsTable: 'data-testid-user-sessions-table', + extensionPointTabs: 'data-testid-extension-point-tabs', + extensionPointTab: (tabId: string) => `data-testid-extension-point-tab-${tabId}`, }, FileUpload: { inputField: 'data-testid-file-upload-input-field', diff --git a/packages/grafana-e2e-selectors/src/selectors/pages.ts b/packages/grafana-e2e-selectors/src/selectors/pages.ts index 65d92211882de..2ab4555591fbe 100644 --- a/packages/grafana-e2e-selectors/src/selectors/pages.ts +++ b/packages/grafana-e2e-selectors/src/selectors/pages.ts @@ -8,20 +8,20 @@ import { Components } from './components'; export const Pages = { Login: { url: '/login', - username: 'Username input field', - password: 'Password input field', - submit: 'Login button', - skip: 'Skip change password button', + username: 'data-testid Username input field', + password: 'data-testid Password input field', + submit: 'data-testid Login button', + skip: 'data-testid Skip change password button', }, Home: { url: '/', }, DataSource: { - name: 'Data source settings page name input field', + name: 'data-testid Data source settings page name input field', delete: 'Data source settings page Delete button', - readOnly: 'Data source settings page read only message', + readOnly: 'data-testid Data source settings page read only message', saveAndTest: 'data-testid Data source settings page Save and Test button', - alert: 'Data source settings page Alert', + alert: 'data-testid Data source settings page Alert', }, DataSources: { url: '/datasources', @@ -268,12 +268,12 @@ export const Pages = { page: 'Plugins list page', list: 'Plugins list', listItem: 'Plugins list item', - signatureErrorNotice: 'Unsigned plugins notice', + signatureErrorNotice: 'data-testid Unsigned plugins notice', }, PluginPage: { page: 'Plugin page', - signatureInfo: 'Plugin signature info', - disabledInfo: 'Plugin disabled info', + signatureInfo: 'data-testid Plugin signature info', + disabledInfo: 'data-testid Plugin disabled info', }, PlaylistForm: { name: 'Playlist name', @@ -310,6 +310,7 @@ export const Pages = { tabs: { allUsers: 'data-testid all-users-tab', orgUsers: 'data-testid org-users-tab', + anonUserDevices: 'data-testid anon-user-devices-tab', publicDashboardsUsers: 'data-testid public-dashboards-users-tab', users: 'data-testid users-tab', }, diff --git a/packages/grafana-e2e/package.json b/packages/grafana-e2e/package.json index 95aa26c950e4d..97e65cf358113 100644 --- a/packages/grafana-e2e/package.json +++ b/packages/grafana-e2e/package.json @@ -82,7 +82,7 @@ "tracelib": "1.0.1", "ts-loader": "8.4.0", "tslib": "2.6.0", - "typescript": "4.8.4", + "typescript": "5.2.2", "uuid": "9.0.0", "yaml": "^2.0.0" } diff --git a/packages/grafana-flamegraph/package.json b/packages/grafana-flamegraph/package.json index 146f201e65573..c41e2a11da3d8 100644 --- a/packages/grafana-flamegraph/package.json +++ b/packages/grafana-flamegraph/package.json @@ -46,7 +46,7 @@ "@emotion/css": "11.11.2", "@grafana/data": "10.3.0-pre", "@grafana/ui": "10.3.0-pre", - "@leeoniya/ufuzzy": "1.0.8", + "@leeoniya/ufuzzy": "1.0.13", "d3": "^7.8.5", "lodash": "4.17.21", "react": "18.2.0", @@ -79,7 +79,7 @@ "rollup-plugin-node-externals": "^5.0.0", "ts-jest": "29.1.1", "ts-node": "10.9.1", - "typescript": "4.8.4" + "typescript": "5.2.2" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0", diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.test.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.test.tsx index fc152e96b0087..93fb6b71eb370 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.test.tsx +++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.test.tsx @@ -25,7 +25,7 @@ jest.mock('react-use', () => { describe('FlameGraph', () => { function setup() { const flameGraphData = createDataFrame(data); - const container = new FlameGraphDataContainer(flameGraphData); + const container = new FlameGraphDataContainer(flameGraphData, { collapsing: true }); const setRangeMin = jest.fn(); const setRangeMax = jest.fn(); @@ -39,7 +39,6 @@ describe('FlameGraph', () => { data={container} rangeMin={0} rangeMax={1} - search={''} setRangeMin={setRangeMin} setRangeMax={setRangeMax} onItemFocused={onItemFocused} diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.tsx index 928654c66d7d3..6bd6bb1ab9fb4 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.tsx +++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraph.tsx @@ -17,7 +17,7 @@ // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF // THIS SOFTWARE. import { css, cx } from '@emotion/css'; -import React, { useMemo } from 'react'; +import React, { useEffect, useState } from 'react'; import { Icon } from '@grafana/ui'; @@ -26,13 +26,13 @@ import { ClickedItemData, ColorScheme, ColorSchemeDiff, TextAlign } from '../typ import FlameGraphCanvas from './FlameGraphCanvas'; import FlameGraphMetadata from './FlameGraphMetadata'; -import { FlameGraphDataContainer } from './dataTransform'; +import { CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform'; type Props = { data: FlameGraphDataContainer; rangeMin: number; rangeMax: number; - search: string; + matchedLabels?: Set; setRangeMin: (range: number) => void; setRangeMax: (range: number) => void; style?: React.CSSProperties; @@ -44,13 +44,15 @@ type Props = { onFocusPillClick: () => void; onSandwichPillClick: () => void; colorScheme: ColorScheme | ColorSchemeDiff; + showFlameGraphOnly?: boolean; + collapsing?: boolean; }; const FlameGraph = ({ data, rangeMin, rangeMax, - search, + matchedLabels, setRangeMin, setRangeMax, onItemFocused, @@ -61,31 +63,52 @@ const FlameGraph = ({ onFocusPillClick, onSandwichPillClick, colorScheme, + showFlameGraphOnly, + collapsing, }: Props) => { const styles = getStyles(); - const [levels, levelsCallers, totalProfileTicks, totalProfileTicksRight, totalViewTicks] = useMemo(() => { - let levels = data.getLevels(); - let totalProfileTicks = levels.length ? levels[0][0].value : 0; - let totalProfileTicksRight = levels.length ? levels[0][0].valueRight : undefined; - let totalViewTicks = totalProfileTicks; - let levelsCallers = undefined; - - if (sandwichItem) { - const [callers, callees] = data.getSandwichLevels(sandwichItem); - levels = callees; - levelsCallers = callers; - // We need this separate as in case of diff profile we want to compute diff colors based on the original ticks. - totalViewTicks = callees[0]?.[0]?.value ?? 0; + const [collapsedMap, setCollapsedMap] = useState(new Map()); + const [levels, setLevels] = useState(); + const [levelsCallers, setLevelsCallers] = useState(); + const [totalProfileTicks, setTotalProfileTicks] = useState(0); + const [totalProfileTicksRight, setTotalProfileTicksRight] = useState(); + const [totalViewTicks, setTotalViewTicks] = useState(0); + + useEffect(() => { + if (data) { + setCollapsedMap(data.getCollapsedMap()); + + let levels = data.getLevels(); + let totalProfileTicks = levels.length ? levels[0][0].value : 0; + let totalProfileTicksRight = levels.length ? levels[0][0].valueRight : undefined; + let totalViewTicks = totalProfileTicks; + let levelsCallers = undefined; + + if (sandwichItem) { + const [callers, callees] = data.getSandwichLevels(sandwichItem); + levels = callees; + levelsCallers = callers; + // We need this separate as in case of diff profile we want to compute diff colors based on the original ticks. + totalViewTicks = callees[0]?.[0]?.value ?? 0; + } + setLevels(levels); + setLevelsCallers(levelsCallers); + setTotalProfileTicks(totalProfileTicks); + setTotalProfileTicksRight(totalProfileTicksRight); + setTotalViewTicks(totalViewTicks); } - return [levels, levelsCallers, totalProfileTicks, totalProfileTicksRight, totalViewTicks]; }, [data, sandwichItem]); + if (!levels) { + return null; + } + const commonCanvasProps = { data, rangeMin, rangeMax, - search, + matchedLabels, setRangeMin, setRangeMax, onItemFocused, @@ -96,6 +119,10 @@ const FlameGraph = ({ totalProfileTicks, totalProfileTicksRight, totalViewTicks, + showFlameGraphOnly, + collapsedMap, + setCollapsedMap, + collapsing, }; const canvas = levelsCallers ? ( <> @@ -109,6 +136,8 @@ const FlameGraph = ({ root={levelsCallers[levelsCallers.length - 1][0]} depth={levelsCallers.length} direction={'parents'} + // We do not support collapsing in sandwich view for now. + collapsing={false} /> @@ -117,7 +146,13 @@ const FlameGraph = ({ Callees - + ) : ( @@ -143,7 +178,6 @@ const getStyles = () => ({ graph: css` label: graph; overflow: auto; - height: 100%; flex-grow: 1; flex-basis: 50%; `, diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphCanvas.test.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphCanvas.test.tsx new file mode 100644 index 0000000000000..17de2b8fdd54d --- /dev/null +++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphCanvas.test.tsx @@ -0,0 +1,40 @@ +import { convertPixelCoordinatesToBarCoordinates } from './FlameGraphCanvas'; +import { textToDataContainer } from './testHelpers'; + +describe('convertPixelCoordinatesToBarCoordinates', () => { + const container = textToDataContainer(` + [0///////////] + [1][3//][4///] + [2] [5///] + [6] + `)!; + const root = container.getLevels()[0][0]; + const testPosFn = (pos: { x: number; y: number }) => { + return convertPixelCoordinatesToBarCoordinates( + pos, + root, + 'children', + container.getLevels().length, + 1, + 14, + 0, + container.getCollapsedMap() + )!; + }; + + it('returns correct item', () => { + expect(testPosFn({ x: 4, y: 23 })!.itemIndexes[0]).toEqual(3); + }); + + it('returns no item when pointing to collapsed item', () => { + expect(testPosFn({ x: 1, y: 45 })).toBeUndefined(); + }); + + it('returns item when pointing to first collapsed item', () => { + expect(testPosFn({ x: 1, y: 23 })!.itemIndexes[0]).toEqual(1); + }); + + it('returns correct shifted item because of collapsing', () => { + expect(testPosFn({ x: 9, y: 45 })!.itemIndexes[0]).toEqual(6); + }); +}); diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphCanvas.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphCanvas.tsx index cdea47c4cfe09..c5b067abea201 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphCanvas.tsx +++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphCanvas.tsx @@ -7,14 +7,14 @@ import { ClickedItemData, ColorScheme, ColorSchemeDiff, TextAlign } from '../typ import FlameGraphContextMenu from './FlameGraphContextMenu'; import FlameGraphTooltip from './FlameGraphTooltip'; -import { FlameGraphDataContainer, LevelItem } from './dataTransform'; +import { CollapseConfig, CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform'; import { getBarX, useFlameRender } from './rendering'; type Props = { data: FlameGraphDataContainer; rangeMin: number; rangeMax: number; - search: string; + matchedLabels: Set | undefined; setRangeMin: (range: number) => void; setRangeMax: (range: number) => void; style?: React.CSSProperties; @@ -32,13 +32,18 @@ type Props = { totalProfileTicks: number; totalProfileTicksRight?: number; totalViewTicks: number; + showFlameGraphOnly?: boolean; + + collapsedMap: CollapsedMap; + setCollapsedMap: (collapsedMap: CollapsedMap) => void; + collapsing?: boolean; }; const FlameGraphCanvas = ({ data, rangeMin, rangeMax, - search, + matchedLabels, setRangeMin, setRangeMax, onItemFocused, @@ -52,6 +57,10 @@ const FlameGraphCanvas = ({ root, direction, depth, + showFlameGraphOnly, + collapsedMap, + setCollapsedMap, + collapsing, }: Props) => { const styles = getStyles(); @@ -71,13 +80,14 @@ const FlameGraphCanvas = ({ depth, rangeMax, rangeMin, - search, + matchedLabels, textAlign, totalViewTicks, // We need this so that if we have a diff profile and are in sandwich view we still show the same diff colors. totalColorTicks: data.isDiffFlamegraph() ? totalProfileTicks : totalViewTicks, totalTicksRight: totalProfileTicksRight, wrapperWidth, + collapsedMap, }); const onGraphClick = useCallback( @@ -91,7 +101,8 @@ const FlameGraphCanvas = ({ depth, pixelsPerTick, totalViewTicks, - rangeMin + rangeMin, + collapsedMap ); // if clicking on a block in the canvas @@ -107,7 +118,7 @@ const FlameGraphCanvas = ({ setClickedItemData(undefined); } }, - [data, rangeMin, rangeMax, totalViewTicks, root, direction, depth] + [data, rangeMin, rangeMax, totalViewTicks, root, direction, depth, collapsedMap] ); const [mousePosition, setMousePosition] = useState<{ x: number; y: number }>(); @@ -124,7 +135,8 @@ const FlameGraphCanvas = ({ depth, pixelsPerTick, totalViewTicks, - rangeMin + rangeMin, + collapsedMap ); if (item) { @@ -133,7 +145,7 @@ const FlameGraphCanvas = ({ } } }, - [rangeMin, rangeMax, totalViewTicks, clickedItemData, setMousePosition, root, direction, depth] + [rangeMin, rangeMax, totalViewTicks, clickedItemData, setMousePosition, root, direction, depth, collapsedMap] ); const onGraphMouseLeave = useCallback(() => { @@ -165,10 +177,18 @@ const FlameGraphCanvas = ({ onMouseLeave={onGraphMouseLeave} /> - - {clickedItemData && ( + + {!showFlameGraphOnly && clickedItemData && ( { setClickedItemData(undefined); }} @@ -180,17 +200,51 @@ const FlameGraphCanvas = ({ onSandwich={() => { onSandwich(data.getLabel(clickedItemData.item.itemIndexes[0])); }} + onExpandGroup={() => { + setCollapsedMap(setCollapsedStatus(collapsedMap, clickedItemData.item, false)); + }} + onCollapseGroup={() => { + setCollapsedMap(setCollapsedStatus(collapsedMap, clickedItemData.item, true)); + }} + onExpandAllGroups={() => { + setCollapsedMap(setAllCollapsedStatus(collapsedMap, false)); + }} + onCollapseAllGroups={() => { + setCollapsedMap(setAllCollapsedStatus(collapsedMap, true)); + }} + allGroupsCollapsed={Array.from(collapsedMap.values()).every((i) => i.collapsed)} + allGroupsExpanded={Array.from(collapsedMap.values()).every((i) => !i.collapsed)} /> )} ); }; +function setCollapsedStatus(collapsedMap: CollapsedMap, item: LevelItem, collapsed: boolean) { + const newMap = new Map(collapsedMap); + const collapsedConfig = collapsedMap.get(item)!; + const newConfig = { ...collapsedConfig, collapsed }; + for (const item of collapsedConfig.items) { + newMap.set(item, newConfig); + } + return newMap; +} + +function setAllCollapsedStatus(collapsedMap: CollapsedMap, collapsed: boolean) { + const newMap = new Map(collapsedMap); + for (const item of collapsedMap.keys()) { + const collapsedConfig = collapsedMap.get(item)!; + const newConfig = { ...collapsedConfig, collapsed }; + newMap.set(item, newConfig); + } + + return newMap; +} + const getStyles = () => ({ graph: css({ label: 'graph', overflow: 'auto', - height: '100%', flexGrow: 1, flexBasis: '50%', }), @@ -217,7 +271,7 @@ const getStyles = () => ({ }), }); -const convertPixelCoordinatesToBarCoordinates = ( +export const convertPixelCoordinatesToBarCoordinates = ( // position relative to the start of the graph pos: { x: number; y: number }, root: LevelItem, @@ -225,7 +279,8 @@ const convertPixelCoordinatesToBarCoordinates = ( depth: number, pixelsPerTick: number, totalTicks: number, - rangeMin: number + rangeMin: number, + collapsedMap: Map ): LevelItem | undefined => { let next: LevelItem | undefined = root; let currentLevel = direction === 'children' ? 0 : depth - 1; @@ -247,7 +302,13 @@ const convertPixelCoordinatesToBarCoordinates = ( const xEnd = getBarX(child.start + child.value, totalTicks, rangeMin, pixelsPerTick); if (xStart <= pos.x && pos.x < xEnd) { next = child; - currentLevel = currentLevel + (direction === 'children' ? 1 : -1); + // Check if item is a collapsed item. if so also check if the item is the first collapsed item in the chain, + // which we render, or a child which we don't render. If it's a child in the chain then don't increase the + // level end effectively skip it. + const collapsedConfig = collapsedMap.get(child); + if (!collapsedConfig || !collapsedConfig.collapsed || collapsedConfig.items[0] === child) { + currentLevel = currentLevel + (direction === 'children' ? 1 : -1); + } break; } } diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphContextMenu.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphContextMenu.tsx index b30d8fc18b952..3a370f5dc86e5 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphContextMenu.tsx +++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphContextMenu.tsx @@ -1,17 +1,40 @@ import React from 'react'; -import { MenuItem, ContextMenu } from '@grafana/ui'; +import { MenuItem, MenuGroup, ContextMenu } from '@grafana/ui'; import { ClickedItemData } from '../types'; +import { CollapseConfig } from './dataTransform'; + type Props = { itemData: ClickedItemData; onMenuItemClick: () => void; onItemFocus: () => void; onSandwich: () => void; + onExpandGroup: () => void; + onCollapseGroup: () => void; + onExpandAllGroups: () => void; + onCollapseAllGroups: () => void; + collapseConfig?: CollapseConfig; + collapsing?: boolean; + allGroupsCollapsed?: boolean; + allGroupsExpanded?: boolean; }; -const FlameGraphContextMenu = ({ itemData, onMenuItemClick, onItemFocus, onSandwich }: Props) => { +const FlameGraphContextMenu = ({ + itemData, + onMenuItemClick, + onItemFocus, + onSandwich, + collapseConfig, + onExpandGroup, + onCollapseGroup, + onExpandAllGroups, + onCollapseAllGroups, + collapsing, + allGroupsExpanded, + allGroupsCollapsed, +}: Props) => { function renderItems() { return ( <> @@ -40,6 +63,52 @@ const FlameGraphContextMenu = ({ itemData, onMenuItemClick, onItemFocus, onSandw onMenuItemClick(); }} /> + + {collapsing && ( + + {collapseConfig ? ( + collapseConfig.collapsed ? ( + { + onExpandGroup(); + onMenuItemClick(); + }} + /> + ) : ( + { + onCollapseGroup(); + onMenuItemClick(); + }} + /> + ) + ) : null} + {!allGroupsExpanded && ( + { + onExpandAllGroups(); + onMenuItemClick(); + }} + /> + )} + {!allGroupsCollapsed && ( + { + onCollapseAllGroups(); + onMenuItemClick(); + }} + /> + )} + + )} ); } diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.test.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.test.tsx index 408398e757438..7ad62ca5f78e8 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.test.tsx +++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.test.tsx @@ -12,7 +12,7 @@ function setupData(unit?: string) { { name: 'label', values: ['total'] }, ], }); - return new FlameGraphDataContainer(flameGraphData); + return new FlameGraphDataContainer(flameGraphData, { collapsing: true }); } function setupDiffData() { @@ -26,7 +26,7 @@ function setupDiffData() { { name: 'label', values: ['total', 'func1'] }, ], }); - return new FlameGraphDataContainer(flameGraphData); + return new FlameGraphDataContainer(flameGraphData, { collapsing: true }); } describe('FlameGraphTooltip', () => { diff --git a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.tsx b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.tsx index fe9d7dd131664..d2fe2866606dc 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.tsx +++ b/packages/grafana-flamegraph/src/FlameGraph/FlameGraphTooltip.tsx @@ -4,16 +4,17 @@ import React from 'react'; import { DisplayValue, getValueFormat, GrafanaTheme2 } from '@grafana/data'; import { InteractiveTable, Portal, useStyles2, VizTooltipContainer } from '@grafana/ui'; -import { FlameGraphDataContainer, LevelItem } from './dataTransform'; +import { CollapseConfig, FlameGraphDataContainer, LevelItem } from './dataTransform'; type Props = { data: FlameGraphDataContainer; totalTicks: number; position?: { x: number; y: number }; item?: LevelItem; + collapseConfig?: CollapseConfig; }; -const FlameGraphTooltip = ({ data, item, totalTicks, position }: Props) => { +const FlameGraphTooltip = ({ data, item, totalTicks, position, collapseConfig }: Props) => { const styles = useStyles2(getStyles); if (!(item && position)) { @@ -56,7 +57,17 @@ const FlameGraphTooltip = ({ data, item, totalTicks, position }: Props) => {
    -

    {data.getLabel(item.itemIndexes[0])}

    +

    + {data.getLabel(item.itemIndexes[0])} + {collapseConfig && collapseConfig.collapsed ? ( + +
    + and {collapseConfig.items.length} similar items +
    + ) : ( + '' + )} +

    {content}
    diff --git a/packages/grafana-flamegraph/src/FlameGraph/__snapshots__/FlameGraph.test.tsx.snap b/packages/grafana-flamegraph/src/FlameGraph/__snapshots__/FlameGraph.test.tsx.snap index df6151e9b3c33..4eb3098bad9bb 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/__snapshots__/FlameGraph.test.tsx.snap +++ b/packages/grafana-flamegraph/src/FlameGraph/__snapshots__/FlameGraph.test.tsx.snap @@ -113,7 +113,7 @@ exports[`FlameGraph should render correctly 1`] = ` "maxWidth": null, "text": "total (16.5 Bil)", "x": 4, - "y": 11, + "y": 13, }, "transform": [ 1, @@ -217,9 +217,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "test/pkg/agent.(*Target).start.func1 (4.10 Bil)", - "x": 4, - "y": 33, + "text": "(2) test/pkg/agent.(*Target).start.func1 (4.10 Bil)", + "x": 10, + "y": 35, }, "transform": [ 1, @@ -233,6 +233,7 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { + "fillRule": "nonzero", "path": [ { "props": {}, @@ -249,9 +250,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 397.5419198055893, - "x": 0.5, - "y": 44, + "width": 10, + "x": 0, + "y": 22, }, "transform": [ 1, @@ -273,7 +274,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "stroke", + "type": "fill", }, { "props": { @@ -293,10 +294,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 397.5419198055893, - "x": 0.5, - "y": 44, + "height": 11, + "width": 3, + "x": 4, + "y": 27.5, }, "transform": [ 1, @@ -320,23 +321,6 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/agent.(*Target).scrape (4.10 Bil)", - "x": 4, - "y": 55, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, { "props": { "path": [ @@ -357,7 +341,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 355.74362089914945, "x": 0.5, - "y": 66, + "y": 44, }, "transform": [ 1, @@ -402,7 +386,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 355.74362089914945, "x": 0.5, - "y": 66, + "y": 44, }, "transform": [ 1, @@ -431,7 +415,7 @@ exports[`FlameGraph should render correctly 1`] = ` "maxWidth": null, "text": "test/pkg/distributor.(*Distributor).Push (3.67 Bil)", "x": 4, - "y": 77, + "y": 57, }, "transform": [ 1, @@ -463,7 +447,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 108.84204131227219, "x": 0.5, - "y": 88, + "y": 66, }, "transform": [ 1, @@ -508,7 +492,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 108.84204131227219, "x": 0.5, - "y": 88, + "y": 66, }, "transform": [ 1, @@ -537,7 +521,7 @@ exports[`FlameGraph should render correctly 1`] = ` "maxWidth": null, "text": "compress/gzip.(*Writer).Write (1.13 Bil)", "x": 4, - "y": 99, + "y": 79, }, "transform": [ 1, @@ -569,7 +553,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 102.03766707168894, "x": 0.5, - "y": 110, + "y": 88, }, "transform": [ 1, @@ -614,7 +598,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 102.03766707168894, "x": 0.5, - "y": 110, + "y": 88, }, "transform": [ 1, @@ -643,7 +627,7 @@ exports[`FlameGraph should render correctly 1`] = ` "maxWidth": null, "text": "compress/flate.(*compressor).write (1.06 Bil)", "x": 4, - "y": 121, + "y": 101, }, "transform": [ 1, @@ -675,7 +659,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 98.1494532199271, "x": 0.5, - "y": 132, + "y": 110, }, "transform": [ 1, @@ -720,7 +704,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 98.1494532199271, "x": 0.5, - "y": 132, + "y": 110, }, "transform": [ 1, @@ -749,7 +733,7 @@ exports[`FlameGraph should render correctly 1`] = ` "maxWidth": null, "text": "compress/flate.(*compressor).deflate (1.02 Bil)", "x": 4, - "y": 143, + "y": 123, }, "transform": [ 1, @@ -781,7 +765,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 13.580801944106927, "x": 0.5, - "y": 154, + "y": 132, }, "transform": [ 1, @@ -826,7 +810,7 @@ exports[`FlameGraph should render correctly 1`] = ` "height": 22, "width": 13.580801944106927, "x": 0.5, - "y": 154, + "y": 132, }, "transform": [ 1, @@ -868,9 +852,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 13.580801944106927, - "x": 0.5, - "y": 176, + "width": 50.51883353584447, + "x": 15.080801944106927, + "y": 132, }, "transform": [ 1, @@ -913,9 +897,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 13.580801944106927, - "x": 0.5, - "y": 176, + "width": 50.51883353584447, + "x": 15.080801944106927, + "y": 132, }, "transform": [ 1, @@ -941,7 +925,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "compress/flate.(*compressor).findMatch (530 Mil)", + "x": 18.580801944106927, + "y": 145, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -958,9 +958,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 0, - "y": 198, + "width": 36.91008505467801, + "x": 110.34204131227219, + "y": 66, }, "transform": [ 1, @@ -982,7 +982,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -1003,9 +1003,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 0, - "y": 220, + "width": 36.91008505467801, + "x": 110.34204131227219, + "y": 66, }, "transform": [ 1, @@ -1029,6 +1029,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) test/pkg/pprof.OpenRaw (390 Mil)", + "x": 119.84204131227219, + "y": 79, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -1048,9 +1065,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 0, - "y": 242, + "width": 10, + "x": 109.84204131227219, + "y": 66, }, "transform": [ 1, @@ -1092,10 +1109,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 0, - "y": 264, + "height": 11, + "width": 3, + "x": 113.84204131227219, + "y": 71.5, }, "transform": [ 1, @@ -1121,7 +1138,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -1138,9 +1154,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1.9441069258809236, - "y": 242, + "width": 16.496962332928312, + "x": 110.34204131227219, + "y": 88, }, "transform": [ 1, @@ -1162,7 +1178,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -1183,9 +1199,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1.9441069258809236, - "y": 264, + "width": 16.496962332928312, + "x": 110.34204131227219, + "y": 88, }, "transform": [ 1, @@ -1211,7 +1227,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -1228,9 +1243,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1.9441069258809236, - "y": 286, + "width": 9.69258809234508, + "x": 127.83900364520049, + "y": 88, }, "transform": [ 1, @@ -1252,7 +1267,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -1273,9 +1288,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1.9441069258809236, - "y": 308, + "width": 9.69258809234508, + "x": 127.83900364520049, + "y": 88, }, "transform": [ 1, @@ -1301,7 +1316,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -1318,9 +1332,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1.9441069258809236, - "y": 330, + "width": 19.413122721749698, + "x": 148.2521263669502, + "y": 66, }, "transform": [ 1, @@ -1342,7 +1356,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -1363,9 +1377,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1.9441069258809236, - "y": 352, + "width": 19.413122721749698, + "x": 148.2521263669502, + "y": 66, }, "transform": [ 1, @@ -1389,6 +1403,50 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 22, + "width": 11.636695018226003, + "x": 148.2521263669502, + "y": 88, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "stroke", + }, { "props": { "fillRule": "nonzero", @@ -1408,9 +1466,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 2.9161603888213854, - "y": 220, + "width": 11.636695018226003, + "x": 148.2521263669502, + "y": 88, }, "transform": [ 1, @@ -1434,6 +1492,50 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 22, + "width": 177.85783718104497, + "x": 168.66524908869988, + "y": 66, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "stroke", + }, { "props": { "fillRule": "nonzero", @@ -1453,9 +1555,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 2.9161603888213854, - "y": 242, + "width": 177.85783718104497, + "x": 168.66524908869988, + "y": 66, }, "transform": [ 1, @@ -1481,7 +1583,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "test/pkg/pprof.(*Profile).Normalize (1.84 Bil)", + "x": 172.16524908869988, + "y": 79, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -1498,9 +1616,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 2.9161603888213854, - "y": 264, + "width": 22.329283110571083, + "x": 168.66524908869988, + "y": 88, }, "transform": [ 1, @@ -1522,7 +1640,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -1543,9 +1661,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 2.9161603888213854, - "y": 286, + "width": 22.329283110571083, + "x": 168.66524908869988, + "y": 88, }, "transform": [ 1, @@ -1569,6 +1687,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) sort.Sort (240 Mil)", + "x": 178.16524908869988, + "y": 101, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -1588,9 +1723,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 7.776427703523694, - "x": 4.860267314702309, - "y": 198, + "width": 10, + "x": 168.16524908869988, + "y": 88, }, "transform": [ 1, @@ -1632,10 +1767,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 3.888213851761847, - "x": 4.860267314702309, - "y": 220, + "height": 11, + "width": 3, + "x": 172.16524908869988, + "y": 93.5, }, "transform": [ 1, @@ -1661,7 +1796,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -1678,9 +1812,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 12.636695018226003, - "y": 198, + "width": 17.469015795868774, + "x": 173.5255164034022, + "y": 110, }, "transform": [ 1, @@ -1702,7 +1836,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -1723,9 +1857,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 13.608748481166465, - "y": 198, + "width": 17.469015795868774, + "x": 173.5255164034022, + "y": 110, }, "transform": [ 1, @@ -1767,9 +1901,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 50.51883353584447, - "x": 15.080801944106927, - "y": 154, + "width": 11.636695018226003, + "x": 173.5255164034022, + "y": 132, }, "transform": [ 1, @@ -1812,9 +1946,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 50.51883353584447, - "x": 15.080801944106927, - "y": 154, + "width": 11.636695018226003, + "x": 173.5255164034022, + "y": 132, }, "transform": [ 1, @@ -1840,10 +1974,37 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "maxWidth": null, - "text": "compress/flate.(*compressor).findMatch (530 Mil)", - "x": 18.580801944106927, - "y": 165, + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 22, + "width": 128.2831105710814, + "x": 191.99453219927096, + "y": 88, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], }, "transform": [ 1, @@ -1853,7 +2014,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fillText", + "type": "stroke", }, { "props": { @@ -1874,9 +2035,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 7.776427703523694, - "x": 66.0996354799514, - "y": 154, + "width": 128.2831105710814, + "x": 191.99453219927096, + "y": 88, }, "transform": [ 1, @@ -1902,7 +2063,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "test/pkg/pprof.(*Profile).clearSampleReferences (1.33 Bil)", + "x": 195.49453219927096, + "y": 101, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -1919,9 +2096,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 99.1494532199271, - "y": 132, + "width": 124.39489671931958, + "x": 191.99453219927096, + "y": 110, }, "transform": [ 1, @@ -1943,7 +2120,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -1964,8 +2141,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 6.804374240583233, - "x": 103.03766707168894, + "width": 124.39489671931958, + "x": 191.99453219927096, "y": 110, }, "transform": [ @@ -1992,7 +2169,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "test/pkg/slices.RemoveInPlace[...] (1.29 Bil)", + "x": 195.49453219927096, + "y": 123, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -2009,8 +2202,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 103.03766707168894, + "width": 30.105710814094778, + "x": 191.99453219927096, "y": 132, }, "transform": [ @@ -2033,7 +2226,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2054,9 +2247,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 103.03766707168894, - "y": 154, + "width": 30.105710814094778, + "x": 191.99453219927096, + "y": 132, }, "transform": [ 1, @@ -2082,7 +2275,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "test/pkg/pprof.(*Profile).clearSampleReferences.func1 (320 Mil)", + "x": 195.49453219927096, + "y": 145, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -2099,9 +2308,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 103.03766707168894, - "y": 176, + "width": 11.636695018226003, + "x": 321.2776427703524, + "y": 88, }, "transform": [ 1, @@ -2123,7 +2332,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2144,9 +2353,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 105.95382746051034, - "y": 176, + "width": 11.636695018226003, + "x": 321.2776427703524, + "y": 88, }, "transform": [ 1, @@ -2172,7 +2381,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -2189,9 +2397,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 105.95382746051034, - "y": 198, + "width": 40.798298906439854, + "x": 357.24362089914945, + "y": 44, }, "transform": [ 1, @@ -2213,7 +2421,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2234,9 +2442,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 105.95382746051034, - "y": 220, + "width": 40.798298906439854, + "x": 357.24362089914945, + "y": 44, }, "transform": [ 1, @@ -2260,6 +2468,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(4) io/ioutil.ReadAll (430 Mil)", + "x": 366.74362089914945, + "y": 57, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -2279,9 +2504,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 105.95382746051034, - "y": 242, + "width": 10, + "x": 356.74362089914945, + "y": 44, }, "transform": [ 1, @@ -2323,10 +2548,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 105.95382746051034, - "y": 264, + "height": 11, + "width": 3, + "x": 360.74362089914945, + "y": 49.5, }, "transform": [ 1, @@ -2352,7 +2577,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -2369,9 +2593,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 105.95382746051034, - "y": 286, + "width": 34.96597812879708, + "x": 362.1038882138518, + "y": 66, }, "transform": [ 1, @@ -2393,7 +2617,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2414,9 +2638,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 106.92588092345079, - "y": 176, + "width": 34.96597812879708, + "x": 362.1038882138518, + "y": 66, }, "transform": [ 1, @@ -2442,7 +2666,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "compress/flate.(*decompressor).huffmanBlock (370 Mil)", + "x": 365.6038882138518, + "y": 79, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -2459,9 +2699,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 106.92588092345079, - "y": 198, + "width": 16.496962332928312, + "x": 364.0479951397327, + "y": 88, }, "transform": [ 1, @@ -2483,7 +2723,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2504,9 +2744,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 106.92588092345079, - "y": 220, + "width": 16.496962332928312, + "x": 364.0479951397327, + "y": 88, }, "transform": [ 1, @@ -2532,7 +2772,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -2549,9 +2788,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 132, + "width": 546.26609963548, + "x": 399.0419198055893, + "y": 22, }, "transform": [ 1, @@ -2573,7 +2812,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2594,9 +2833,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 154, + "width": 546.26609963548, + "x": 399.0419198055893, + "y": 22, }, "transform": [ 1, @@ -2622,7 +2861,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "net/http.(*conn).serve (5.63 Bil)", + "x": 402.5419198055893, + "y": 35, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -2639,9 +2894,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 176, + "width": 541.4058323207777, + "x": 399.0419198055893, + "y": 44, }, "transform": [ 1, @@ -2663,7 +2918,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2684,9 +2939,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 198, + "width": 541.4058323207777, + "x": 399.0419198055893, + "y": 44, }, "transform": [ 1, @@ -2710,6 +2965,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(8) net/http.serverHandler.ServeHTTP (5.58 Bil)", + "x": 408.5419198055893, + "y": 57, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -2729,9 +3001,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 220, + "width": 10, + "x": 398.5419198055893, + "y": 44, }, "transform": [ 1, @@ -2773,10 +3045,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 242, + "height": 11, + "width": 3, + "x": 402.5419198055893, + "y": 49.5, }, "transform": [ 1, @@ -2802,7 +3074,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -2819,9 +3090,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 264, + "width": 537.5176184690158, + "x": 399.0419198055893, + "y": 66, }, "transform": [ 1, @@ -2843,7 +3114,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -2864,9 +3135,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 286, + "width": 537.5176184690158, + "x": 399.0419198055893, + "y": 66, }, "transform": [ 1, @@ -2890,6 +3161,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) net/http.HandlerFunc.ServeHTTP (5.54 Bil)", + "x": 408.5419198055893, + "y": 79, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -2909,9 +3197,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 107.89793438639126, - "y": 308, + "width": 10, + "x": 398.5419198055893, + "y": 66, }, "transform": [ 1, @@ -2953,10 +3241,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 107.89793438639126, - "y": 330, + "height": 11, + "width": 3, + "x": 402.5419198055893, + "y": 71.5, }, "transform": [ 1, @@ -2998,8 +3286,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 36.91008505467801, - "x": 110.34204131227219, + "width": 536.5455650060753, + "x": 399.0419198055893, "y": 88, }, "transform": [ @@ -3043,8 +3331,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 36.91008505467801, - "x": 110.34204131227219, + "width": 536.5455650060753, + "x": 399.0419198055893, "y": 88, }, "transform": [ @@ -3072,9 +3360,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "test/pkg/pprof.OpenRaw (390 Mil)", - "x": 113.84204131227219, - "y": 99, + "text": "net/http.HandlerFunc.ServeHTTP (5.53 Bil)", + "x": 402.5419198055893, + "y": 101, }, "transform": [ 1, @@ -3104,8 +3392,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 36.91008505467801, - "x": 110.34204131227219, + "width": 534.6014580801944, + "x": 399.0419198055893, "y": 110, }, "transform": [ @@ -3149,8 +3437,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 36.91008505467801, - "x": 110.34204131227219, + "width": 534.6014580801944, + "x": 399.0419198055893, "y": 110, }, "transform": [ @@ -3178,9 +3466,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "test/pkg/gen/google/v1.(*Profile).UnmarshalVT (390 Mil)", - "x": 113.84204131227219, - "y": 121, + "text": "github.com/weaveworks/common/middleware.Instrument.Wrap.func1 (5.51 Bil)", + "x": 402.5419198055893, + "y": 123, }, "transform": [ 1, @@ -3210,8 +3498,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 16.496962332928312, - "x": 110.34204131227219, + "width": 533.629404617254, + "x": 399.0419198055893, "y": 132, }, "transform": [ @@ -3255,8 +3543,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 16.496962332928312, - "x": 110.34204131227219, + "width": 533.629404617254, + "x": 399.0419198055893, "y": 132, }, "transform": [ @@ -3281,6 +3569,67 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "github.com/felixge/httpsnoop.(*Metrics).CaptureMetrics (5.50 Bil)", + "x": 402.5419198055893, + "y": 145, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 22, + "width": 532.6573511543135, + "x": 399.0419198055893, + "y": 154, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "stroke", + }, { "props": { "fillRule": "nonzero", @@ -3300,8 +3649,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 6.804374240583233, - "x": 109.84204131227219, + "width": 532.6573511543135, + "x": 399.0419198055893, "y": 154, }, "transform": [ @@ -3326,6 +3675,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) github.com/weaveworks/common/middleware.Instrument.Wrap.func1.2 (5.49 Bil)", + "x": 408.5419198055893, + "y": 167, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -3345,9 +3711,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 109.84204131227219, - "y": 176, + "width": 10, + "x": 398.5419198055893, + "y": 154, }, "transform": [ 1, @@ -3389,10 +3755,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 109.84204131227219, - "y": 198, + "height": 11, + "width": 3, + "x": 402.5419198055893, + "y": 159.5, }, "transform": [ 1, @@ -3418,7 +3784,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -3435,9 +3800,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 110.81409477521264, - "y": 198, + "width": 155.50060753341435, + "x": 399.0419198055893, + "y": 176, }, "transform": [ 1, @@ -3459,7 +3824,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -3480,9 +3845,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 110.81409477521264, - "y": 220, + "width": 155.50060753341435, + "x": 399.0419198055893, + "y": 176, }, "transform": [ 1, @@ -3506,6 +3871,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) github.com/bufbuild/connect-go.(*Handler).ServeHTTP (1.61 Bil)", + "x": 408.5419198055893, + "y": 189, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -3525,9 +3907,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 110.81409477521264, - "y": 242, + "width": 10, + "x": 398.5419198055893, + "y": 176, }, "transform": [ 1, @@ -3569,10 +3951,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 110.81409477521264, - "y": 264, + "height": 11, + "width": 3, + "x": 402.5419198055893, + "y": 181.5, }, "transform": [ 1, @@ -3598,7 +3980,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -3615,9 +3996,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 111.7861482381531, - "y": 242, + "width": 148.69623329283112, + "x": 399.0419198055893, + "y": 198, }, "transform": [ 1, @@ -3639,7 +4020,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -3660,9 +4041,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 111.7861482381531, - "y": 264, + "width": 148.69623329283112, + "x": 399.0419198055893, + "y": 198, }, "transform": [ 1, @@ -3686,6 +4067,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) github.com/bufbuild/connect-go.NewUnaryHandler[...].func1.1 (1.54 Bil)", + "x": 408.5419198055893, + "y": 211, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -3705,9 +4103,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 111.7861482381531, - "y": 286, + "width": 10, + "x": 398.5419198055893, + "y": 198, }, "transform": [ 1, @@ -3749,10 +4147,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 114.70230862697449, - "y": 176, + "height": 11, + "width": 3, + "x": 402.5419198055893, + "y": 203.5, }, "transform": [ 1, @@ -3778,7 +4176,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -3795,9 +4192,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 115.67436208991495, - "y": 176, + "width": 17.469015795868774, + "x": 399.0419198055893, + "y": 220, }, "transform": [ 1, @@ -3819,7 +4216,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -3840,9 +4237,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 116.64641555285542, - "y": 154, + "width": 17.469015795868774, + "x": 399.0419198055893, + "y": 220, }, "transform": [ 1, @@ -3868,7 +4265,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -3885,9 +4281,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 116.64641555285542, - "y": 176, + "width": 15.52490886998785, + "x": 399.0419198055893, + "y": 242, }, "transform": [ 1, @@ -3909,7 +4305,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -3930,9 +4326,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 117.61846901579588, - "y": 176, + "width": 15.52490886998785, + "x": 399.0419198055893, + "y": 242, }, "transform": [ 1, @@ -3956,6 +4352,50 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 22, + "width": 10.664641555285542, + "x": 401.95808019441074, + "y": 264, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "stroke", + }, { "props": { "fillRule": "nonzero", @@ -3975,9 +4415,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 118.59052247873633, - "y": 154, + "width": 10.664641555285542, + "x": 401.95808019441074, + "y": 264, }, "transform": [ 1, @@ -4019,9 +4459,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 9.69258809234508, - "x": 127.83900364520049, - "y": 132, + "width": 81.62454434993926, + "x": 417.51093560145813, + "y": 220, }, "transform": [ 1, @@ -4064,9 +4504,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 9.69258809234508, - "x": 127.83900364520049, - "y": 132, + "width": 81.62454434993926, + "x": 417.51093560145813, + "y": 220, }, "transform": [ 1, @@ -4092,7 +4532,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "test/pkg/create.(*Head).Ingest (850 Mil)", + "x": 421.01093560145813, + "y": 233, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -4109,9 +4565,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 7.776427703523694, - "x": 127.33900364520049, - "y": 154, + "width": 33.02187120291616, + "x": 417.51093560145813, + "y": 242, }, "transform": [ 1, @@ -4133,7 +4589,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4154,9 +4610,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 5.832320777642771, - "x": 127.33900364520049, - "y": 176, + "width": 33.02187120291616, + "x": 417.51093560145813, + "y": 242, }, "transform": [ 1, @@ -4182,7 +4638,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "test/pkg/create.(*Head).convertSamples (350 Mil)", + "x": 421.01093560145813, + "y": 255, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -4199,9 +4671,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 127.33900364520049, - "y": 198, + "width": 28.161603888213854, + "x": 417.51093560145813, + "y": 264, }, "transform": [ 1, @@ -4223,7 +4695,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4244,9 +4716,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 128.31105710814094, - "y": 198, + "width": 28.161603888213854, + "x": 417.51093560145813, + "y": 264, }, "transform": [ 1, @@ -4272,7 +4744,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "test/pkg/create.(*deduplicatingSlice[...]).ingest (300 Mil)", + "x": 421.01093560145813, + "y": 277, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -4289,9 +4777,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 128.31105710814094, - "y": 220, + "width": 10.664641555285542, + "x": 417.51093560145813, + "y": 286, }, "transform": [ 1, @@ -4313,97 +4801,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 128.31105710814094, - "y": 242, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 128.31105710814094, - "y": 264, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4424,8 +4822,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 128.31105710814094, + "width": 10.664641555285542, + "x": 417.51093560145813, "y": 286, }, "transform": [ @@ -4452,7 +4850,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -4469,8 +4866,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 128.31105710814094, + "width": 9.69258809234508, + "x": 417.51093560145813, "y": 308, }, "transform": [ @@ -4493,7 +4890,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4514,9 +4911,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 128.31105710814094, - "y": 330, + "width": 9.69258809234508, + "x": 417.51093560145813, + "y": 308, }, "transform": [ 1, @@ -4542,7 +4939,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -4559,9 +4955,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 128.31105710814094, - "y": 352, + "width": 34.96597812879708, + "x": 451.5328068043743, + "y": 242, }, "transform": [ 1, @@ -4583,7 +4979,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4604,9 +5000,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 128.31105710814094, - "y": 374, + "width": 34.96597812879708, + "x": 451.5328068043743, + "y": 242, }, "transform": [ 1, @@ -4632,38 +5028,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 128.31105710814094, - "y": 396, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "test/pkg/create.(*deduplicatingSlice[...]).ingest (370 Mil)", + "x": 455.0328068043743, + "y": 255, }, "transform": [ 1, @@ -4673,11 +5041,10 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -4694,9 +5061,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 130.25516403402187, - "y": 198, + "width": 9.69258809234508, + "x": 488.4708383961118, + "y": 242, }, "transform": [ 1, @@ -4718,7 +5085,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4739,9 +5106,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 133.17132442284327, - "y": 176, + "width": 9.69258809234508, + "x": 488.4708383961118, + "y": 242, }, "transform": [ 1, @@ -4767,7 +5134,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -4784,9 +5150,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 134.14337788578374, - "y": 176, + "width": 45.658566221142166, + "x": 500.1354799513974, + "y": 220, }, "transform": [ 1, @@ -4808,7 +5174,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4829,9 +5195,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 135.1154313487242, - "y": 154, + "width": 45.658566221142166, + "x": 500.1354799513974, + "y": 220, }, "transform": [ 1, @@ -4857,38 +5223,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 135.1154313487242, - "y": 176, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "test/pkg/gen/google/v1.(*Profile).UnmarshalVT (480 Mil)", + "x": 503.6354799513974, + "y": 233, }, "transform": [ 1, @@ -4898,11 +5236,10 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -4919,9 +5256,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 138.03159173754557, - "y": 132, + "width": 13.580801944106927, + "x": 500.1354799513974, + "y": 242, }, "transform": [ 1, @@ -4943,7 +5280,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -4964,9 +5301,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 138.03159173754557, - "y": 154, + "width": 13.580801944106927, + "x": 500.1354799513974, + "y": 242, }, "transform": [ 1, @@ -4992,7 +5329,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -5009,9 +5345,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 138.03159173754557, - "y": 176, + "width": 11.636695018226003, + "x": 501.1075334143378, + "y": 264, }, "transform": [ 1, @@ -5033,7 +5369,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -5054,9 +5390,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 139.9756986634265, - "y": 176, + "width": 11.636695018226003, + "x": 501.1075334143378, + "y": 264, }, "transform": [ 1, @@ -5082,7 +5418,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -5099,9 +5434,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 140.94775212636696, - "y": 154, + "width": 12.608748481166465, + "x": 514.7162818955043, + "y": 242, }, "transform": [ 1, @@ -5123,7 +5458,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -5144,9 +5479,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 141.91980558930743, - "y": 132, + "width": 12.608748481166465, + "x": 514.7162818955043, + "y": 242, }, "transform": [ 1, @@ -5170,6 +5505,50 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 22, + "width": 10.664641555285542, + "x": 528.3250303766707, + "y": 242, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "stroke", + }, { "props": { "fillRule": "nonzero", @@ -5189,9 +5568,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 141.91980558930743, - "y": 154, + "width": 10.664641555285542, + "x": 528.3250303766707, + "y": 242, }, "transform": [ 1, @@ -5217,7 +5596,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -5234,8 +5612,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 141.91980558930743, + "width": 376.1567436208992, + "x": 555.5425273390036, "y": 176, }, "transform": [ @@ -5258,7 +5636,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -5279,8 +5657,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 142.8918590522479, + "width": 376.1567436208992, + "x": 555.5425273390036, "y": 176, }, "transform": [ @@ -5305,6 +5683,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(5) net/http.(*ServeMux).ServeHTTP (3.88 Bil)", + "x": 565.0425273390036, + "y": 189, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -5324,8 +5719,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 143.86391251518833, + "width": 10, + "x": 555.0425273390036, "y": 176, }, "transform": [ @@ -5353,6 +5748,50 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "fillRule": "nonzero", + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 11, + "width": 3, + "x": 559.0425273390036, + "y": 181.5, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fill", + }, + { + "props": { "path": [ { "props": {}, @@ -5369,8 +5808,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 143.86391251518833, + "width": 312.97326852976914, + "x": 555.5425273390036, "y": 198, }, "transform": [ @@ -5393,7 +5832,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -5414,9 +5853,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 143.86391251518833, - "y": 220, + "width": 312.97326852976914, + "x": 555.5425273390036, + "y": 198, }, "transform": [ 1, @@ -5440,6 +5879,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) runtime/pprof.writeAlloc (3.23 Bil)", + "x": 565.0425273390036, + "y": 211, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -5459,9 +5915,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 143.86391251518833, - "y": 242, + "width": 10, + "x": 555.0425273390036, + "y": 198, }, "transform": [ 1, @@ -5503,10 +5959,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 143.86391251518833, - "y": 264, + "height": 11, + "width": 3, + "x": 559.0425273390036, + "y": 203.5, }, "transform": [ 1, @@ -5548,9 +6004,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 19.413122721749698, - "x": 148.2521263669502, - "y": 88, + "width": 311.0291616038882, + "x": 555.5425273390036, + "y": 220, }, "transform": [ 1, @@ -5593,9 +6049,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 19.413122721749698, - "x": 148.2521263669502, - "y": 88, + "width": 311.0291616038882, + "x": 555.5425273390036, + "y": 220, }, "transform": [ 1, @@ -5619,6 +6075,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "runtime/pprof.writeHeapProto (3.21 Bil)", + "x": 559.0425273390036, + "y": 233, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "path": [ @@ -5637,9 +6110,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 19.413122721749698, - "x": 148.2521263669502, - "y": 110, + "width": 30.105710814094778, + "x": 555.5425273390036, + "y": 242, }, "transform": [ 1, @@ -5682,9 +6155,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 19.413122721749698, - "x": 148.2521263669502, - "y": 110, + "width": 30.105710814094778, + "x": 555.5425273390036, + "y": 242, }, "transform": [ 1, @@ -5708,6 +6181,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "runtime/pprof.(*profileBuilder).pbSample (320 Mil)", + "x": 559.0425273390036, + "y": 255, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "path": [ @@ -5726,9 +6216,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 19.413122721749698, - "x": 148.2521263669502, - "y": 132, + "width": 178.82989064398544, + "x": 586.6482381530984, + "y": 242, }, "transform": [ 1, @@ -5771,9 +6261,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 19.413122721749698, - "x": 148.2521263669502, - "y": 132, + "width": 178.82989064398544, + "x": 586.6482381530984, + "y": 242, }, "transform": [ 1, @@ -5797,6 +6287,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "runtime/pprof.(*profileBuilder).appendLocsForStack (1.85 Bil)", + "x": 590.1482381530984, + "y": 255, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "path": [ @@ -5815,9 +6322,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 11.636695018226003, - "x": 148.2521263669502, - "y": 154, + "width": 38.85419198055893, + "x": 586.6482381530984, + "y": 264, }, "transform": [ 1, @@ -5860,9 +6367,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 11.636695018226003, - "x": 148.2521263669502, - "y": 154, + "width": 38.85419198055893, + "x": 586.6482381530984, + "y": 264, }, "transform": [ 1, @@ -5886,6 +6393,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "runtime/pprof.(*profileBuilder).emitLocation (410 Mil)", + "x": 590.1482381530984, + "y": 277, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "path": [ @@ -5904,9 +6428,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 11.636695018226003, - "x": 148.2521263669502, - "y": 176, + "width": 9.69258809234508, + "x": 586.6482381530984, + "y": 286, }, "transform": [ 1, @@ -5949,9 +6473,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 11.636695018226003, - "x": 148.2521263669502, - "y": 176, + "width": 9.69258809234508, + "x": 586.6482381530984, + "y": 286, }, "transform": [ 1, @@ -5977,7 +6501,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -5994,9 +6517,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 147.7521263669502, - "y": 198, + "width": 14.552855407047389, + "x": 626.5024301336574, + "y": 264, }, "transform": [ 1, @@ -6018,7 +6541,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -6039,9 +6562,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 148.72417982989066, - "y": 198, + "width": 14.552855407047389, + "x": 626.5024301336574, + "y": 264, }, "transform": [ 1, @@ -6067,7 +6590,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -6084,9 +6606,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 148.72417982989066, - "y": 220, + "width": 10.664641555285542, + "x": 626.5024301336574, + "y": 286, }, "transform": [ 1, @@ -6108,7 +6630,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -6129,9 +6651,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 148.72417982989066, - "y": 242, + "width": 10.664641555285542, + "x": 626.5024301336574, + "y": 286, }, "transform": [ 1, @@ -6157,7 +6679,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -6174,9 +6695,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 6.804374240583233, - "x": 153.58444714459296, - "y": 198, + "width": 61.211421628189555, + "x": 642.0552855407047, + "y": 264, }, "transform": [ 1, @@ -6198,7 +6719,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -6219,9 +6740,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 153.58444714459296, - "y": 220, + "width": 61.211421628189555, + "x": 642.0552855407047, + "y": 264, }, "transform": [ 1, @@ -6247,38 +6768,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 160.3888213851762, - "y": 154, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "runtime/pprof.allFrames (640 Mil)", + "x": 645.5552855407047, + "y": 277, }, "transform": [ 1, @@ -6288,7 +6781,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { @@ -6308,9 +6801,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 177.85783718104497, - "x": 168.66524908869988, - "y": 88, + "width": 52.462940461725395, + "x": 643.0273390036452, + "y": 286, }, "transform": [ 1, @@ -6353,9 +6846,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 177.85783718104497, - "x": 168.66524908869988, - "y": 88, + "width": 52.462940461725395, + "x": 643.0273390036452, + "y": 286, }, "transform": [ 1, @@ -6382,9 +6875,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "test/pkg/pprof.(*Profile).Normalize (1.84 Bil)", - "x": 172.16524908869988, - "y": 99, + "text": "runtime.(*Frames).Next (550 Mil)", + "x": 646.5273390036452, + "y": 299, }, "transform": [ 1, @@ -6414,9 +6907,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 22.329283110571083, - "x": 168.66524908869988, - "y": 110, + "width": 38.85419198055893, + "x": 643.0273390036452, + "y": 308, }, "transform": [ 1, @@ -6459,9 +6952,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 22.329283110571083, - "x": 168.66524908869988, - "y": 110, + "width": 38.85419198055893, + "x": 643.0273390036452, + "y": 308, }, "transform": [ 1, @@ -6488,9 +6981,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "sort.Sort (240 Mil)", - "x": 172.16524908869988, - "y": 121, + "text": "runtime.funcline1 (410 Mil)", + "x": 646.5273390036452, + "y": 321, }, "transform": [ 1, @@ -6520,9 +7013,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 22.329283110571083, - "x": 168.66524908869988, - "y": 132, + "width": 24.273390036452007, + "x": 650.803766707169, + "y": 330, }, "transform": [ 1, @@ -6565,9 +7058,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 22.329283110571083, - "x": 168.66524908869988, - "y": 132, + "width": 24.273390036452007, + "x": 650.803766707169, + "y": 330, }, "transform": [ 1, @@ -6594,9 +7087,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "sort.quickSort (240 Mil)", - "x": 172.16524908869988, - "y": 143, + "text": "runtime.pcvalue (260 Mil)", + "x": 654.303766707169, + "y": 343, }, "transform": [ 1, @@ -6610,7 +7103,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -6627,9 +7119,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 168.16524908869988, - "y": 154, + "width": 15.52490886998785, + "x": 652.7478736330498, + "y": 352, }, "transform": [ 1, @@ -6651,7 +7143,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -6672,9 +7164,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 168.16524908869988, - "y": 176, + "width": 15.52490886998785, + "x": 652.7478736330498, + "y": 352, }, "transform": [ 1, @@ -6700,7 +7192,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -6717,9 +7208,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 169.13730255164035, - "y": 176, + "width": 27.189550425273392, + "x": 704.2667071688943, + "y": 264, }, "transform": [ 1, @@ -6741,10 +7232,11 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { + "fillRule": "nonzero", "path": [ { "props": {}, @@ -6761,9 +7253,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 17.469015795868774, - "x": 173.5255164034022, - "y": 154, + "width": 27.189550425273392, + "x": 704.2667071688943, + "y": 264, }, "transform": [ 1, @@ -6785,11 +7277,27 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "stroke", + "type": "fill", + }, + { + "props": { + "maxWidth": null, + "text": "runtime.mapaccess2_fast64 (290 Mil)", + "x": 707.7667071688943, + "y": 277, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -6806,9 +7314,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 17.469015795868774, - "x": 173.5255164034022, - "y": 154, + "width": 19.413122721749698, + "x": 735.3724179829891, + "y": 264, }, "transform": [ 1, @@ -6830,10 +7338,11 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { + "fillRule": "nonzero", "path": [ { "props": {}, @@ -6850,9 +7359,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 11.636695018226003, - "x": 173.5255164034022, - "y": 176, + "width": 19.413122721749698, + "x": 735.3724179829891, + "y": 264, }, "transform": [ 1, @@ -6874,11 +7383,10 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "stroke", + "type": "fill", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -6895,9 +7403,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 11.636695018226003, - "x": 173.5255164034022, - "y": 176, + "width": 10.664641555285542, + "x": 737.3165249088701, + "y": 286, }, "transform": [ 1, @@ -6919,7 +7427,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -6940,9 +7448,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 173.0255164034022, - "y": 198, + "width": 10.664641555285542, + "x": 737.3165249088701, + "y": 286, }, "transform": [ 1, @@ -6968,7 +7476,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -6985,9 +7492,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 173.0255164034022, - "y": 220, + "width": 26.21749696233293, + "x": 767.4501822600243, + "y": 242, }, "transform": [ 1, @@ -7009,7 +7516,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7030,8 +7537,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 173.0255164034022, + "width": 26.21749696233293, + "x": 767.4501822600243, "y": 242, }, "transform": [ @@ -7058,7 +7565,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "runtime/pprof.(*profileBuilder).build (280 Mil)", + "x": 770.9501822600243, + "y": 255, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -7075,8 +7598,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 173.0255164034022, + "width": 13.580801944106927, + "x": 767.4501822600243, "y": 264, }, "transform": [ @@ -7099,7 +7622,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7120,9 +7643,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 173.0255164034022, - "y": 286, + "width": 13.580801944106927, + "x": 767.4501822600243, + "y": 264, }, "transform": [ 1, @@ -7148,7 +7671,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -7165,9 +7687,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 174.9696233292831, - "y": 220, + "width": 11.636695018226003, + "x": 782.0309842041313, + "y": 264, }, "transform": [ 1, @@ -7189,7 +7711,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7210,9 +7732,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 175.94167679222357, - "y": 220, + "width": 11.636695018226003, + "x": 782.0309842041313, + "y": 264, }, "transform": [ 1, @@ -7238,7 +7760,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -7255,8 +7776,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 175.94167679222357, + "width": 56.35115431348724, + "x": 794.6676792223573, "y": 242, }, "transform": [ @@ -7279,7 +7800,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7300,9 +7821,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 7.776427703523694, - "x": 177.8857837181045, - "y": 198, + "width": 56.35115431348724, + "x": 794.6676792223573, + "y": 242, }, "transform": [ 1, @@ -7328,38 +7849,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 177.8857837181045, - "y": 220, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "runtime.FuncForPC (590 Mil)", + "x": 798.1676792223573, + "y": 255, }, "transform": [ 1, @@ -7369,11 +7862,10 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -7390,9 +7882,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, - "y": 220, + "width": 13.580801944106927, + "x": 800.5, + "y": 264, }, "transform": [ 1, @@ -7414,7 +7906,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7435,9 +7927,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, - "y": 242, + "width": 13.580801944106927, + "x": 800.5, + "y": 264, }, "transform": [ 1, @@ -7463,7 +7955,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -7480,9 +7971,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, - "y": 264, + "width": 10.664641555285542, + "x": 803.4161603888215, + "y": 286, }, "transform": [ 1, @@ -7504,7 +7995,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7525,8 +8016,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, + "width": 10.664641555285542, + "x": 803.4161603888215, "y": 286, }, "transform": [ @@ -7553,7 +8044,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -7570,9 +8060,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, - "y": 308, + "width": 34.96597812879708, + "x": 815.080801944107, + "y": 264, }, "transform": [ 1, @@ -7594,7 +8084,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7615,9 +8105,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, - "y": 330, + "width": 34.96597812879708, + "x": 815.080801944107, + "y": 264, }, "transform": [ 1, @@ -7643,38 +8133,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, - "y": 352, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "runtime.funcline1 (370 Mil)", + "x": 818.580801944107, + "y": 277, }, "transform": [ 1, @@ -7684,11 +8146,10 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -7705,9 +8166,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 179.82989064398544, - "y": 374, + "width": 24.273390036452007, + "x": 815.080801944107, + "y": 286, }, "transform": [ 1, @@ -7729,7 +8190,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -7750,9 +8211,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 5.832320777642771, - "x": 185.6622114216282, - "y": 176, + "width": 24.273390036452007, + "x": 815.080801944107, + "y": 286, }, "transform": [ 1, @@ -7778,38 +8239,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 185.6622114216282, - "y": 198, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "runtime.pcvalue (260 Mil)", + "x": 818.580801944107, + "y": 299, }, "transform": [ 1, @@ -7819,7 +8252,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { @@ -7839,9 +8272,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 128.2831105710814, - "x": 191.99453219927096, - "y": 110, + "width": 13.580801944106927, + "x": 818.9690157958688, + "y": 308, }, "transform": [ 1, @@ -7884,9 +8317,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 128.2831105710814, - "x": 191.99453219927096, - "y": 110, + "width": 13.580801944106927, + "x": 818.9690157958688, + "y": 308, }, "transform": [ 1, @@ -7910,23 +8343,6 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/pprof.(*Profile).clearSampleReferences (1.33 Bil)", - "x": 195.49453219927096, - "y": 121, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, { "props": { "path": [ @@ -7945,9 +8361,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 124.39489671931958, - "x": 191.99453219927096, - "y": 132, + "width": 9.69258809234508, + "x": 840.354191980559, + "y": 286, }, "transform": [ 1, @@ -7990,9 +8406,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 124.39489671931958, - "x": 191.99453219927096, - "y": 132, + "width": 9.69258809234508, + "x": 840.354191980559, + "y": 286, }, "transform": [ 1, @@ -8016,23 +8432,6 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/slices.RemoveInPlace[...] (1.29 Bil)", - "x": 195.49453219927096, - "y": 143, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, { "props": { "path": [ @@ -8051,9 +8450,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 30.105710814094778, - "x": 191.99453219927096, - "y": 154, + "width": 61.211421628189555, + "x": 869.5157958687728, + "y": 198, }, "transform": [ 1, @@ -8096,9 +8495,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 30.105710814094778, - "x": 191.99453219927096, - "y": 154, + "width": 61.211421628189555, + "x": 869.5157958687728, + "y": 198, }, "transform": [ 1, @@ -8125,9 +8524,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "test/pkg/pprof.(*Profile).clearSampleReferences.func1 (320 Mil)", - "x": 195.49453219927096, - "y": 165, + "text": "(2) runtime/pprof.writeGoroutine (640 Mil)", + "x": 879.0157958687728, + "y": 211, }, "transform": [ 1, @@ -8158,9 +8557,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 316.88942891859057, - "y": 132, + "width": 10, + "x": 869.0157958687728, + "y": 198, }, "transform": [ 1, @@ -8202,10 +8601,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 316.88942891859057, - "y": 154, + "height": 11, + "width": 3, + "x": 873.0157958687728, + "y": 203.5, }, "transform": [ 1, @@ -8231,7 +8630,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -8248,9 +8646,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 317.861482381531, - "y": 132, + "width": 23.301336573511545, + "x": 869.5157958687728, + "y": 220, }, "transform": [ 1, @@ -8272,10 +8670,11 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { + "fillRule": "nonzero", "path": [ { "props": {}, @@ -8292,9 +8691,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 11.636695018226003, - "x": 321.2776427703524, - "y": 110, + "width": 23.301336573511545, + "x": 869.5157958687728, + "y": 220, }, "transform": [ 1, @@ -8316,42 +8715,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "stroke", + "type": "fill", }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 321.2776427703524, - "y": 110, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "(2) runtime/pprof.runtime_goroutineProfileWithLabels (250 Mil)", + "x": 879.0157958687728, + "y": 233, }, "transform": [ 1, @@ -8361,7 +8732,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { @@ -8382,9 +8753,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 320.7776427703524, - "y": 132, + "width": 10, + "x": 869.0157958687728, + "y": 220, }, "transform": [ 1, @@ -8426,10 +8797,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 321.74969623329287, - "y": 132, + "height": 11, + "width": 3, + "x": 873.0157958687728, + "y": 225.5, }, "transform": [ 1, @@ -8455,7 +8826,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -8472,9 +8842,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 5.832320777642771, - "x": 322.7217496962333, - "y": 132, + "width": 21.35722964763062, + "x": 869.5157958687728, + "y": 242, }, "transform": [ 1, @@ -8496,7 +8866,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -8517,9 +8887,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 328.5540704738761, - "y": 132, + "width": 21.35722964763062, + "x": 869.5157958687728, + "y": 242, }, "transform": [ 1, @@ -8545,38 +8915,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.720534629404618, - "x": 333.4143377885784, - "y": 110, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], + "maxWidth": null, + "text": "runtime.forEachGRace (230 Mil)", + "x": 873.0157958687728, + "y": 255, }, "transform": [ 1, @@ -8586,11 +8928,10 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "fillText", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -8607,9 +8948,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 333.4143377885784, - "y": 132, + "width": 16.496962332928312, + "x": 869.5157958687728, + "y": 264, }, "transform": [ 1, @@ -8631,7 +8972,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -8652,9 +8993,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 333.4143377885784, - "y": 154, + "width": 16.496962332928312, + "x": 869.5157958687728, + "y": 264, }, "transform": [ 1, @@ -8680,7 +9021,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -8697,9 +9037,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 337.30255164034025, - "y": 132, + "width": 15.52490886998785, + "x": 869.5157958687728, + "y": 286, }, "transform": [ 1, @@ -8721,7 +9061,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -8742,9 +9082,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 343.134872417983, - "y": 110, + "width": 15.52490886998785, + "x": 869.5157958687728, + "y": 286, }, "transform": [ 1, @@ -8770,7 +9110,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -8787,9 +9126,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 343.134872417983, - "y": 132, + "width": 36.91008505467801, + "x": 893.8171324422843, + "y": 220, }, "transform": [ 1, @@ -8811,7 +9150,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -8832,9 +9171,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 343.134872417983, - "y": 154, + "width": 36.91008505467801, + "x": 893.8171324422843, + "y": 220, }, "transform": [ 1, @@ -8860,7 +9199,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "runtime/pprof.printCountProfile (390 Mil)", + "x": 897.3171324422843, + "y": 233, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -8877,9 +9232,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 343.134872417983, - "y": 176, + "width": 16.496962332928312, + "x": 911.3140947752127, + "y": 242, }, "transform": [ 1, @@ -8901,7 +9256,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -8922,9 +9277,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 6.804374240583233, - "x": 347.02308626974485, - "y": 88, + "width": 16.496962332928312, + "x": 911.3140947752127, + "y": 242, }, "transform": [ 1, @@ -8950,7 +9305,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -8967,9 +9321,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 347.02308626974485, - "y": 110, + "width": 15.52490886998785, + "x": 911.3140947752127, + "y": 264, }, "transform": [ 1, @@ -8991,7 +9345,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -9012,9 +9366,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 347.02308626974485, - "y": 132, + "width": 15.52490886998785, + "x": 911.3140947752127, + "y": 264, }, "transform": [ 1, @@ -9040,7 +9394,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -9057,9 +9410,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 4.860267314702309, - "x": 347.9951397326853, - "y": 110, + "width": 600.7010935601459, + "x": 946.3080194410693, + "y": 22, }, "transform": [ 1, @@ -9081,7 +9434,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -9102,9 +9455,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 347.9951397326853, - "y": 132, + "width": 600.7010935601459, + "x": 946.3080194410693, + "y": 22, }, "transform": [ 1, @@ -9130,7 +9483,23 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", + "maxWidth": null, + "text": "runtime.gcBgMarkWorker (6.19 Bil)", + "x": 949.8080194410693, + "y": 35, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { "path": [ { "props": {}, @@ -9147,9 +9516,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 352.85540704738764, - "y": 110, + "width": 598.7569866342649, + "x": 946.3080194410693, + "y": 44, }, "transform": [ 1, @@ -9171,7 +9540,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -9192,9 +9561,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 353.8274605103281, - "y": 88, + "width": 598.7569866342649, + "x": 946.3080194410693, + "y": 44, }, "transform": [ 1, @@ -9218,6 +9587,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "(2) runtime.systemstack (6.17 Bil)", + "x": 955.8080194410693, + "y": 57, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "fillRule": "nonzero", @@ -9237,9 +9623,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 353.8274605103281, - "y": 110, + "width": 10, + "x": 945.8080194410693, + "y": 44, }, "transform": [ 1, @@ -9281,10 +9667,10 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 355.771567436209, - "y": 110, + "height": 11, + "width": 3, + "x": 949.8080194410693, + "y": 49.5, }, "transform": [ 1, @@ -9326,8 +9712,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, + "width": 589.0364520048603, + "x": 946.3080194410693, "y": 66, }, "transform": [ @@ -9371,8 +9757,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, + "width": 589.0364520048603, + "x": 946.3080194410693, "y": 66, }, "transform": [ @@ -9400,9 +9786,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "io/ioutil.ReadAll (430 Mil)", - "x": 360.74362089914945, - "y": 77, + "text": "runtime.gcDrain (6.07 Bil)", + "x": 949.8080194410693, + "y": 79, }, "transform": [ 1, @@ -9432,8 +9818,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, + "width": 432.53584447144596, + "x": 946.3080194410693, "y": 88, }, "transform": [ @@ -9477,8 +9863,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, + "width": 432.53584447144596, + "x": 946.3080194410693, "y": 88, }, "transform": [ @@ -9506,9 +9892,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "io.ReadAll (430 Mil)", - "x": 360.74362089914945, - "y": 99, + "text": "runtime.scanobject (4.46 Bil)", + "x": 949.8080194410693, + "y": 101, }, "transform": [ 1, @@ -9538,8 +9924,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, + "width": 41.77035236938032, + "x": 952.140340218712, "y": 110, }, "transform": [ @@ -9583,8 +9969,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, + "width": 41.77035236938032, + "x": 952.140340218712, "y": 110, }, "transform": [ @@ -9612,9 +9998,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "compress/gzip.(*Reader).Read (430 Mil)", - "x": 360.74362089914945, - "y": 121, + "text": "runtime.pageIndexOf (440 Mil)", + "x": 955.640340218712, + "y": 123, }, "transform": [ 1, @@ -9644,9 +10030,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, - "y": 132, + "width": 51.49088699878494, + "x": 994.9106925880924, + "y": 110, }, "transform": [ 1, @@ -9689,9 +10075,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 40.798298906439854, - "x": 357.24362089914945, - "y": 132, + "width": 51.49088699878494, + "x": 994.9106925880924, + "y": 110, }, "transform": [ 1, @@ -9718,9 +10104,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "compress/flate.(*decompressor).Read (430 Mil)", - "x": 360.74362089914945, - "y": 143, + "text": "runtime.greyobject (540 Mil)", + "x": 998.4106925880924, + "y": 123, }, "transform": [ 1, @@ -9734,7 +10120,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -9751,9 +10136,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 356.74362089914945, - "y": 154, + "width": 94.26123936816525, + "x": 1047.4015795868772, + "y": 110, }, "transform": [ 1, @@ -9775,7 +10160,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -9796,9 +10181,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 3.888213851761847, - "x": 357.71567436208994, - "y": 154, + "width": 94.26123936816525, + "x": 1047.4015795868772, + "y": 110, }, "transform": [ 1, @@ -9822,6 +10207,67 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "runtime.findObject (980 Mil)", + "x": 1050.9015795868772, + "y": 123, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, + { + "props": { + "path": [ + { + "props": {}, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "beginPath", + }, + { + "props": { + "height": 22, + "width": 45.658566221142166, + "x": 1147.523086269745, + "y": 110, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + ], + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "stroke", + }, { "props": { "fillRule": "nonzero", @@ -9841,9 +10287,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 357.71567436208994, - "y": 176, + "width": 45.658566221142166, + "x": 1147.523086269745, + "y": 110, }, "transform": [ 1, @@ -9867,6 +10313,23 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "fill", }, + { + "props": { + "maxWidth": null, + "text": "runtime.spanOf (480 Mil)", + "x": 1151.023086269745, + "y": 123, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "fillText", + }, { "props": { "path": [ @@ -9885,9 +10348,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 34.96597812879708, - "x": 362.1038882138518, - "y": 154, + "width": 51.49088699878494, + "x": 1194.181652490887, + "y": 110, }, "transform": [ 1, @@ -9930,9 +10393,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 34.96597812879708, - "x": 362.1038882138518, - "y": 154, + "width": 51.49088699878494, + "x": 1194.181652490887, + "y": 110, }, "transform": [ 1, @@ -9959,9 +10422,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "maxWidth": null, - "text": "compress/flate.(*decompressor).huffmanBlock (370 Mil)", - "x": 365.6038882138518, - "y": 165, + "text": "runtime.markBits.isMarked (540 Mil)", + "x": 1197.681652490887, + "y": 123, }, "transform": [ 1, @@ -9975,7 +10438,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -9992,9 +10454,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 361.6038882138518, - "y": 176, + "width": 19.413122721749698, + "x": 1379.8438639125152, + "y": 88, }, "transform": [ 1, @@ -10016,7 +10478,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -10037,9 +10499,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 361.6038882138518, - "y": 198, + "width": 19.413122721749698, + "x": 1379.8438639125152, + "y": 88, }, "transform": [ 1, @@ -10082,8 +10544,8 @@ exports[`FlameGraph should render correctly 1`] = ` "props": { "height": 22, "width": 16.496962332928312, - "x": 364.0479951397327, - "y": 176, + "x": 1409.005467800729, + "y": 88, }, "transform": [ 1, @@ -10127,8 +10589,8 @@ exports[`FlameGraph should render correctly 1`] = ` "props": { "height": 22, "width": 16.496962332928312, - "x": 364.0479951397327, - "y": 176, + "x": 1409.005467800729, + "y": 88, }, "transform": [ 1, @@ -10154,7 +10616,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -10171,9 +10632,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 363.5479951397327, - "y": 198, + "width": 19.413122721749698, + "x": 1427.4744835965978, + "y": 88, }, "transform": [ 1, @@ -10195,7 +10656,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -10216,9 +10677,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 381.044957472661, - "y": 176, + "width": 19.413122721749698, + "x": 1427.4744835965978, + "y": 88, }, "transform": [ 1, @@ -10244,7 +10705,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -10261,9 +10721,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 397.5698663426489, - "y": 154, + "width": 15.52490886998785, + "x": 1551.897326852977, + "y": 22, }, "transform": [ 1, @@ -10285,7 +10745,7 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { @@ -10306,9 +10766,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 397.5698663426489, - "y": 176, + "width": 15.52490886998785, + "x": 1551.897326852977, + "y": 22, }, "transform": [ 1, @@ -10334,7 +10794,6 @@ exports[`FlameGraph should render correctly 1`] = ` }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -10351,9 +10810,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 397.5698663426489, - "y": 198, + "width": 14.552855407047389, + "x": 1551.897326852977, + "y": 44, }, "transform": [ 1, @@ -10375,10 +10834,11 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", + "type": "stroke", }, { "props": { + "fillRule": "nonzero", "path": [ { "props": {}, @@ -10395,9 +10855,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 546.26609963548, - "x": 399.0419198055893, - "y": 22, + "width": 14.552855407047389, + "x": 1551.897326852977, + "y": 44, }, "transform": [ 1, @@ -10419,11 +10879,10 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "stroke", + "type": "fill", }, { "props": { - "fillRule": "nonzero", "path": [ { "props": {}, @@ -10440,8 +10899,8 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 546.26609963548, - "x": 399.0419198055893, + "width": 15.52490886998785, + "x": 1568.4222357229648, "y": 22, }, "transform": [ @@ -10464,27 +10923,11 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.(*conn).serve (5.63 Bil)", - "x": 402.5419198055893, - "y": 33, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", + "type": "stroke", }, { "props": { + "fillRule": "nonzero", "path": [ { "props": {}, @@ -10501,9 +10944,9 @@ exports[`FlameGraph should render correctly 1`] = ` { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 44, + "width": 15.52490886998785, + "x": 1568.4222357229648, + "y": 22, }, "transform": [ 1, @@ -10525,14 +10968,19 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "stroke", + "type": "fill", }, { "props": { "fillRule": "nonzero", "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 0, + "y": 154, + }, "transform": [ 1, 0, @@ -10541,14 +10989,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 44, + "width": 2.9161603888213854, + "x": 0, + "y": 176, }, "transform": [ 1, @@ -10560,40 +11008,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.serverHandler.ServeHTTP (5.58 Bil)", - "x": 402.5419198055893, - "y": 55, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 0, + "y": 198, + }, "transform": [ 1, 0, @@ -10602,14 +11023,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 66, + "width": 0.9720534629404618, + "x": 0, + "y": 220, }, "transform": [ 1, @@ -10621,24 +11042,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1.9441069258809236, + "y": 198, + }, "transform": [ 1, 0, @@ -10647,14 +11057,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 66, + "width": 0.9720534629404618, + "x": 2.9161603888213854, + "y": 176, }, "transform": [ 1, @@ -10666,40 +11076,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.HandlerFunc.ServeHTTP (5.58 Bil)", - "x": 402.5419198055893, - "y": 77, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 4.860267314702309, + "y": 154, + }, "transform": [ 1, 0, @@ -10708,14 +11091,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 88, + "width": 3.888213851761847, + "x": 4.860267314702309, + "y": 176, }, "transform": [ 1, @@ -10727,24 +11110,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 12.636695018226003, + "y": 154, + }, "transform": [ 1, 0, @@ -10753,14 +11125,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 88, + "width": 0.9720534629404618, + "x": 13.608748481166465, + "y": 154, }, "transform": [ 1, @@ -10772,40 +11144,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/util.glob..func1.1 (5.58 Bil)", - "x": 402.5419198055893, - "y": 99, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 66.0996354799514, + "y": 132, + }, "transform": [ 1, 0, @@ -10814,13 +11159,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, + "width": 3.888213851761847, + "x": 99.1494532199271, "y": 110, }, "transform": [ @@ -10833,24 +11178,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 6.804374240583233, + "x": 103.03766707168894, + "y": 88, + }, "transform": [ 1, 0, @@ -10859,13 +11193,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, + "width": 4.860267314702309, + "x": 103.03766707168894, "y": 110, }, "transform": [ @@ -10878,40 +11212,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "golang.org/x/net/http2/h2c.h2cHandler.ServeHTTP (5.58 Bil)", - "x": 402.5419198055893, - "y": 121, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 103.03766707168894, + "y": 132, + }, "transform": [ 1, 0, @@ -10920,13 +11227,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, + "width": 0.9720534629404618, + "x": 105.95382746051034, "y": 132, }, "transform": [ @@ -10939,24 +11246,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 106.92588092345079, + "y": 132, + }, "transform": [ 1, 0, @@ -10965,14 +11261,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 132, + "width": 1.9441069258809236, + "x": 107.89793438639126, + "y": 110, }, "transform": [ 1, @@ -10984,40 +11280,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.HandlerFunc.ServeHTTP (5.58 Bil)", - "x": 402.5419198055893, - "y": 143, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 107.89793438639126, + "y": 132, + }, "transform": [ 1, 0, @@ -11026,14 +11295,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 154, + "width": 6.804374240583233, + "x": 109.84204131227219, + "y": 110, }, "transform": [ 1, @@ -11045,24 +11314,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 109.84204131227219, + "y": 132, + }, "transform": [ 1, 0, @@ -11071,13 +11329,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, + "width": 0.9720534629404618, + "x": 109.84204131227219, "y": 154, }, "transform": [ @@ -11090,40 +11348,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/create.(*create).initServer.func2.1 (5.58 Bil)", - "x": 402.5419198055893, - "y": 165, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 110.81409477521264, + "y": 154, + }, "transform": [ 1, 0, @@ -11132,13 +11363,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, + "width": 0.9720534629404618, + "x": 110.81409477521264, "y": 176, }, "transform": [ @@ -11151,36759 +11382,12 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 176, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.HandlerFunc.ServeHTTP (5.58 Bil)", - "x": 402.5419198055893, - "y": 187, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 198, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 541.4058323207777, - "x": 399.0419198055893, - "y": 198, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/opentracing-contrib/go-stdlib/nethttp.MiddlewareFunc.func5 (5.58 Bil)", - "x": 402.5419198055893, - "y": 209, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 537.5176184690158, - "x": 399.0419198055893, - "y": 220, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 537.5176184690158, - "x": 399.0419198055893, - "y": 220, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.HandlerFunc.ServeHTTP (5.54 Bil)", - "x": 402.5419198055893, - "y": 231, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 537.5176184690158, - "x": 399.0419198055893, - "y": 242, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 537.5176184690158, - "x": 399.0419198055893, - "y": 242, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/weaveworks/common/middleware.Log.Wrap.func1 (5.54 Bil)", - "x": 402.5419198055893, - "y": 253, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 536.5455650060753, - "x": 399.0419198055893, - "y": 264, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 536.5455650060753, - "x": 399.0419198055893, - "y": 264, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.HandlerFunc.ServeHTTP (5.53 Bil)", - "x": 402.5419198055893, - "y": 275, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 534.6014580801944, - "x": 399.0419198055893, - "y": 286, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 534.6014580801944, - "x": 399.0419198055893, - "y": 286, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/weaveworks/common/middleware.Instrument.Wrap.func1 (5.51 Bil)", - "x": 402.5419198055893, - "y": 297, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 533.629404617254, - "x": 399.0419198055893, - "y": 308, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 533.629404617254, - "x": 399.0419198055893, - "y": 308, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/felixge/httpsnoop.(*Metrics).CaptureMetrics (5.50 Bil)", - "x": 402.5419198055893, - "y": 319, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 532.6573511543135, - "x": 399.0419198055893, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 532.6573511543135, - "x": 399.0419198055893, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/weaveworks/common/middleware.Instrument.Wrap.func1.2 (5.49 Bil)", - "x": 402.5419198055893, - "y": 341, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 532.6573511543135, - "x": 399.0419198055893, - "y": 352, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 532.6573511543135, - "x": 399.0419198055893, - "y": 352, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/gorilla/mux.(*Router).ServeHTTP (5.49 Bil)", - "x": 402.5419198055893, - "y": 363, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 155.50060753341435, - "x": 399.0419198055893, - "y": 374, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 155.50060753341435, - "x": 399.0419198055893, - "y": 374, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/bufbuild/connect-go.(*Handler).ServeHTTP (1.61 Bil)", - "x": 402.5419198055893, - "y": 385, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 155.50060753341435, - "x": 399.0419198055893, - "y": 396, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 155.50060753341435, - "x": 399.0419198055893, - "y": 396, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/bufbuild/connect-go.NewUnaryHandler[...].func1 (1.61 Bil)", - "x": 402.5419198055893, - "y": 407, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 148.69623329283112, - "x": 399.0419198055893, - "y": 418, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 148.69623329283112, - "x": 399.0419198055893, - "y": 418, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "github.com/bufbuild/connect-go.NewUnaryHandler[...].func1.1 (1.54 Bil)", - "x": 402.5419198055893, - "y": 429, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 148.69623329283112, - "x": 399.0419198055893, - "y": 440, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 148.69623329283112, - "x": 399.0419198055893, - "y": 440, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/ingester.(*Ingester).Push (1.54 Bil)", - "x": 402.5419198055893, - "y": 451, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 17.469015795868774, - "x": 399.0419198055893, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 17.469015795868774, - "x": 399.0419198055893, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 399.0419198055893, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 399.0419198055893, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 399.0419198055893, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 399.0419198055893, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 398.5419198055893, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 399.5139732685298, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 401.95808019441074, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 401.95808019441074, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 401.45808019441074, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 401.45808019441074, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 413.12272174969627, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 413.12272174969627, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 415.0668286755772, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 415.0668286755772, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 416.03888213851764, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 81.62454434993926, - "x": 417.51093560145813, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 81.62454434993926, - "x": 417.51093560145813, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/create.(*Head).Ingest (850 Mil)", - "x": 421.01093560145813, - "y": 473, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 33.02187120291616, - "x": 417.51093560145813, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 33.02187120291616, - "x": 417.51093560145813, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/create.(*Head).convertSamples (350 Mil)", - "x": 421.01093560145813, - "y": 495, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 28.161603888213854, - "x": 417.51093560145813, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 28.161603888213854, - "x": 417.51093560145813, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/create.(*deduplicatingSlice[...]).ingest (300 Mil)", - "x": 421.01093560145813, - "y": 517, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 417.51093560145813, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 417.51093560145813, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 417.51093560145813, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 417.51093560145813, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 417.01093560145813, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 417.01093560145813, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 424.7873633049818, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 428.67557715674366, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 428.67557715674366, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 428.67557715674366, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 432.5637910085055, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 436.4520048602673, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 437.4240583232078, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 437.4240583232078, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 438.39611178614825, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 438.39611178614825, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 438.39611178614825, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 439.36816524908875, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 439.36816524908875, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 442.2843256379101, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 446.172539489672, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 446.172539489672, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 447.1445929526124, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 447.1445929526124, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 448.1166464155529, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 449.08869987849334, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 34.96597812879708, - "x": 451.5328068043743, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 34.96597812879708, - "x": 451.5328068043743, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/create.(*deduplicatingSlice[...]).ingest (370 Mil)", - "x": 455.0328068043743, - "y": 495, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 451.0328068043743, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 451.0328068043743, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 452.9769137302552, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.720534629404618, - "x": 454.92102065613614, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 454.92102065613614, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 454.92102065613614, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 454.92102065613614, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 455.8930741190766, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 455.8930741190766, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 464.64155528554073, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 464.64155528554073, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 466.58566221142166, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 466.58566221142166, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 472.4179829890644, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 473.3900364520049, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 473.3900364520049, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 474.36208991494533, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 477.27825030376675, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 478.2503037667072, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 480.1944106925881, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 481.16646415552856, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 483.1105710814095, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 483.1105710814095, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 483.1105710814095, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 486.99878493317135, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 486.99878493317135, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 486.99878493317135, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 486.99878493317135, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 488.4708383961118, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 488.4708383961118, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 488.4708383961118, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 488.4708383961118, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 487.9708383961118, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 487.9708383961118, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 487.9708383961118, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 487.9708383961118, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 487.9708383961118, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 489.9149453219927, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 489.9149453219927, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 489.9149453219927, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 489.9149453219927, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 489.9149453219927, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 493.8031591737546, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 498.6634264884569, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 45.658566221142166, - "x": 500.1354799513974, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 45.658566221142166, - "x": 500.1354799513974, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "test/pkg/gen/google/v1.(*Profile).UnmarshalVT (480 Mil)", - "x": 503.6354799513974, - "y": 473, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 500.1354799513974, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 500.1354799513974, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 499.6354799513974, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 501.1075334143378, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 501.1075334143378, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 500.6075334143378, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 501.5795868772783, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 502.55164034021874, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 12.608748481166465, - "x": 514.7162818955043, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 12.608748481166465, - "x": 514.7162818955043, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 514.2162818955043, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 514.2162818955043, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 514.2162818955043, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 518.1044957472661, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 521.992709599028, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 521.992709599028, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 522.9647630619685, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 523.9368165249089, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 528.3250303766707, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 528.3250303766707, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 527.8250303766707, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 527.8250303766707, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 527.8250303766707, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 528.7970838396112, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 528.7970838396112, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 528.7970838396112, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 531.7132442284326, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 539.4896719319563, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 539.4896719319563, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 539.4896719319563, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 541.4337788578372, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 546.2940461725395, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 547.26609963548, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 547.26609963548, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 548.2381530984204, - "y": 418, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 548.2381530984204, - "y": 440, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 548.2381530984204, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 548.2381530984204, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 548.2381530984204, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 548.2381530984204, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 549.2102065613609, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 549.2102065613609, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 549.2102065613609, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 549.2102065613609, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 549.2102065613609, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 551.1543134872418, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 551.1543134872418, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 551.1543134872418, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 551.1543134872418, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 551.1543134872418, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 551.1543134872418, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 418, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 440, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 554.0704738760633, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 374, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 374, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.(*ServeMux).ServeHTTP (3.88 Bil)", - "x": 559.0425273390036, - "y": 385, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 396, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 396, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http.HandlerFunc.ServeHTTP (3.88 Bil)", - "x": 559.0425273390036, - "y": 407, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 418, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 418, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http/pprof.Index (3.88 Bil)", - "x": 559.0425273390036, - "y": 429, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 440, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 376.1567436208992, - "x": 555.5425273390036, - "y": 440, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "net/http/pprof.handler.ServeHTTP (3.88 Bil)", - "x": 559.0425273390036, - "y": 451, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 375.1846901579587, - "x": 555.5425273390036, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 375.1846901579587, - "x": 555.5425273390036, - "y": 462, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.(*Profile).WriteTo (3.87 Bil)", - "x": 559.0425273390036, - "y": 473, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 312.97326852976914, - "x": 555.5425273390036, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 312.97326852976914, - "x": 555.5425273390036, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.writeAlloc (3.23 Bil)", - "x": 559.0425273390036, - "y": 495, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 312.97326852976914, - "x": 555.5425273390036, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 312.97326852976914, - "x": 555.5425273390036, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.writeHeapInternal (3.23 Bil)", - "x": 559.0425273390036, - "y": 517, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 311.0291616038882, - "x": 555.5425273390036, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 311.0291616038882, - "x": 555.5425273390036, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.writeHeapProto (3.21 Bil)", - "x": 559.0425273390036, - "y": 539, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 30.105710814094778, - "x": 555.5425273390036, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 30.105710814094778, - "x": 555.5425273390036, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.(*profileBuilder).pbSample (320 Mil)", - "x": 559.0425273390036, - "y": 561, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 555.0425273390036, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 555.0425273390036, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 555.0425273390036, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 555.0425273390036, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 555.0425273390036, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 858, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 880, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 902, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 924, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 946, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 968, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 990, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 1012, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 1034, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 1056, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 555.0425273390036, - "y": 1078, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 556.0145808019441, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 556.9866342648846, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 558.9307411907655, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 558.9307411907655, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 559.902794653706, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 559.902794653706, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 559.902794653706, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 561.8469015795869, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 561.8469015795869, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 561.8469015795869, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 563.7910085054679, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 566.7071688942892, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 566.7071688942892, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 567.6792223572297, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.720534629404618, - "x": 568.6512758201701, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 568.6512758201701, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 578.3718104495748, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 178.82989064398544, - "x": 586.6482381530984, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 178.82989064398544, - "x": 586.6482381530984, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.(*profileBuilder).appendLocsForStack (1.85 Bil)", - "x": 590.1482381530984, - "y": 561, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 38.85419198055893, - "x": 586.6482381530984, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 38.85419198055893, - "x": 586.6482381530984, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.(*profileBuilder).emitLocation (410 Mil)", - "x": 590.1482381530984, - "y": 583, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 586.6482381530984, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 586.6482381530984, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 586.6482381530984, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 586.6482381530984, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 8.748481166464156, - "x": 586.1482381530984, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 586.1482381530984, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 586.1482381530984, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 586.1482381530984, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 590.0364520048603, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 590.0364520048603, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 590.0364520048603, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 591.9805589307413, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 591.9805589307413, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 591.9805589307413, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 591.9805589307413, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 591.9805589307413, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 592.9526123936816, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 592.9526123936816, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 592.9526123936816, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 592.9526123936816, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 592.9526123936816, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 592.9526123936816, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 592.9526123936816, - "y": 858, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 594.8967193195626, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 594.8967193195626, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 594.8967193195626, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 594.8967193195626, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 595.868772782503, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 596.8408262454435, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 596.8408262454435, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 598.7849331713245, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 599.7569866342649, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 858, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 599.7569866342649, - "y": 880, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 603.6452004860267, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 603.6452004860267, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 607.5334143377886, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 607.5334143377886, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 607.5334143377886, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 607.5334143377886, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 607.5334143377886, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 607.5334143377886, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 607.5334143377886, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 607.5334143377886, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 607.5334143377886, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 607.5334143377886, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 610.44957472661, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 615.3098420413123, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 615.3098420413123, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 618.2260024301337, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 618.2260024301337, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 621.1421628189551, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 622.1142162818956, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 622.1142162818956, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 623.086269744836, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 624.0583232077764, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 14.552855407047389, - "x": 626.5024301336574, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 14.552855407047389, - "x": 626.5024301336574, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 626.5024301336574, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 626.5024301336574, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 626.0024301336574, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.720534629404618, - "x": 627.9465370595383, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 627.9465370595383, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 632.8068043742406, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 633.7788578371811, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 61.211421628189555, - "x": 642.0552855407047, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 61.211421628189555, - "x": 642.0552855407047, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.allFrames (640 Mil)", - "x": 645.5552855407047, - "y": 583, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 641.5552855407047, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 52.462940461725395, - "x": 643.0273390036452, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 52.462940461725395, - "x": 643.0273390036452, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.(*Frames).Next (550 Mil)", - "x": 646.5273390036452, - "y": 605, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 38.85419198055893, - "x": 643.0273390036452, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 38.85419198055893, - "x": 643.0273390036452, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.funcline1 (410 Mil)", - "x": 646.5273390036452, - "y": 627, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 642.5273390036452, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 642.5273390036452, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 24.273390036452007, - "x": 650.803766707169, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 24.273390036452007, - "x": 650.803766707169, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.pcvalue (260 Mil)", - "x": 654.303766707169, - "y": 649, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 650.303766707169, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 652.7478736330498, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 652.7478736330498, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 675.5771567436209, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 675.5771567436209, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 675.5771567436209, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 682.3815309842041, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 682.3815309842041, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 682.3815309842041, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 684.3256379100851, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 685.2976913730256, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 686.269744835966, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 688.213851761847, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 688.213851761847, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 688.213851761847, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 692.1020656136088, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 692.1020656136088, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 695.9902794653706, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 695.9902794653706, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 698.9064398541921, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 27.189550425273392, - "x": 704.2667071688943, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 27.189550425273392, - "x": 704.2667071688943, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.mapaccess2_fast64 (290 Mil)", - "x": 707.7667071688943, - "y": 583, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 8.748481166464156, - "x": 703.7667071688943, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 731.9562575941677, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 731.9562575941677, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 732.9283110571082, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 732.9283110571082, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 732.9283110571082, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 19.413122721749698, - "x": 735.3724179829891, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 19.413122721749698, - "x": 735.3724179829891, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 734.8724179829891, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 734.8724179829891, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 734.8724179829891, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 735.8444714459296, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 737.3165249088701, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 737.3165249088701, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 8.748481166464156, - "x": 736.8165249088701, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 8.748481166464156, - "x": 736.8165249088701, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 736.8165249088701, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 742.6488456865128, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 745.5650060753342, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 745.5650060753342, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 745.5650060753342, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 745.5650060753342, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 745.5650060753342, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 746.5370595382747, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 748.4811664641555, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 748.4811664641555, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 755.2855407047388, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 765.9781287970839, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 26.21749696233293, - "x": 767.4501822600243, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 26.21749696233293, - "x": 767.4501822600243, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.(*profileBuilder).build (280 Mil)", - "x": 770.9501822600243, - "y": 561, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 767.4501822600243, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 767.4501822600243, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 767.4501822600243, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 767.4501822600243, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 767.4501822600243, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 767.4501822600243, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 766.9501822600243, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 766.9501822600243, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 772.7825030376671, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 772.7825030376671, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 858, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 880, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 902, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 772.7825030376671, - "y": 924, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 772.7825030376671, - "y": 946, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 772.7825030376671, - "y": 968, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 772.7825030376671, - "y": 990, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 772.7825030376671, - "y": 1012, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 772.7825030376671, - "y": 1034, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 772.7825030376671, - "y": 1056, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 774.7266099635481, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 777.6427703523694, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 777.6427703523694, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 777.6427703523694, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 858, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 880, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 902, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 924, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 946, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 968, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 990, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 1012, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 1034, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 779.5868772782503, - "y": 1056, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 780.5589307411908, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 782.0309842041313, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 782.0309842041313, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 782.0309842041313, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 782.0309842041313, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 782.0309842041313, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 11.636695018226003, - "x": 782.0309842041313, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 781.5309842041313, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 781.5309842041313, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 784.4471445929527, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 858, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 880, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 902, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 924, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 946, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 968, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 784.4471445929527, - "y": 990, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 785.4191980558932, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 787.363304981774, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 788.3353584447145, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 789.3074119076549, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 793.1956257594168, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 56.35115431348724, - "x": 794.6676792223573, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 56.35115431348724, - "x": 794.6676792223573, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.FuncForPC (590 Mil)", - "x": 798.1676792223573, - "y": 561, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 794.1676792223573, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 794.1676792223573, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 794.1676792223573, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 796.1117861482383, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 800.5, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 800.5, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 800, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 800, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 803.4161603888215, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 10.664641555285542, - "x": 803.4161603888215, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 802.9161603888215, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 7.776427703523694, - "x": 803.8882138517619, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 34.96597812879708, - "x": 815.080801944107, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 34.96597812879708, - "x": 815.080801944107, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.funcline1 (370 Mil)", - "x": 818.580801944107, - "y": 583, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 24.273390036452007, - "x": 815.080801944107, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 24.273390036452007, - "x": 815.080801944107, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.pcvalue (260 Mil)", - "x": 818.580801944107, - "y": 605, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 814.580801944107, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 818.9690157958688, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 13.580801944106927, - "x": 818.9690157958688, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 840.354191980559, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 9.69258809234508, - "x": 840.354191980559, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 8.748481166464156, - "x": 839.854191980559, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 851.5188335358445, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 852.490886998785, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 854.434993924666, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 854.434993924666, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 854.434993924666, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 854.434993924666, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 856.3791008505468, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 856.3791008505468, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 867.0716889428919, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 867.0716889428919, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 61.211421628189555, - "x": 869.5157958687728, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 61.211421628189555, - "x": 869.5157958687728, - "y": 484, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.writeGoroutine (640 Mil)", - "x": 873.0157958687728, - "y": 495, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 61.211421628189555, - "x": 869.5157958687728, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 61.211421628189555, - "x": 869.5157958687728, - "y": 506, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.writeRuntimeProfile (640 Mil)", - "x": 873.0157958687728, - "y": 517, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 23.301336573511545, - "x": 869.5157958687728, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 23.301336573511545, - "x": 869.5157958687728, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.runtime_goroutineProfileWithLabels (250 Mil)", - "x": 873.0157958687728, - "y": 539, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 23.301336573511545, - "x": 869.5157958687728, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 23.301336573511545, - "x": 869.5157958687728, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.goroutineProfileWithLabels (250 Mil)", - "x": 873.0157958687728, - "y": 561, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 21.35722964763062, - "x": 869.5157958687728, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 21.35722964763062, - "x": 869.5157958687728, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.forEachGRace (230 Mil)", - "x": 873.0157958687728, - "y": 583, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 16.496962332928312, - "x": 869.5157958687728, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 16.496962332928312, - "x": 869.5157958687728, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 869.5157958687728, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 869.0157958687728, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 869.0157958687728, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 869.9878493317133, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 869.9878493317133, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 870.9599027946538, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 873.8760631834751, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 873.8760631834751, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 873.8760631834751, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 874.8481166464156, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 879.7083839611179, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 885.5407047387607, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 885.5407047387607, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 885.5407047387607, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 885.5407047387607, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 886.5127582017011, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 886.5127582017011, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 886.5127582017011, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 891.3730255164035, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 892.345078979344, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 892.345078979344, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 892.345078979344, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 892.345078979344, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 36.91008505467801, - "x": 893.8171324422843, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 36.91008505467801, - "x": 893.8171324422843, - "y": 528, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime/pprof.printCountProfile (390 Mil)", - "x": 897.3171324422843, - "y": 539, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 893.3171324422843, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 893.3171324422843, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 893.3171324422843, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 893.3171324422843, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 893.3171324422843, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 893.3171324422843, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 896.2332928311058, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 896.2332928311058, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 897.2053462940462, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 897.2053462940462, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 899.1494532199272, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 899.1494532199272, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 899.1494532199272, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 899.1494532199272, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 899.1494532199272, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 900.1215066828676, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 8.748481166464156, - "x": 902.0656136087485, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 902.0656136087485, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 902.0656136087485, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 5.832320777642771, - "x": 903.037667071689, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 903.037667071689, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 904.0097205346294, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 904.0097205346294, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 904.0097205346294, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 904.0097205346294, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 904.0097205346294, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 904.9817739975699, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 904.9817739975699, - "y": 858, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 906.9258809234508, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 906.9258809234508, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 906.9258809234508, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 908.8699878493318, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 908.8699878493318, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 908.8699878493318, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 909.8420413122723, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 909.8420413122723, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 909.8420413122723, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 16.496962332928312, - "x": 911.3140947752127, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 16.496962332928312, - "x": 911.3140947752127, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 911.3140947752127, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 15.52490886998785, - "x": 911.3140947752127, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 910.8140947752127, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 910.8140947752127, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 910.8140947752127, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 910.8140947752127, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 910.8140947752127, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 910.8140947752127, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 912.7582017010936, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 912.7582017010936, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 913.730255164034, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 913.730255164034, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 914.7023086269745, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 914.7023086269745, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 915.674362089915, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 915.674362089915, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 915.674362089915, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 915.674362089915, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 915.674362089915, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 917.6184690157959, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 917.6184690157959, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 917.6184690157959, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 917.6184690157959, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 917.6184690157959, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 917.6184690157959, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 917.6184690157959, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 8.748481166464156, - "x": 918.5905224787364, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 704, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 726, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 748, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 770, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 792, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 814, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 918.5905224787364, - "y": 836, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 919.5625759416769, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 919.5625759416769, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 919.5625759416769, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 919.5625759416769, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 920.5346294046172, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 920.5346294046172, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 920.5346294046172, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 6.804374240583233, - "x": 920.5346294046172, - "y": 682, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 927.3390036452006, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 928.311057108141, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 928.311057108141, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 928.311057108141, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 928.311057108141, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 928.311057108141, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 929.2831105710815, - "y": 594, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 929.2831105710815, - "y": 616, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 929.2831105710815, - "y": 638, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 929.2831105710815, - "y": 660, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 930.255164034022, - "y": 550, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 930.255164034022, - "y": 572, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 932.1992709599028, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 933.1713244228433, - "y": 308, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 933.1713244228433, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 933.1713244228433, - "y": 352, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 933.1713244228433, - "y": 374, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 934.1433778857838, - "y": 286, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 934.1433778857838, - "y": 308, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 934.1433778857838, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 934.1433778857838, - "y": 352, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 935.1154313487242, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 935.1154313487242, - "y": 352, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 935.1154313487242, - "y": 374, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 935.1154313487242, - "y": 396, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 935.1154313487242, - "y": 418, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 935.1154313487242, - "y": 440, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 936.0874848116647, - "y": 264, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 936.0874848116647, - "y": 286, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 936.0874848116647, - "y": 308, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 936.0874848116647, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 936.0874848116647, - "y": 352, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 936.0874848116647, - "y": 374, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 937.0595382746052, - "y": 220, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 937.0595382746052, - "y": 242, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 937.0595382746052, - "y": 264, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 937.0595382746052, - "y": 286, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 937.0595382746052, - "y": 308, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 938.0315917375456, - "y": 264, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 938.0315917375456, - "y": 286, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 939.0036452004861, - "y": 220, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 939.0036452004861, - "y": 242, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 939.0036452004861, - "y": 264, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 939.0036452004861, - "y": 286, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 1.9441069258809236, - "x": 939.0036452004861, - "y": 308, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 939.0036452004861, - "y": 330, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 940.947752126367, - "y": 44, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 3.888213851761847, - "x": 940.947752126367, - "y": 66, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 940.947752126367, - "y": 88, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 940.947752126367, - "y": 110, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 940.947752126367, - "y": 132, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 940.947752126367, - "y": 154, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 940.947752126367, - "y": 176, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 941.9198055893074, - "y": 88, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 941.9198055893074, - "y": 110, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 941.9198055893074, - "y": 132, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 941.9198055893074, - "y": 154, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 941.9198055893074, - "y": 176, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 941.9198055893074, - "y": 198, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 944.8359659781288, - "y": 44, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 944.8359659781288, - "y": 66, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 600.7010935601459, - "x": 946.3080194410693, - "y": 22, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 600.7010935601459, - "x": 946.3080194410693, - "y": 22, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.gcBgMarkWorker (6.19 Bil)", - "x": 949.8080194410693, - "y": 33, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 598.7569866342649, - "x": 946.3080194410693, - "y": 44, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 598.7569866342649, - "x": 946.3080194410693, - "y": 44, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.systemstack (6.17 Bil)", - "x": 949.8080194410693, - "y": 55, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 598.7569866342649, - "x": 946.3080194410693, - "y": 66, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 598.7569866342649, - "x": 946.3080194410693, - "y": 66, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.gcBgMarkWorker.func2 (6.17 Bil)", - "x": 949.8080194410693, - "y": 77, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 589.0364520048603, - "x": 946.3080194410693, - "y": 88, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 589.0364520048603, - "x": 946.3080194410693, - "y": 88, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.gcDrain (6.07 Bil)", - "x": 949.8080194410693, - "y": 99, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 432.53584447144596, - "x": 946.3080194410693, - "y": 110, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 432.53584447144596, - "x": 946.3080194410693, - "y": 110, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.scanobject (4.46 Bil)", - "x": 949.8080194410693, - "y": 121, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 0.9720534629404618, - "x": 945.8080194410693, - "y": 132, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 4.860267314702309, - "x": 946.7800729040098, - "y": 132, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 41.77035236938032, - "x": 952.140340218712, - "y": 132, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 41.77035236938032, - "x": 952.140340218712, - "y": 132, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.pageIndexOf (440 Mil)", - "x": 955.640340218712, - "y": 143, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, - { - "props": { - "height": 22, - "width": 51.49088699878494, - "x": 994.9106925880924, - "y": 132, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, { "props": { - "height": 22, - "width": 51.49088699878494, - "x": 994.9106925880924, - "y": 132, + "height": 22, + "width": 0.9720534629404618, + "x": 111.7861482381531, + "y": 176, }, "transform": [ 1, @@ -47915,57 +11399,12 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.greyobject (540 Mil)", - "x": 998.4106925880924, - "y": 143, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 994.4106925880924, - "y": 154, + "width": 0.9720534629404618, + "x": 114.70230862697449, + "y": 132, }, "transform": [ 1, @@ -47977,40 +11416,12 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 994.4106925880924, - "y": 176, + "x": 115.67436208991495, + "y": 132, }, "transform": [ 1, @@ -48022,24 +11433,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 116.64641555285542, + "y": 110, + }, "transform": [ 1, 0, @@ -48048,14 +11448,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 995.3827460510329, - "y": 176, + "x": 116.64641555285542, + "y": 132, }, "transform": [ 1, @@ -48067,24 +11467,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 117.61846901579588, + "y": 132, + }, "transform": [ 1, 0, @@ -48093,14 +11482,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 995.3827460510329, - "y": 198, + "x": 118.59052247873633, + "y": 110, }, "transform": [ 1, @@ -48112,23 +11501,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 127.33900364520049, + "y": 110, + }, "transform": [ 1, 0, @@ -48137,13 +11516,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 94.26123936816525, - "x": 1047.4015795868772, + "width": 5.832320777642771, + "x": 127.33900364520049, "y": 132, }, "transform": [ @@ -48156,24 +11535,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 127.33900364520049, + "y": 154, + }, "transform": [ 1, 0, @@ -48182,14 +11550,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 94.26123936816525, - "x": 1047.4015795868772, - "y": 132, + "width": 1.9441069258809236, + "x": 128.31105710814094, + "y": 154, }, "transform": [ 1, @@ -48201,41 +11569,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.findObject (980 Mil)", - "x": 1050.9015795868772, - "y": 143, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 128.31105710814094, + "y": 176, + }, "transform": [ 1, 0, @@ -48244,13 +11584,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1046.9015795868772, + "width": 1.9441069258809236, + "x": 130.25516403402187, "y": 154, }, "transform": [ @@ -48263,24 +11603,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 133.17132442284327, + "y": 132, + }, "transform": [ 1, 0, @@ -48289,13 +11618,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1142.1628189550427, + "width": 0.9720534629404618, + "x": 134.14337788578374, "y": 132, }, "transform": [ @@ -48308,23 +11637,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 135.1154313487242, + "y": 110, + }, "transform": [ 1, 0, @@ -48333,13 +11652,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 45.658566221142166, - "x": 1147.523086269745, + "width": 1.9441069258809236, + "x": 135.1154313487242, "y": 132, }, "transform": [ @@ -48352,40 +11671,12 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, { "props": { "height": 22, - "width": 45.658566221142166, - "x": 1147.523086269745, - "y": 132, + "width": 3.888213851761847, + "x": 138.03159173754557, + "y": 88, }, "transform": [ 1, @@ -48397,40 +11688,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.spanOf (480 Mil)", - "x": 1151.023086269745, - "y": 143, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 138.03159173754557, + "y": 110, + }, "transform": [ 1, 0, @@ -48439,13 +11703,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 51.49088699878494, - "x": 1194.181652490887, + "width": 1.9441069258809236, + "x": 138.03159173754557, "y": 132, }, "transform": [ @@ -48458,24 +11722,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 139.9756986634265, + "y": 132, + }, "transform": [ 1, 0, @@ -48484,14 +11737,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 51.49088699878494, - "x": 1194.181652490887, - "y": 132, + "width": 0.9720534629404618, + "x": 140.94775212636696, + "y": 110, }, "transform": [ 1, @@ -48503,41 +11756,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "maxWidth": null, - "text": "runtime.markBits.isMarked (540 Mil)", - "x": 1197.681652490887, - "y": 143, - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fillText", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 141.91980558930743, + "y": 88, + }, "transform": [ 1, 0, @@ -48546,14 +11771,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1246.172539489672, - "y": 132, + "width": 0.9720534629404618, + "x": 141.91980558930743, + "y": 110, }, "transform": [ 1, @@ -48565,23 +11790,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 142.8918590522479, + "y": 110, + }, "transform": [ 1, 0, @@ -48590,43 +11805,32 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 19.413122721749698, - "x": 1379.8438639125152, + "width": 0.9720534629404618, + "x": 143.86391251518833, "y": 110, }, "transform": [ 1, 0, - 0, - 1, - 0, - 0, - ], - "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 147.7521263669502, + "y": 110, + }, "transform": [ 1, 0, @@ -48635,13 +11839,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 19.413122721749698, - "x": 1379.8438639125152, + "width": 4.860267314702309, + "x": 148.72417982989066, "y": 110, }, "transform": [ @@ -48654,24 +11858,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 148.72417982989066, + "y": 132, + }, "transform": [ 1, 0, @@ -48680,13 +11873,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1399.7569866342649, + "width": 6.804374240583233, + "x": 153.58444714459296, "y": 110, }, "transform": [ @@ -48699,24 +11892,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 153.58444714459296, + "y": 132, + }, "transform": [ 1, 0, @@ -48725,14 +11907,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1399.7569866342649, - "y": 132, + "width": 3.888213851761847, + "x": 160.3888213851762, + "y": 88, }, "transform": [ 1, @@ -48744,24 +11926,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 168.16524908869988, + "y": 110, + }, "transform": [ 1, 0, @@ -48770,14 +11941,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1402.6731470230864, - "y": 110, + "width": 0.9720534629404618, + "x": 168.16524908869988, + "y": 132, }, "transform": [ 1, @@ -48789,23 +11960,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 169.13730255164035, + "y": 132, + }, "transform": [ 1, 0, @@ -48814,14 +11975,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 16.496962332928312, - "x": 1409.005467800729, - "y": 110, + "width": 4.860267314702309, + "x": 173.0255164034022, + "y": 154, }, "transform": [ 1, @@ -48833,24 +11994,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 173.0255164034022, + "y": 176, + }, "transform": [ 1, 0, @@ -48859,14 +12009,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 16.496962332928312, - "x": 1409.005467800729, - "y": 110, + "width": 0.9720534629404618, + "x": 173.0255164034022, + "y": 198, }, "transform": [ 1, @@ -48878,24 +12028,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 174.9696233292831, + "y": 176, + }, "transform": [ 1, 0, @@ -48904,14 +12043,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1426.0024301336575, - "y": 110, + "x": 175.94167679222357, + "y": 176, }, "transform": [ 1, @@ -48923,23 +12062,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 177.8857837181045, + "y": 154, + }, "transform": [ 1, 0, @@ -48948,14 +12077,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 19.413122721749698, - "x": 1427.4744835965978, - "y": 110, + "width": 1.9441069258809236, + "x": 177.8857837181045, + "y": 176, }, "transform": [ 1, @@ -48967,24 +12096,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 179.82989064398544, + "y": 176, + }, "transform": [ 1, 0, @@ -48993,14 +12111,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 19.413122721749698, - "x": 1427.4744835965978, - "y": 110, + "width": 5.832320777642771, + "x": 185.6622114216282, + "y": 132, }, "transform": [ 1, @@ -49012,24 +12130,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 185.6622114216282, + "y": 154, + }, "transform": [ 1, 0, @@ -49038,13 +12145,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1447.3876063183475, + "width": 0.9720534629404618, + "x": 316.88942891859057, "y": 110, }, "transform": [ @@ -49057,24 +12164,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 317.861482381531, + "y": 110, + }, "transform": [ 1, 0, @@ -49083,14 +12179,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1447.3876063183475, - "y": 132, + "width": 0.9720534629404618, + "x": 320.7776427703524, + "y": 110, }, "transform": [ 1, @@ -49102,24 +12198,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 321.74969623329287, + "y": 110, + }, "transform": [ 1, 0, @@ -49128,14 +12213,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1447.3876063183475, - "y": 154, + "width": 5.832320777642771, + "x": 322.7217496962333, + "y": 110, }, "transform": [ 1, @@ -49147,24 +12232,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 328.5540704738761, + "y": 110, + }, "transform": [ 1, 0, @@ -49173,13 +12247,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 9.720534629404618, - "x": 1535.8444714459297, + "x": 333.4143377885784, "y": 88, }, "transform": [ @@ -49192,24 +12266,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 333.4143377885784, + "y": 110, + }, "transform": [ 1, 0, @@ -49218,14 +12281,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1545.5650060753342, - "y": 44, + "width": 0.9720534629404618, + "x": 333.4143377885784, + "y": 132, }, "transform": [ 1, @@ -49237,24 +12300,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 337.30255164034025, + "y": 110, + }, "transform": [ 1, 0, @@ -49263,14 +12315,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1545.5650060753342, - "y": 66, + "width": 3.888213851761847, + "x": 343.134872417983, + "y": 88, }, "transform": [ 1, @@ -49282,24 +12334,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 343.134872417983, + "y": 110, + }, "transform": [ 1, 0, @@ -49308,14 +12349,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1545.5650060753342, - "y": 88, + "x": 343.134872417983, + "y": 132, }, "transform": [ 1, @@ -49327,24 +12368,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 6.804374240583233, + "x": 347.02308626974485, + "y": 66, + }, "transform": [ 1, 0, @@ -49353,14 +12383,31 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1545.5650060753342, - "y": 110, + "x": 347.02308626974485, + "y": 88, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + { + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 347.9951397326853, + "y": 88, }, "transform": [ 1, @@ -49372,24 +12419,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 347.9951397326853, + "y": 110, + }, "transform": [ 1, 0, @@ -49398,14 +12434,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1545.5650060753342, - "y": 132, + "x": 352.85540704738764, + "y": 88, }, "transform": [ 1, @@ -49417,24 +12453,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 353.8274605103281, + "y": 66, + }, "transform": [ 1, 0, @@ -49443,13 +12468,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1546.5370595382747, + "width": 1.9441069258809236, + "x": 353.8274605103281, "y": 88, }, "transform": [ @@ -49462,24 +12487,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 355.771567436209, + "y": 88, + }, "transform": [ 1, 0, @@ -49488,14 +12502,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1546.5370595382747, - "y": 110, + "x": 356.74362089914945, + "y": 66, }, "transform": [ 1, @@ -49507,24 +12521,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 357.71567436208994, + "y": 66, + }, "transform": [ 1, 0, @@ -49533,14 +12536,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1546.5370595382747, - "y": 132, + "width": 1.9441069258809236, + "x": 357.71567436208994, + "y": 88, }, "transform": [ 1, @@ -49552,24 +12555,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 361.6038882138518, + "y": 88, + }, "transform": [ 1, 0, @@ -49578,14 +12570,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1546.5370595382747, - "y": 154, + "x": 361.6038882138518, + "y": 110, }, "transform": [ 1, @@ -49597,24 +12589,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 363.5479951397327, + "y": 110, + }, "transform": [ 1, 0, @@ -49623,14 +12604,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1546.5370595382747, - "y": 176, + "width": 2.9161603888213854, + "x": 381.044957472661, + "y": 88, }, "transform": [ 1, @@ -49642,24 +12623,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 397.5698663426489, + "y": 66, + }, "transform": [ 1, 0, @@ -49668,14 +12638,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1546.5370595382747, - "y": 198, + "x": 398.5419198055893, + "y": 264, }, "transform": [ 1, @@ -49687,24 +12657,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 399.5139732685298, + "y": 264, + }, "transform": [ 1, 0, @@ -49713,14 +12672,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 3.888213851761847, - "x": 1547.5091130012152, - "y": 22, + "width": 0.9720534629404618, + "x": 401.45808019441074, + "y": 286, }, "transform": [ 1, @@ -49732,24 +12691,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 413.12272174969627, + "y": 264, + }, "transform": [ 1, 0, @@ -49758,14 +12706,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1547.5091130012152, - "y": 44, + "width": 1.9441069258809236, + "x": 415.0668286755772, + "y": 242, }, "transform": [ 1, @@ -49777,24 +12725,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 415.0668286755772, + "y": 264, + }, "transform": [ 1, 0, @@ -49803,14 +12740,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1547.5091130012152, - "y": 66, + "x": 416.03888213851764, + "y": 264, }, "transform": [ 1, @@ -49822,24 +12759,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 417.01093560145813, + "y": 330, + }, "transform": [ 1, 0, @@ -49848,14 +12774,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1547.5091130012152, - "y": 88, + "width": 1.9441069258809236, + "x": 417.01093560145813, + "y": 352, }, "transform": [ 1, @@ -49867,24 +12793,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 424.7873633049818, + "y": 330, + }, "transform": [ 1, 0, @@ -49893,14 +12808,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1547.5091130012152, - "y": 110, + "width": 7.776427703523694, + "x": 428.67557715674366, + "y": 286, }, "transform": [ 1, @@ -49912,24 +12827,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 428.67557715674366, + "y": 308, + }, "transform": [ 1, 0, @@ -49938,14 +12842,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1547.5091130012152, - "y": 132, + "width": 1.9441069258809236, + "x": 428.67557715674366, + "y": 330, }, "transform": [ 1, @@ -49957,24 +12861,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 432.5637910085055, + "y": 308, + }, "transform": [ 1, 0, @@ -49983,14 +12876,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1547.5091130012152, - "y": 154, + "x": 436.4520048602673, + "y": 286, }, "transform": [ 1, @@ -50002,24 +12895,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 437.4240583232078, + "y": 286, + }, "transform": [ 1, 0, @@ -50028,14 +12910,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1547.5091130012152, - "y": 176, + "x": 437.4240583232078, + "y": 308, }, "transform": [ 1, @@ -50047,24 +12929,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 438.39611178614825, + "y": 308, + }, "transform": [ 1, 0, @@ -50073,14 +12944,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 44, + "x": 439.36816524908875, + "y": 308, }, "transform": [ 1, @@ -50092,24 +12963,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 442.2843256379101, + "y": 286, + }, "transform": [ 1, 0, @@ -50118,14 +12978,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 66, + "x": 446.172539489672, + "y": 264, }, "transform": [ 1, @@ -50137,24 +12997,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 446.172539489672, + "y": 286, + }, "transform": [ 1, 0, @@ -50163,14 +13012,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 88, + "width": 0.9720534629404618, + "x": 447.1445929526124, + "y": 286, }, "transform": [ 1, @@ -50182,24 +13031,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 448.1166464155529, + "y": 264, + }, "transform": [ 1, 0, @@ -50208,14 +13046,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 110, + "width": 0.9720534629404618, + "x": 449.08869987849334, + "y": 264, }, "transform": [ 1, @@ -50227,24 +13065,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 451.0328068043743, + "y": 264, + }, "transform": [ 1, 0, @@ -50253,14 +13080,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 132, + "x": 451.0328068043743, + "y": 286, }, "transform": [ 1, @@ -50272,24 +13099,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 452.9769137302552, + "y": 286, + }, "transform": [ 1, 0, @@ -50298,14 +13114,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 154, + "width": 9.720534629404618, + "x": 454.92102065613614, + "y": 264, }, "transform": [ 1, @@ -50317,24 +13133,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 454.92102065613614, + "y": 286, + }, "transform": [ 1, 0, @@ -50343,14 +13148,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 176, + "width": 2.9161603888213854, + "x": 455.8930741190766, + "y": 286, }, "transform": [ 1, @@ -50362,24 +13167,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 464.64155528554073, + "y": 264, + }, "transform": [ 1, 0, @@ -50388,14 +13182,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1548.4811664641556, - "y": 198, + "x": 464.64155528554073, + "y": 286, }, "transform": [ 1, @@ -50407,24 +13201,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 466.58566221142166, + "y": 286, + }, "transform": [ 1, 0, @@ -50433,14 +13216,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1550.4252733900366, - "y": 44, + "x": 472.4179829890644, + "y": 264, }, "transform": [ 1, @@ -50452,24 +13235,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 473.3900364520049, + "y": 264, + }, "transform": [ 1, 0, @@ -50478,14 +13250,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1550.4252733900366, - "y": 66, + "x": 473.3900364520049, + "y": 286, }, "transform": [ 1, @@ -50497,24 +13269,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 474.36208991494533, + "y": 286, + }, "transform": [ 1, 0, @@ -50523,14 +13284,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1550.4252733900366, - "y": 88, + "x": 477.27825030376675, + "y": 264, }, "transform": [ 1, @@ -50542,24 +13303,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 478.2503037667072, + "y": 264, + }, "transform": [ 1, 0, @@ -50568,14 +13318,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1550.4252733900366, - "y": 110, + "x": 480.1944106925881, + "y": 264, }, "transform": [ 1, @@ -50587,24 +13337,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 481.16646415552856, + "y": 264, + }, "transform": [ 1, 0, @@ -50613,14 +13352,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1550.4252733900366, - "y": 132, + "x": 483.1105710814095, + "y": 264, }, "transform": [ 1, @@ -50632,39 +13371,12 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ - { - "props": {}, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "beginPath", - }, { "props": { "height": 22, - "width": 15.52490886998785, - "x": 1551.897326852977, - "y": 22, + "width": 0.9720534629404618, + "x": 486.99878493317135, + "y": 242, }, "transform": [ 1, @@ -50676,24 +13388,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 487.9708383961118, + "y": 264, + }, "transform": [ 1, 0, @@ -50702,14 +13403,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 15.52490886998785, - "x": 1551.897326852977, - "y": 22, + "width": 1.9441069258809236, + "x": 487.9708383961118, + "y": 286, }, "transform": [ 1, @@ -50721,23 +13422,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 487.9708383961118, + "y": 308, + }, "transform": [ 1, 0, @@ -50746,14 +13437,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 14.552855407047389, - "x": 1551.897326852977, - "y": 44, + "width": 0.9720534629404618, + "x": 489.9149453219927, + "y": 286, }, "transform": [ 1, @@ -50765,24 +13456,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 493.8031591737546, + "y": 264, + }, "transform": [ 1, 0, @@ -50791,14 +13471,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 14.552855407047389, - "x": 1551.897326852977, - "y": 44, + "width": 0.9720534629404618, + "x": 498.6634264884569, + "y": 242, }, "transform": [ 1, @@ -50810,24 +13490,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 499.6354799513974, + "y": 264, + }, "transform": [ 1, 0, @@ -50836,14 +13505,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 6.804374240583233, - "x": 1551.397326852977, - "y": 66, + "width": 0.9720534629404618, + "x": 500.6075334143378, + "y": 286, }, "transform": [ 1, @@ -50855,24 +13524,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 501.5795868772783, + "y": 286, + }, "transform": [ 1, 0, @@ -50881,14 +13539,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { - "height": 22, - "width": 2.9161603888213854, - "x": 1558.2017010935601, - "y": 66, + "height": 22, + "width": 4.860267314702309, + "x": 502.55164034021874, + "y": 286, }, "transform": [ 1, @@ -50900,24 +13558,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 514.2162818955043, + "y": 264, + }, "transform": [ 1, 0, @@ -50926,14 +13573,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1558.2017010935601, - "y": 88, + "width": 3.888213851761847, + "x": 514.2162818955043, + "y": 286, }, "transform": [ 1, @@ -50945,24 +13592,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 514.2162818955043, + "y": 308, + }, "transform": [ 1, 0, @@ -50971,14 +13607,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 3.888213851761847, - "x": 1561.1178614823816, - "y": 66, + "width": 0.9720534629404618, + "x": 518.1044957472661, + "y": 286, }, "transform": [ 1, @@ -50990,24 +13626,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 521.992709599028, + "y": 264, + }, "transform": [ 1, 0, @@ -51016,14 +13641,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1566.9501822600243, - "y": 44, + "x": 521.992709599028, + "y": 286, }, "transform": [ 1, @@ -51035,23 +13660,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 522.9647630619685, + "y": 286, + }, "transform": [ 1, 0, @@ -51060,14 +13675,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 15.52490886998785, - "x": 1568.4222357229648, - "y": 22, + "width": 1.9441069258809236, + "x": 523.9368165249089, + "y": 264, }, "transform": [ 1, @@ -51079,24 +13694,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "stroke", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 527.8250303766707, + "y": 264, + }, "transform": [ 1, 0, @@ -51105,14 +13709,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 15.52490886998785, - "x": 1568.4222357229648, - "y": 22, + "width": 3.888213851761847, + "x": 527.8250303766707, + "y": 286, }, "transform": [ 1, @@ -51124,24 +13728,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 527.8250303766707, + "y": 308, + }, "transform": [ 1, 0, @@ -51150,14 +13743,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 8.748481166464156, - "x": 1567.9222357229648, - "y": 44, + "width": 0.9720534629404618, + "x": 528.7970838396112, + "y": 308, }, "transform": [ 1, @@ -51169,24 +13762,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 531.7132442284326, + "y": 286, + }, "transform": [ 1, 0, @@ -51195,14 +13777,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 8.748481166464156, - "x": 1567.9222357229648, - "y": 66, + "width": 2.9161603888213854, + "x": 539.4896719319563, + "y": 242, }, "transform": [ 1, @@ -51214,24 +13796,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 539.4896719319563, + "y": 264, + }, "transform": [ 1, 0, @@ -51240,14 +13811,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 6.804374240583233, - "x": 1567.9222357229648, - "y": 88, + "width": 0.9720534629404618, + "x": 541.4337788578372, + "y": 264, }, "transform": [ 1, @@ -51259,24 +13830,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 546.2940461725395, + "y": 220, + }, "transform": [ 1, 0, @@ -51285,14 +13845,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1567.9222357229648, - "y": 110, + "width": 0.9720534629404618, + "x": 547.26609963548, + "y": 220, }, "transform": [ 1, @@ -51304,24 +13864,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 548.2381530984204, + "y": 198, + }, "transform": [ 1, 0, @@ -51330,14 +13879,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1567.9222357229648, - "y": 132, + "width": 2.9161603888213854, + "x": 548.2381530984204, + "y": 220, }, "transform": [ 1, @@ -51349,24 +13898,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 548.2381530984204, + "y": 242, + }, "transform": [ 1, 0, @@ -51375,14 +13913,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1569.8663426488458, - "y": 110, + "width": 1.9441069258809236, + "x": 549.2102065613609, + "y": 242, }, "transform": [ 1, @@ -51394,24 +13932,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 551.1543134872418, + "y": 220, + }, "transform": [ 1, 0, @@ -51420,14 +13947,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1569.8663426488458, - "y": 132, + "width": 0.9720534629404618, + "x": 554.0704738760633, + "y": 198, }, "transform": [ 1, @@ -51439,24 +13966,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 6.804374240583233, + "x": 555.0425273390036, + "y": 264, + }, "transform": [ 1, 0, @@ -51465,14 +13981,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1569.8663426488458, - "y": 154, + "width": 3.888213851761847, + "x": 555.0425273390036, + "y": 286, }, "transform": [ 1, @@ -51484,24 +14000,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 555.0425273390036, + "y": 308, + }, "transform": [ 1, 0, @@ -51510,14 +14015,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1569.8663426488458, - "y": 176, + "width": 0.9720534629404618, + "x": 555.0425273390036, + "y": 330, }, "transform": [ 1, @@ -51529,24 +14034,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 556.0145808019441, + "y": 330, + }, "transform": [ 1, 0, @@ -51555,14 +14049,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1572.782503037667, - "y": 110, + "width": 1.9441069258809236, + "x": 556.9866342648846, + "y": 308, }, "transform": [ 1, @@ -51574,24 +14068,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 558.9307411907655, + "y": 286, + }, "transform": [ 1, 0, @@ -51600,14 +14083,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1573.7545565006076, - "y": 110, + "x": 558.9307411907655, + "y": 308, }, "transform": [ 1, @@ -51618,25 +14101,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, ], "type": "rect", - }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ + }, { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 559.902794653706, + "y": 308, + }, "transform": [ 1, 0, @@ -51645,14 +14117,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1573.7545565006076, - "y": 132, + "width": 6.804374240583233, + "x": 561.8469015795869, + "y": 264, }, "transform": [ 1, @@ -51664,24 +14136,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 561.8469015795869, + "y": 286, + }, "transform": [ 1, 0, @@ -51690,14 +14151,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1573.7545565006076, - "y": 154, + "width": 1.9441069258809236, + "x": 561.8469015795869, + "y": 308, }, "transform": [ 1, @@ -51709,24 +14170,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 563.7910085054679, + "y": 308, + }, "transform": [ 1, 0, @@ -51735,14 +14185,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1574.726609963548, - "y": 88, + "x": 566.7071688942892, + "y": 308, }, "transform": [ 1, @@ -51754,24 +14204,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 567.6792223572297, + "y": 286, + }, "transform": [ 1, 0, @@ -51780,14 +14219,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1574.726609963548, - "y": 110, + "width": 9.720534629404618, + "x": 568.6512758201701, + "y": 264, }, "transform": [ 1, @@ -51799,24 +14238,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 568.6512758201701, + "y": 286, + }, "transform": [ 1, 0, @@ -51825,14 +14253,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1574.726609963548, - "y": 132, + "width": 4.860267314702309, + "x": 578.3718104495748, + "y": 264, }, "transform": [ 1, @@ -51844,24 +14272,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 8.748481166464156, + "x": 586.1482381530984, + "y": 308, + }, "transform": [ 1, 0, @@ -51870,14 +14287,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1575.6986634264886, - "y": 88, + "width": 5.832320777642771, + "x": 586.1482381530984, + "y": 330, }, "transform": [ 1, @@ -51889,24 +14306,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 586.1482381530984, + "y": 352, + }, "transform": [ 1, 0, @@ -51915,14 +14321,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 7.776427703523694, - "x": 1576.670716889429, - "y": 44, + "width": 1.9441069258809236, + "x": 590.0364520048603, + "y": 352, }, "transform": [ 1, @@ -51934,24 +14340,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 591.9805589307413, + "y": 330, + }, "transform": [ 1, 0, @@ -51960,14 +14355,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1576.670716889429, - "y": 66, + "x": 591.9805589307413, + "y": 352, }, "transform": [ 1, @@ -51979,24 +14374,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 592.9526123936816, + "y": 352, + }, "transform": [ 1, 0, @@ -52005,14 +14389,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1576.670716889429, - "y": 88, + "x": 592.9526123936816, + "y": 374, }, "transform": [ 1, @@ -52024,24 +14408,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 594.8967193195626, + "y": 308, + }, "transform": [ 1, 0, @@ -52050,14 +14423,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 6.804374240583233, - "x": 1577.6427703523696, - "y": 66, + "width": 0.9720534629404618, + "x": 594.8967193195626, + "y": 330, }, "transform": [ 1, @@ -52069,24 +14442,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 595.868772782503, + "y": 330, + }, "transform": [ 1, 0, @@ -52095,14 +14457,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1577.6427703523696, - "y": 88, + "width": 2.9161603888213854, + "x": 596.8408262454435, + "y": 286, }, "transform": [ 1, @@ -52114,24 +14476,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 596.8408262454435, + "y": 308, + }, "transform": [ 1, 0, @@ -52140,14 +14491,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1577.6427703523696, - "y": 110, + "x": 598.7849331713245, + "y": 308, }, "transform": [ 1, @@ -52159,24 +14510,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 599.7569866342649, + "y": 286, + }, "transform": [ 1, 0, @@ -52185,14 +14525,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1577.6427703523696, - "y": 132, + "x": 599.7569866342649, + "y": 308, }, "transform": [ 1, @@ -52204,24 +14544,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 603.6452004860267, + "y": 286, + }, "transform": [ 1, 0, @@ -52230,14 +14559,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1578.6148238153098, - "y": 110, + "width": 0.9720534629404618, + "x": 603.6452004860267, + "y": 308, }, "transform": [ 1, @@ -52249,24 +14578,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 607.5334143377886, + "y": 286, + }, "transform": [ 1, 0, @@ -52275,14 +14593,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1580.5589307411908, - "y": 110, + "width": 2.9161603888213854, + "x": 607.5334143377886, + "y": 308, }, "transform": [ 1, @@ -52294,24 +14612,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 607.5334143377886, + "y": 330, + }, "transform": [ 1, 0, @@ -52320,14 +14627,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1580.5589307411908, - "y": 132, + "x": 610.44957472661, + "y": 308, }, "transform": [ 1, @@ -52339,24 +14646,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 615.3098420413123, + "y": 286, + }, "transform": [ 1, 0, @@ -52365,14 +14661,31 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1583.4750911300123, - "y": 88, + "width": 2.9161603888213854, + "x": 615.3098420413123, + "y": 308, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + { + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 618.2260024301337, + "y": 308, }, "transform": [ 1, @@ -52384,24 +14697,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 618.2260024301337, + "y": 330, + }, "transform": [ 1, 0, @@ -52410,14 +14712,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 7.776427703523694, - "x": 1584.4471445929528, - "y": 22, + "width": 0.9720534629404618, + "x": 621.1421628189551, + "y": 286, }, "transform": [ 1, @@ -52429,24 +14731,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 622.1142162818956, + "y": 286, + }, "transform": [ 1, 0, @@ -52455,14 +14746,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1584.4471445929528, - "y": 44, + "x": 623.086269744836, + "y": 286, }, "transform": [ 1, @@ -52474,24 +14765,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 624.0583232077764, + "y": 286, + }, "transform": [ 1, 0, @@ -52500,14 +14780,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1584.4471445929528, - "y": 66, + "width": 1.9441069258809236, + "x": 626.0024301336574, + "y": 308, }, "transform": [ 1, @@ -52519,24 +14799,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 9.720534629404618, + "x": 627.9465370595383, + "y": 308, + }, "transform": [ 1, 0, @@ -52545,14 +14814,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1584.4471445929528, - "y": 88, + "width": 4.860267314702309, + "x": 627.9465370595383, + "y": 330, }, "transform": [ 1, @@ -52564,24 +14833,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 632.8068043742406, + "y": 330, + }, "transform": [ 1, 0, @@ -52590,14 +14848,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1584.4471445929528, - "y": 110, + "x": 633.7788578371811, + "y": 330, }, "transform": [ 1, @@ -52609,24 +14867,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 641.5552855407047, + "y": 286, + }, "transform": [ 1, 0, @@ -52635,14 +14882,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1584.4471445929528, - "y": 132, + "width": 7.776427703523694, + "x": 642.5273390036452, + "y": 330, }, "transform": [ 1, @@ -52654,24 +14901,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 642.5273390036452, + "y": 352, + }, "transform": [ 1, 0, @@ -52680,14 +14916,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 44, + "x": 650.303766707169, + "y": 352, }, "transform": [ 1, @@ -52699,24 +14935,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 675.5771567436209, + "y": 330, + }, "transform": [ 1, 0, @@ -52725,14 +14950,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 66, + "width": 2.9161603888213854, + "x": 675.5771567436209, + "y": 352, }, "transform": [ 1, @@ -52744,24 +14969,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 675.5771567436209, + "y": 374, + }, "transform": [ 1, 0, @@ -52770,14 +14984,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 88, + "x": 682.3815309842041, + "y": 308, }, "transform": [ 1, @@ -52789,24 +15003,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 682.3815309842041, + "y": 330, + }, "transform": [ 1, 0, @@ -52815,14 +15018,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 110, + "width": 0.9720534629404618, + "x": 684.3256379100851, + "y": 308, }, "transform": [ 1, @@ -52834,24 +15037,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 685.2976913730256, + "y": 308, + }, "transform": [ 1, 0, @@ -52860,14 +15052,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 132, + "x": 686.269744835966, + "y": 308, }, "transform": [ 1, @@ -52879,24 +15071,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 688.213851761847, + "y": 308, + }, "transform": [ 1, 0, @@ -52905,14 +15086,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 154, + "width": 3.888213851761847, + "x": 688.213851761847, + "y": 330, }, "transform": [ 1, @@ -52924,24 +15105,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 688.213851761847, + "y": 352, + }, "transform": [ 1, 0, @@ -52950,14 +15120,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 176, + "width": 0.9720534629404618, + "x": 692.1020656136088, + "y": 330, }, "transform": [ 1, @@ -52969,24 +15139,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 6.804374240583233, + "x": 695.9902794653706, + "y": 286, + }, "transform": [ 1, 0, @@ -52995,14 +15154,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 198, + "width": 2.9161603888213854, + "x": 695.9902794653706, + "y": 308, }, "transform": [ 1, @@ -53014,24 +15173,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 698.9064398541921, + "y": 308, + }, "transform": [ 1, 0, @@ -53040,14 +15188,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 220, + "width": 8.748481166464156, + "x": 703.7667071688943, + "y": 286, }, "transform": [ 1, @@ -53059,24 +15207,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 731.9562575941677, + "y": 264, + }, "transform": [ 1, 0, @@ -53085,14 +15222,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 242, + "width": 0.9720534629404618, + "x": 731.9562575941677, + "y": 286, }, "transform": [ 1, @@ -53104,24 +15241,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 732.9283110571082, + "y": 286, + }, "transform": [ 1, 0, @@ -53130,14 +15256,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 264, + "x": 734.8724179829891, + "y": 286, }, "transform": [ 1, @@ -53149,24 +15275,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 734.8724179829891, + "y": 308, + }, "transform": [ 1, 0, @@ -53175,14 +15290,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 1.9441069258809236, - "x": 1585.419198055893, - "y": 286, + "width": 0.9720534629404618, + "x": 735.8444714459296, + "y": 308, }, "transform": [ 1, @@ -53194,24 +15309,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 8.748481166464156, + "x": 736.8165249088701, + "y": 308, + }, "transform": [ 1, 0, @@ -53220,14 +15324,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1587.363304981774, - "y": 44, + "width": 5.832320777642771, + "x": 736.8165249088701, + "y": 330, }, "transform": [ 1, @@ -53239,24 +15343,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 742.6488456865128, + "y": 330, + }, "transform": [ 1, 0, @@ -53265,14 +15358,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1587.363304981774, - "y": 66, + "width": 2.9161603888213854, + "x": 745.5650060753342, + "y": 308, }, "transform": [ 1, @@ -53284,24 +15377,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 745.5650060753342, + "y": 330, + }, "transform": [ 1, 0, @@ -53310,14 +15392,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1587.363304981774, - "y": 88, + "width": 1.9441069258809236, + "x": 746.5370595382747, + "y": 330, }, "transform": [ 1, @@ -53329,24 +15411,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 748.4811664641555, + "y": 286, + }, "transform": [ 1, 0, @@ -53355,14 +15426,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1587.363304981774, - "y": 110, + "width": 0.9720534629404618, + "x": 748.4811664641555, + "y": 308, }, "transform": [ 1, @@ -53374,24 +15445,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 755.2855407047388, + "y": 264, + }, "transform": [ 1, 0, @@ -53400,14 +15460,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1587.363304981774, - "y": 132, + "width": 0.9720534629404618, + "x": 765.9781287970839, + "y": 242, }, "transform": [ 1, @@ -53419,24 +15479,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 766.9501822600243, + "y": 286, + }, "transform": [ 1, 0, @@ -53445,14 +15494,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 4.860267314702309, - "x": 1587.363304981774, - "y": 154, + "width": 2.9161603888213854, + "x": 766.9501822600243, + "y": 308, }, "transform": [ 1, @@ -53464,24 +15513,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 7.776427703523694, + "x": 772.7825030376671, + "y": 286, + }, "transform": [ 1, 0, @@ -53490,14 +15528,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 4.860267314702309, - "x": 1587.363304981774, - "y": 176, + "x": 772.7825030376671, + "y": 308, }, "transform": [ 1, @@ -53509,24 +15547,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 772.7825030376671, + "y": 330, + }, "transform": [ 1, 0, @@ -53535,14 +15562,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1587.363304981774, - "y": 198, + "x": 772.7825030376671, + "y": 352, }, "transform": [ 1, @@ -53554,24 +15581,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 774.7266099635481, + "y": 330, + }, "transform": [ 1, 0, @@ -53580,14 +15596,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1587.363304981774, - "y": 220, + "width": 1.9441069258809236, + "x": 777.6427703523694, + "y": 308, }, "transform": [ 1, @@ -53599,24 +15615,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 779.5868772782503, + "y": 308, + }, "transform": [ 1, 0, @@ -53625,14 +15630,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1587.363304981774, - "y": 242, + "x": 780.5589307411908, + "y": 286, }, "transform": [ 1, @@ -53644,24 +15649,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 6.804374240583233, + "x": 781.5309842041313, + "y": 286, + }, "transform": [ 1, 0, @@ -53670,14 +15664,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1592.2235722964765, - "y": 22, + "width": 2.9161603888213854, + "x": 781.5309842041313, + "y": 308, }, "transform": [ 1, @@ -53689,24 +15683,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 784.4471445929527, + "y": 308, + }, "transform": [ 1, 0, @@ -53715,14 +15698,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1592.2235722964765, - "y": 44, + "width": 0.9720534629404618, + "x": 784.4471445929527, + "y": 330, }, "transform": [ 1, @@ -53734,24 +15717,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 785.4191980558932, + "y": 330, + }, "transform": [ 1, 0, @@ -53760,14 +15732,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1592.2235722964765, - "y": 66, + "width": 0.9720534629404618, + "x": 787.363304981774, + "y": 308, }, "transform": [ 1, @@ -53779,24 +15751,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 788.3353584447145, + "y": 286, + }, "transform": [ 1, 0, @@ -53805,14 +15766,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1592.2235722964765, - "y": 88, + "width": 3.888213851761847, + "x": 789.3074119076549, + "y": 286, }, "transform": [ 1, @@ -53824,24 +15785,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 793.1956257594168, + "y": 286, + }, "transform": [ 1, 0, @@ -53850,14 +15800,31 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1592.2235722964765, - "y": 110, + "width": 1.9441069258809236, + "x": 794.1676792223573, + "y": 264, + }, + "transform": [ + 1, + 0, + 0, + 1, + 0, + 0, + ], + "type": "rect", + }, + { + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 794.1676792223573, + "y": 286, }, "transform": [ 1, @@ -53869,24 +15836,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 796.1117861482383, + "y": 264, + }, "transform": [ 1, 0, @@ -53895,14 +15851,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1592.2235722964765, - "y": 132, + "width": 2.9161603888213854, + "x": 800, + "y": 286, }, "transform": [ 1, @@ -53914,24 +15870,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 802.9161603888215, + "y": 308, + }, "transform": [ 1, 0, @@ -53940,14 +15885,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 5.832320777642771, - "x": 1592.2235722964765, - "y": 154, + "width": 7.776427703523694, + "x": 803.8882138517619, + "y": 308, }, "transform": [ 1, @@ -53959,24 +15904,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 814.580801944107, + "y": 308, + }, "transform": [ 1, 0, @@ -53985,14 +15919,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 3.888213851761847, - "x": 1592.2235722964765, - "y": 176, + "width": 8.748481166464156, + "x": 839.854191980559, + "y": 308, }, "transform": [ 1, @@ -54004,24 +15938,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 851.5188335358445, + "y": 242, + }, "transform": [ 1, 0, @@ -54030,14 +15953,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 3.888213851761847, - "x": 1592.2235722964765, - "y": 198, + "width": 1.9441069258809236, + "x": 852.490886998785, + "y": 242, }, "transform": [ 1, @@ -54049,24 +15972,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 854.434993924666, + "y": 242, + }, "transform": [ 1, 0, @@ -54075,14 +15987,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1592.2235722964765, - "y": 220, + "width": 6.804374240583233, + "x": 856.3791008505468, + "y": 242, }, "transform": [ 1, @@ -54094,24 +16006,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 856.3791008505468, + "y": 264, + }, "transform": [ 1, 0, @@ -54120,14 +16021,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1592.2235722964765, - "y": 242, + "width": 1.9441069258809236, + "x": 867.0716889428919, + "y": 220, }, "transform": [ 1, @@ -54139,24 +16040,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 869.0157958687728, + "y": 308, + }, "transform": [ 1, 0, @@ -54165,14 +16055,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1592.2235722964765, - "y": 264, + "width": 0.9720534629404618, + "x": 869.0157958687728, + "y": 330, }, "transform": [ 1, @@ -54184,24 +16074,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 869.9878493317133, + "y": 330, + }, "transform": [ 1, 0, @@ -54210,14 +16089,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1592.2235722964765, - "y": 286, + "width": 0.9720534629404618, + "x": 869.9878493317133, + "y": 352, }, "transform": [ 1, @@ -54229,24 +16108,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 870.9599027946538, + "y": 352, + }, "transform": [ 1, 0, @@ -54255,13 +16123,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 2.9161603888213854, - "x": 1592.2235722964765, + "width": 5.832320777642771, + "x": 873.8760631834751, "y": 308, }, "transform": [ @@ -54274,24 +16142,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 873.8760631834751, + "y": 330, + }, "transform": [ 1, 0, @@ -54300,13 +16157,13 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 2.9161603888213854, - "x": 1592.2235722964765, + "x": 874.8481166464156, "y": 330, }, "transform": [ @@ -54319,24 +16176,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 879.7083839611179, + "y": 308, + }, "transform": [ 1, 0, @@ -54345,14 +16191,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 352, + "x": 885.5407047387607, + "y": 286, }, "transform": [ 1, @@ -54364,24 +16210,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 886.5127582017011, + "y": 264, + }, "transform": [ 1, 0, @@ -54390,14 +16225,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 374, + "width": 1.9441069258809236, + "x": 886.5127582017011, + "y": 286, }, "transform": [ 1, @@ -54409,24 +16244,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 891.3730255164035, + "y": 242, + }, "transform": [ 1, 0, @@ -54435,14 +16259,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 396, + "x": 892.345078979344, + "y": 242, }, "transform": [ 1, @@ -54454,24 +16278,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 893.3171324422843, + "y": 242, + }, "transform": [ 1, 0, @@ -54480,14 +16293,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 418, + "width": 3.888213851761847, + "x": 893.3171324422843, + "y": 264, }, "transform": [ 1, @@ -54499,24 +16312,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 893.3171324422843, + "y": 286, + }, "transform": [ 1, 0, @@ -54525,14 +16327,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 440, + "width": 1.9441069258809236, + "x": 893.3171324422843, + "y": 308, }, "transform": [ 1, @@ -54544,24 +16346,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 893.3171324422843, + "y": 330, + }, "transform": [ 1, 0, @@ -54570,14 +16361,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 462, + "x": 896.2332928311058, + "y": 286, }, "transform": [ 1, @@ -54589,24 +16380,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 897.2053462940462, + "y": 264, + }, "transform": [ 1, 0, @@ -54615,14 +16395,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 484, + "width": 2.9161603888213854, + "x": 899.1494532199272, + "y": 242, }, "transform": [ 1, @@ -54634,24 +16414,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 899.1494532199272, + "y": 264, + }, "transform": [ 1, 0, @@ -54660,14 +16429,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1592.2235722964765, - "y": 506, + "x": 900.1215066828676, + "y": 264, }, "transform": [ 1, @@ -54679,24 +16448,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 8.748481166464156, + "x": 902.0656136087485, + "y": 242, + }, "transform": [ 1, 0, @@ -54705,14 +16463,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1593.1956257594168, - "y": 352, + "x": 902.0656136087485, + "y": 264, }, "transform": [ 1, @@ -54724,24 +16482,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 903.037667071689, + "y": 264, + }, "transform": [ 1, 0, @@ -54750,14 +16497,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1593.1956257594168, - "y": 374, + "x": 903.037667071689, + "y": 286, }, "transform": [ 1, @@ -54769,24 +16516,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 904.0097205346294, + "y": 286, + }, "transform": [ 1, 0, @@ -54795,14 +16531,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1593.1956257594168, - "y": 396, + "width": 2.9161603888213854, + "x": 904.0097205346294, + "y": 308, }, "transform": [ 1, @@ -54814,24 +16550,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 904.0097205346294, + "y": 330, + }, "transform": [ 1, 0, @@ -54840,14 +16565,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1593.1956257594168, - "y": 418, + "x": 904.9817739975699, + "y": 330, }, "transform": [ 1, @@ -54859,24 +16584,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 906.9258809234508, + "y": 308, + }, "transform": [ 1, 0, @@ -54885,14 +16599,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 352, + "width": 1.9441069258809236, + "x": 908.8699878493318, + "y": 264, }, "transform": [ 1, @@ -54904,24 +16618,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 908.8699878493318, + "y": 286, + }, "transform": [ 1, 0, @@ -54930,14 +16633,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 374, + "x": 909.8420413122723, + "y": 286, }, "transform": [ 1, @@ -54949,24 +16652,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 910.8140947752127, + "y": 286, + }, "transform": [ 1, 0, @@ -54975,14 +16667,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 396, + "width": 1.9441069258809236, + "x": 910.8140947752127, + "y": 308, }, "transform": [ 1, @@ -54994,24 +16686,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 910.8140947752127, + "y": 330, + }, "transform": [ 1, 0, @@ -55020,14 +16701,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 418, + "x": 912.7582017010936, + "y": 308, }, "transform": [ 1, @@ -55039,24 +16720,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 913.730255164034, + "y": 308, + }, "transform": [ 1, 0, @@ -55065,14 +16735,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 440, + "x": 914.7023086269745, + "y": 308, }, "transform": [ 1, @@ -55084,24 +16754,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 915.674362089915, + "y": 286, + }, "transform": [ 1, 0, @@ -55110,14 +16769,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 462, + "width": 1.9441069258809236, + "x": 915.674362089915, + "y": 308, }, "transform": [ 1, @@ -55129,24 +16788,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 917.6184690157959, + "y": 308, + }, "transform": [ 1, 0, @@ -55155,14 +16803,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 484, + "width": 8.748481166464156, + "x": 918.5905224787364, + "y": 286, }, "transform": [ 1, @@ -55174,24 +16822,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 918.5905224787364, + "y": 308, + }, "transform": [ 1, 0, @@ -55200,14 +16837,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1594.1676792223573, - "y": 506, + "x": 919.5625759416769, + "y": 308, }, "transform": [ 1, @@ -55219,24 +16856,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 6.804374240583233, + "x": 920.5346294046172, + "y": 308, + }, "transform": [ 1, 0, @@ -55245,14 +16871,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 176, + "x": 927.3390036452006, + "y": 264, }, "transform": [ 1, @@ -55264,24 +16890,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 928.311057108141, + "y": 242, + }, "transform": [ 1, 0, @@ -55290,14 +16905,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 198, + "x": 928.311057108141, + "y": 264, }, "transform": [ 1, @@ -55309,24 +16924,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 929.2831105710815, + "y": 264, + }, "transform": [ 1, 0, @@ -55335,14 +16939,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 220, + "x": 930.255164034022, + "y": 242, }, "transform": [ 1, @@ -55354,24 +16958,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 932.1992709599028, + "y": 154, + }, "transform": [ 1, 0, @@ -55380,14 +16973,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 242, + "x": 933.1713244228433, + "y": 132, }, "transform": [ 1, @@ -55399,24 +16992,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 934.1433778857838, + "y": 110, + }, "transform": [ 1, 0, @@ -55425,14 +17007,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 264, + "x": 934.1433778857838, + "y": 132, }, "transform": [ 1, @@ -55444,24 +17026,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 935.1154313487242, + "y": 132, + }, "transform": [ 1, 0, @@ -55470,14 +17041,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 286, + "x": 936.0874848116647, + "y": 88, }, "transform": [ 1, @@ -55489,24 +17060,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 937.0595382746052, + "y": 66, + }, "transform": [ 1, 0, @@ -55515,14 +17075,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 308, + "x": 937.0595382746052, + "y": 88, }, "transform": [ 1, @@ -55534,24 +17094,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 938.0315917375456, + "y": 88, + }, "transform": [ 1, 0, @@ -55560,14 +17109,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 330, + "width": 1.9441069258809236, + "x": 939.0036452004861, + "y": 66, }, "transform": [ 1, @@ -55579,24 +17128,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 939.0036452004861, + "y": 88, + }, "transform": [ 1, 0, @@ -55605,14 +17143,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 352, + "width": 3.888213851761847, + "x": 940.947752126367, + "y": 44, }, "transform": [ 1, @@ -55624,24 +17162,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 940.947752126367, + "y": 66, + }, "transform": [ 1, 0, @@ -55650,14 +17177,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 374, + "width": 2.9161603888213854, + "x": 941.9198055893074, + "y": 66, }, "transform": [ 1, @@ -55669,24 +17196,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 944.8359659781288, + "y": 44, + }, "transform": [ 1, 0, @@ -55695,14 +17211,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 396, + "x": 945.8080194410693, + "y": 110, }, "transform": [ 1, @@ -55714,24 +17230,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 946.7800729040098, + "y": 110, + }, "transform": [ 1, 0, @@ -55740,14 +17245,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 418, + "width": 1.9441069258809236, + "x": 994.4106925880924, + "y": 132, }, "transform": [ 1, @@ -55759,24 +17264,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 994.4106925880924, + "y": 154, + }, "transform": [ 1, 0, @@ -55785,14 +17279,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 440, + "x": 995.3827460510329, + "y": 154, }, "transform": [ 1, @@ -55804,24 +17298,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1046.9015795868772, + "y": 132, + }, "transform": [ 1, 0, @@ -55830,14 +17313,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 462, + "width": 4.860267314702309, + "x": 1142.1628189550427, + "y": 110, }, "transform": [ 1, @@ -55849,24 +17332,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 1246.172539489672, + "y": 110, + }, "transform": [ 1, 0, @@ -55875,14 +17347,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 484, + "width": 2.9161603888213854, + "x": 1399.7569866342649, + "y": 88, }, "transform": [ 1, @@ -55894,24 +17366,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 1402.6731470230864, + "y": 88, + }, "transform": [ 1, 0, @@ -55920,14 +17381,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1596.1117861482383, - "y": 506, + "x": 1426.0024301336575, + "y": 88, }, "transform": [ 1, @@ -55939,24 +17400,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 1447.3876063183475, + "y": 88, + }, "transform": [ 1, 0, @@ -55965,14 +17415,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1597.0838396111787, - "y": 176, + "width": 9.720534629404618, + "x": 1535.8444714459297, + "y": 66, }, "transform": [ 1, @@ -55984,24 +17434,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 1545.5650060753342, + "y": 44, + }, "transform": [ 1, 0, @@ -56010,14 +17449,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1597.0838396111787, - "y": 198, + "x": 1545.5650060753342, + "y": 66, }, "transform": [ 1, @@ -56029,24 +17468,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1546.5370595382747, + "y": 66, + }, "transform": [ 1, 0, @@ -56055,14 +17483,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1597.0838396111787, - "y": 220, + "width": 3.888213851761847, + "x": 1547.5091130012152, + "y": 22, }, "transform": [ 1, @@ -56074,24 +17502,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1547.5091130012152, + "y": 44, + }, "transform": [ 1, 0, @@ -56100,14 +17517,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1597.0838396111787, - "y": 242, + "width": 1.9441069258809236, + "x": 1548.4811664641556, + "y": 44, }, "transform": [ 1, @@ -56119,24 +17536,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1550.4252733900366, + "y": 44, + }, "transform": [ 1, 0, @@ -56145,14 +17551,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1597.0838396111787, - "y": 264, + "width": 6.804374240583233, + "x": 1551.397326852977, + "y": 66, }, "transform": [ 1, @@ -56164,24 +17570,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 1558.2017010935601, + "y": 66, + }, "transform": [ 1, 0, @@ -56190,14 +17585,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1597.0838396111787, - "y": 286, + "x": 1558.2017010935601, + "y": 88, }, "transform": [ 1, @@ -56209,24 +17604,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 3.888213851761847, + "x": 1561.1178614823816, + "y": 66, + }, "transform": [ 1, 0, @@ -56235,14 +17619,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1597.0838396111787, - "y": 308, + "x": 1566.9501822600243, + "y": 44, }, "transform": [ 1, @@ -56254,24 +17638,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 8.748481166464156, + "x": 1567.9222357229648, + "y": 44, + }, "transform": [ 1, 0, @@ -56280,14 +17653,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 22, + "width": 6.804374240583233, + "x": 1567.9222357229648, + "y": 66, }, "transform": [ 1, @@ -56299,24 +17672,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 1567.9222357229648, + "y": 88, + }, "transform": [ 1, 0, @@ -56325,14 +17687,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 44, + "x": 1567.9222357229648, + "y": 110, }, "transform": [ 1, @@ -56344,24 +17706,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 1569.8663426488458, + "y": 88, + }, "transform": [ 1, 0, @@ -56370,14 +17721,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 66, + "x": 1572.782503037667, + "y": 88, }, "transform": [ 1, @@ -56389,24 +17740,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1573.7545565006076, + "y": 88, + }, "transform": [ 1, 0, @@ -56415,14 +17755,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 88, + "x": 1574.726609963548, + "y": 66, }, "transform": [ 1, @@ -56434,24 +17774,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1575.6986634264886, + "y": 66, + }, "transform": [ 1, 0, @@ -56460,14 +17789,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 110, + "width": 7.776427703523694, + "x": 1576.670716889429, + "y": 44, }, "transform": [ 1, @@ -56479,24 +17808,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1576.670716889429, + "y": 66, + }, "transform": [ 1, 0, @@ -56505,14 +17823,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 132, + "width": 6.804374240583233, + "x": 1577.6427703523696, + "y": 66, }, "transform": [ 1, @@ -56524,24 +17842,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 1577.6427703523696, + "y": 88, + }, "transform": [ 1, 0, @@ -56550,14 +17857,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 154, + "x": 1577.6427703523696, + "y": 110, }, "transform": [ 1, @@ -56569,24 +17876,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 1.9441069258809236, + "x": 1578.6148238153098, + "y": 110, + }, "transform": [ 1, 0, @@ -56595,14 +17891,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 176, + "width": 1.9441069258809236, + "x": 1580.5589307411908, + "y": 110, }, "transform": [ 1, @@ -56614,24 +17910,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1583.4750911300123, + "y": 88, + }, "transform": [ 1, 0, @@ -56640,14 +17925,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 198, + "width": 7.776427703523694, + "x": 1584.4471445929528, + "y": 22, }, "transform": [ 1, @@ -56659,24 +17944,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1584.4471445929528, + "y": 44, + }, "transform": [ 1, 0, @@ -56685,14 +17959,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 220, + "width": 1.9441069258809236, + "x": 1585.419198055893, + "y": 44, }, "transform": [ 1, @@ -56704,24 +17978,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 4.860267314702309, + "x": 1587.363304981774, + "y": 44, + }, "transform": [ 1, 0, @@ -56730,14 +17993,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 242, + "x": 1587.363304981774, + "y": 66, }, "transform": [ 1, @@ -56749,24 +18012,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 5.832320777642771, + "x": 1592.2235722964765, + "y": 22, + }, "transform": [ 1, 0, @@ -56775,14 +18027,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, - "width": 0.9720534629404618, - "x": 1598.0558930741192, - "y": 264, + "width": 3.888213851761847, + "x": 1592.2235722964765, + "y": 44, }, "transform": [ 1, @@ -56794,24 +18046,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 2.9161603888213854, + "x": 1592.2235722964765, + "y": 66, + }, "transform": [ 1, 0, @@ -56820,14 +18061,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1599.0279465370597, - "y": 22, + "x": 1592.2235722964765, + "y": 88, }, "transform": [ 1, @@ -56839,24 +18080,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1593.1956257594168, + "y": 88, + }, "transform": [ 1, 0, @@ -56865,14 +18095,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1599.0279465370597, - "y": 44, + "x": 1594.1676792223573, + "y": 88, }, "transform": [ 1, @@ -56884,24 +18114,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1596.1117861482383, + "y": 44, + }, "transform": [ 1, 0, @@ -56910,14 +18129,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, - "x": 1599.0279465370597, - "y": 66, + "x": 1597.0838396111787, + "y": 44, }, "transform": [ 1, @@ -56929,24 +18148,13 @@ exports[`FlameGraph should render correctly 1`] = ` ], "type": "rect", }, - ], - }, - "transform": [ - 1, - 0, - 0, - 1, - 0, - 0, - ], - "type": "fill", - }, - { - "props": { - "fillRule": "nonzero", - "path": [ { - "props": {}, + "props": { + "height": 22, + "width": 0.9720534629404618, + "x": 1598.0558930741192, + "y": 22, + }, "transform": [ 1, 0, @@ -56955,14 +18163,14 @@ exports[`FlameGraph should render correctly 1`] = ` 0, 0, ], - "type": "beginPath", + "type": "rect", }, { "props": { "height": 22, "width": 0.9720534629404618, "x": 1599.0279465370597, - "y": 88, + "y": 22, }, "transform": [ 1, diff --git a/packages/grafana-flamegraph/src/FlameGraph/dataTransform.test.ts b/packages/grafana-flamegraph/src/FlameGraph/dataTransform.test.ts index 89757c1f6e6ce..af0d8f19cc15b 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/dataTransform.test.ts +++ b/packages/grafana-flamegraph/src/FlameGraph/dataTransform.test.ts @@ -1,6 +1,7 @@ import { createDataFrame, FieldType } from '@grafana/data'; -import { FlameGraphDataContainer, LevelItem, nestedSetToLevels } from './dataTransform'; +import { CollapsedMapContainer, FlameGraphDataContainer, LevelItem, nestedSetToLevels } from './dataTransform'; +import { textToDataContainer } from './testHelpers'; describe('nestedSetToLevels', () => { it('converts nested set data frame to levels', () => { @@ -17,7 +18,7 @@ describe('nestedSetToLevels', () => { { name: 'self', values: [0, 0, 0, 0, 0, 0, 0, 0, 0] }, ], }); - const [levels] = nestedSetToLevels(new FlameGraphDataContainer(frame)); + const [levels] = nestedSetToLevels(new FlameGraphDataContainer(frame, { collapsing: true })); const n9: LevelItem = { itemIndexes: [8], start: 5, children: [], value: 1, level: 4 }; const n8: LevelItem = { itemIndexes: [7], start: 5, children: [n9], value: 2, level: 3 }; @@ -54,7 +55,7 @@ describe('nestedSetToLevels', () => { { name: 'self', values: [10, 5, 3, 1] }, ], }); - const [levels] = nestedSetToLevels(new FlameGraphDataContainer(frame)); + const [levels] = nestedSetToLevels(new FlameGraphDataContainer(frame, { collapsing: true })); const n4: LevelItem = { itemIndexes: [3], start: 8, children: [], value: 1, level: 1 }; const n3: LevelItem = { itemIndexes: [2], start: 5, children: [], value: 3, level: 1 }; @@ -69,3 +70,126 @@ describe('nestedSetToLevels', () => { expect(levels[1]).toEqual([n2, n3, n4]); }); }); + +describe('FlameGraphDataContainer', () => { + it('creates correct collapse map', () => { + const container = textToDataContainer(` + [0//////////////] + [1][3//][6///] + [2][4] [7///] + [5] [8///] + [9///] + `)!; + + const collapsedMap = container.getCollapsedMap(); + expect(Array.from(collapsedMap.keys()).map((item) => item.itemIndexes[0])).toEqual([1, 2, 4, 5, 6, 7, 8, 9]); + + expect(Array.from(collapsedMap.values())[0]).toMatchObject({ + collapsed: true, + items: [{ itemIndexes: [1] }, { itemIndexes: [2] }], + }); + }); + + it('creates correct collapse map 2', () => { + // Should not create any groups because even though the 1 is within threshold it has a sibling + const container = textToDataContainer( + ` + [0////////////////////////////////] + [1/////////////////////////////][2] + `, + { collapsing: true, collapsingThreshold: 0.5 } + )!; + + const collapsedMap = container.getCollapsedMap(); + expect(Array.from(collapsedMap.keys()).length).toEqual(0); + }); + + it('creates empty collapse map if no items are similar', () => { + const container = textToDataContainer(` + [0//////////////] + [1][3//][6///] + [9/] + `)!; + + const collapsedMap = container.getCollapsedMap(); + expect(Array.from(collapsedMap.keys()).length).toEqual(0); + }); +}); + +describe('CollapsedMapContainer', () => { + const defaultItem: LevelItem = { + itemIndexes: [0], + value: 100, + level: 0, + children: [], + start: 0, + }; + + it('groups items if they are within value threshold', () => { + const container = new CollapsedMapContainer(); + + const child2: LevelItem = { + ...defaultItem, + itemIndexes: [2], + value: 99.1, + }; + + const child1: LevelItem = { + ...defaultItem, + itemIndexes: [1], + children: [child2], + }; + + const parent: LevelItem = { + ...defaultItem, + children: [child1], + }; + + container.addItem(child1, parent); + container.addItem(child2, child1); + expect(container.getMap().get(child1)).toMatchObject({ collapsed: true, items: [parent, child1, child2] }); + expect(container.getMap().get(child2)).toMatchObject({ collapsed: true, items: [parent, child1, child2] }); + expect(container.getMap().get(parent)).toMatchObject({ collapsed: true, items: [parent, child1, child2] }); + }); + + it("doesn't group items if they are outside value threshold", () => { + const container = new CollapsedMapContainer(); + + const parent: LevelItem = { + ...defaultItem, + }; + + const child: LevelItem = { + ...defaultItem, + itemIndexes: [1], + value: 98, + }; + + container.addItem(child, parent); + expect(container.getMap().size).toBe(0); + }); + + it("doesn't group items if parent has multiple children", () => { + const container = new CollapsedMapContainer(); + + const child1: LevelItem = { + ...defaultItem, + itemIndexes: [1], + value: 99.1, + }; + + const child2: LevelItem = { + ...defaultItem, + itemIndexes: [2], + value: 0.09, + }; + + const parent: LevelItem = { + ...defaultItem, + children: [child1, child2], + }; + + container.addItem(child1, parent); + expect(container.getMap().size).toBe(0); + }); +}); diff --git a/packages/grafana-flamegraph/src/FlameGraph/dataTransform.ts b/packages/grafana-flamegraph/src/FlameGraph/dataTransform.ts index 526b608280fe6..1fb8461947643 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/dataTransform.ts +++ b/packages/grafana-flamegraph/src/FlameGraph/dataTransform.ts @@ -34,13 +34,14 @@ export type CollapseConfig = { collapsed: boolean; }; -export type CollapsedMap = Map; - /** * Convert data frame with nested set format into array of level. This is mainly done for compatibility with current * rendering code. */ -export function nestedSetToLevels(container: FlameGraphDataContainer): [LevelItem[][], Record] { +export function nestedSetToLevels( + container: FlameGraphDataContainer, + options?: Options +): [LevelItem[][], Record, CollapsedMap] { const levels: LevelItem[][] = []; let offset = 0; @@ -85,12 +86,68 @@ export function nestedSetToLevels(container: FlameGraphDataContainer): [LevelIte if (parent) { parent.children.push(newItem); } - parent = newItem; + parent = newItem; levels[currentLevel].push(newItem); } - return [levels, uniqueLabels]; + const collapsedMapContainer = new CollapsedMapContainer(options?.collapsingThreshold); + if (options?.collapsing) { + // We collapse similar items here, where it seems like parent and child are the same thing and so the distinction + // isn't that important. We create a map of items that should be collapsed together. We need to do it with complete + // tree as we need to know how many children an item has to know if we can collapse it. + collapsedMapContainer.addTree(levels[0][0]); + } + + return [levels, uniqueLabels, collapsedMapContainer.getMap()]; +} + +export type CollapsedMap = Map; +export class CollapsedMapContainer { + private map = new Map(); + private threshold = 0.99; + + constructor(threshold?: number) { + if (threshold !== undefined) { + this.threshold = threshold; + } + } + + addTree(root: LevelItem) { + const stack = [root]; + while (stack.length) { + const current = stack.shift()!; + + if (current.parents?.length) { + this.addItem(current, current.parents[0]); + } + + if (current.children.length) { + stack.unshift(...current.children); + } + } + } + + addItem(item: LevelItem, parent?: LevelItem) { + // The heuristics here is pretty simple right now. Just check if it's single child and if we are within threshold. + // We assume items with small self just aren't too important while we cannot really collapse items with siblings + // as it's not clear what to do with said sibling. + if (parent && item.value > parent.value * this.threshold && parent.children.length === 1) { + if (this.map.has(parent)) { + const config = this.map.get(parent)!; + this.map.set(item, config); + config.items.push(item); + } else { + const config = { items: [parent, item], collapsed: true }; + this.map.set(parent, config); + this.map.set(item, config); + } + } + } + + getMap() { + return new Map(this.map); + } } export function getMessageCheckFieldsResult(wrongFields: CheckFieldsResult) { @@ -144,8 +201,15 @@ export function checkFields(data: DataFrame): CheckFieldsResult | undefined { return undefined; } +export type Options = { + collapsing: boolean; + collapsingThreshold?: number; +}; + export class FlameGraphDataContainer { data: DataFrame; + options: Options; + labelField: Field; levelField: Field; valueField: Field; @@ -161,9 +225,11 @@ export class FlameGraphDataContainer { private levels: LevelItem[][] | undefined; private uniqueLabelsMap: Record | undefined; + private collapsedMap: Map | undefined; - constructor(data: DataFrame, theme: GrafanaTheme2 = createTheme()) { + constructor(data: DataFrame, options: Options, theme: GrafanaTheme2 = createTheme()) { this.data = data; + this.options = options; const wrongFields = checkFields(data); if (wrongFields) { @@ -275,11 +341,17 @@ export class FlameGraphDataContainer { return this.uniqueLabelsMap![label]; } + getCollapsedMap() { + this.initLevels(); + return this.collapsedMap!; + } + private initLevels() { if (!this.levels) { - const [levels, uniqueLabelsMap] = nestedSetToLevels(this); + const [levels, uniqueLabelsMap, collapsedMap] = nestedSetToLevels(this, this.options); this.levels = levels; this.uniqueLabelsMap = uniqueLabelsMap; + this.collapsedMap = collapsedMap; } } } diff --git a/packages/grafana-flamegraph/src/FlameGraph/rendering.test.ts b/packages/grafana-flamegraph/src/FlameGraph/rendering.test.ts index 314eab7486e62..cbdfa0b6e5751 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/rendering.test.ts +++ b/packages/grafana-flamegraph/src/FlameGraph/rendering.test.ts @@ -2,6 +2,7 @@ import { createDataFrame, FieldType } from '@grafana/data'; import { FlameGraphDataContainer, LevelItem } from './dataTransform'; import { walkTree } from './rendering'; +import { textToDataContainer } from './testHelpers'; function makeDataFrame(fields: Record>) { return createDataFrame({ @@ -20,22 +21,36 @@ type RenderData = { width: number; height: number; label: string; - collapsed: boolean; + muted: boolean; }; describe('walkTree', () => { it('correctly compute sizes for a single item', () => { const root: LevelItem = { start: 0, itemIndexes: [0], children: [], value: 100, level: 0 }; - const container = new FlameGraphDataContainer(makeDataFrame({ value: [100], level: [1], label: ['1'], self: [0] })); - walkTree(root, 'children', container, 100, 0, 1, 100, (item, x, y, width, height, label, collapsed) => { - expect(item).toEqual(root); - expect(x).toEqual(0); - expect(y).toEqual(0); - expect(width).toEqual(99); // -1 for border - expect(height).toEqual(22); - expect(label).toEqual('1'); - expect(collapsed).toEqual(false); - }); + const container = new FlameGraphDataContainer( + makeDataFrame({ value: [100], level: [0], label: ['1'], self: [0] }), + { collapsing: true } + ); + + walkTree( + root, + 'children', + container, + 100, + 0, + 1, + 100, + container.getCollapsedMap(), + (item, x, y, width, height, label, collapsed) => { + expect(item).toEqual(root); + expect(x).toEqual(0); + expect(y).toEqual(0); + expect(width).toEqual(99); // -1 for border + expect(height).toEqual(22); + expect(label).toEqual('1'); + expect(collapsed).toEqual(false); + } + ); }); it('should render a multiple items', () => { @@ -50,20 +65,31 @@ describe('walkTree', () => { ], }; const container = new FlameGraphDataContainer( - makeDataFrame({ value: [100, 50, 50], level: [0, 1, 1], label: ['1', '2', '3'], self: [0, 50, 50] }) + makeDataFrame({ value: [100, 50, 50], level: [0, 1, 1], label: ['1', '2', '3'], self: [0, 50, 50] }), + { collapsing: true } ); const renderData: RenderData[] = []; - walkTree(root, 'children', container, 100, 0, 1, 100, (item, x, y, width, height, label, collapsed) => { - renderData.push({ item, x, y, width, height, label, collapsed }); - }); + walkTree( + root, + 'children', + container, + 100, + 0, + 1, + 100, + container.getCollapsedMap(), + (item, x, y, width, height, label, muted) => { + renderData.push({ item, x, y, width, height, label, muted }); + } + ); expect(renderData).toEqual([ - { item: root, width: 99, height: 22, x: 0, y: 0, collapsed: false, label: '1' }, - { item: root.children[0], width: 49, height: 22, x: 0, y: 22, collapsed: false, label: '2' }, - { item: root.children[1], width: 49, height: 22, x: 50, y: 22, collapsed: false, label: '3' }, + { item: root, width: 99, height: 22, x: 0, y: 0, muted: false, label: '1' }, + { item: root.children[0], width: 49, height: 22, x: 0, y: 22, muted: false, label: '2' }, + { item: root.children[1], width: 49, height: 22, x: 50, y: 22, muted: false, label: '3' }, ]); }); - it('should render a collapsed items', () => { + it('should render a muted items', () => { const root: LevelItem = { start: 0, itemIndexes: [0], @@ -75,16 +101,27 @@ describe('walkTree', () => { ], }; const container = new FlameGraphDataContainer( - makeDataFrame({ value: [100, 1, 1], level: [0, 1, 1], label: ['1', '2', '3'], self: [0, 1, 1] }) + makeDataFrame({ value: [100, 1, 1], level: [0, 1, 1], label: ['1', '2', '3'], self: [0, 1, 1] }), + { collapsing: true } ); const renderData: RenderData[] = []; - walkTree(root, 'children', container, 100, 0, 1, 100, (item, x, y, width, height, label, collapsed) => { - renderData.push({ item, x, y, width, height, label, collapsed }); - }); + walkTree( + root, + 'children', + container, + 100, + 0, + 1, + 100, + container.getCollapsedMap(), + (item, x, y, width, height, label, muted) => { + renderData.push({ item, x, y, width, height, label, muted }); + } + ); expect(renderData).toEqual([ - { item: root, width: 99, height: 22, x: 0, y: 0, collapsed: false, label: '1' }, - { item: root.children[0], width: 1, height: 22, x: 0, y: 22, collapsed: true, label: '2' }, - { item: root.children[1], width: 1, height: 22, x: 1, y: 22, collapsed: true, label: '3' }, + { item: root, width: 99, height: 22, x: 0, y: 0, muted: false, label: '1' }, + { item: root.children[0], width: 1, height: 22, x: 0, y: 22, muted: true, label: '2' }, + { item: root.children[1], width: 1, height: 22, x: 1, y: 22, muted: true, label: '3' }, ]); }); @@ -100,12 +137,54 @@ describe('walkTree', () => { ], }; const container = new FlameGraphDataContainer( - makeDataFrame({ value: [100, 0.1, 0.1], level: [0, 1, 1], label: ['1', '2', '3'], self: [0, 0.1, 0.1] }) + makeDataFrame({ value: [100, 0.1, 0.1], level: [0, 1, 1], label: ['1', '2', '3'], self: [0, 0.1, 0.1] }), + { collapsing: true } ); const renderData: RenderData[] = []; - walkTree(root, 'children', container, 100, 0, 1, 100, (item, x, y, width, height, label, collapsed) => { - renderData.push({ item, x, y, width, height, label, collapsed }); - }); - expect(renderData).toEqual([{ item: root, width: 99, height: 22, x: 0, y: 0, collapsed: false, label: '1' }]); + walkTree( + root, + 'children', + container, + 100, + 0, + 1, + 100, + container.getCollapsedMap(), + (item, x, y, width, height, label, muted) => { + renderData.push({ item, x, y, width, height, label, muted }); + } + ); + expect(renderData).toEqual([{ item: root, width: 99, height: 22, x: 0, y: 0, muted: false, label: '1' }]); + }); + + it('should correctly skip a collapsed items', () => { + const container = textToDataContainer(` + [0///////////] + [1][3//][4///] + [2] [5///] + `)!; + + const root = container.getLevels()[0][0]; + + const renderData: RenderData[] = []; + walkTree( + root, + 'children', + container, + 14, + 0, + 1, + 14, + container.getCollapsedMap(), + (item, x, y, width, height, label, muted) => { + renderData.push({ item, x, y, width, height, label, muted }); + } + ); + expect(renderData).toEqual([ + { item: root, width: 13, height: 22, x: 0, y: 0, muted: false, label: '0' }, + { item: root.children[0], width: 3, height: 22, x: 0, y: 22, muted: true, label: '1' }, + { item: root.children[1], width: 5, height: 22, x: 3, y: 22, muted: true, label: '3' }, + { item: root.children[2], width: 6, height: 22, x: 8, y: 22, muted: true, label: '4' }, + ]); }); }); diff --git a/packages/grafana-flamegraph/src/FlameGraph/rendering.ts b/packages/grafana-flamegraph/src/FlameGraph/rendering.ts index c829649cfff79..7e28eba707946 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/rendering.ts +++ b/packages/grafana-flamegraph/src/FlameGraph/rendering.ts @@ -1,5 +1,4 @@ -import uFuzzy from '@leeoniya/ufuzzy'; -import { RefObject, useEffect, useMemo, useState } from 'react'; +import { RefObject, useCallback, useEffect, useMemo, useState } from 'react'; import color from 'tinycolor2'; import { GrafanaTheme2 } from '@grafana/data'; @@ -8,17 +7,19 @@ import { useTheme2 } from '@grafana/ui'; import { BAR_BORDER_WIDTH, BAR_TEXT_PADDING_LEFT, - COLLAPSE_THRESHOLD, + MUTE_THRESHOLD, HIDE_THRESHOLD, LABEL_THRESHOLD, PIXELS_PER_LEVEL, + GROUP_STRIP_WIDTH, + GROUP_STRIP_PADDING, + GROUP_STRIP_MARGIN_LEFT, + GROUP_TEXT_OFFSET, } from '../constants'; import { ClickedItemData, ColorScheme, ColorSchemeDiff, TextAlign } from '../types'; import { getBarColorByDiff, getBarColorByPackage, getBarColorByValue } from './colors'; -import { FlameGraphDataContainer, LevelItem } from './dataTransform'; - -const ufuzzy = new uFuzzy(); +import { CollapseConfig, CollapsedMap, FlameGraphDataContainer, LevelItem } from './dataTransform'; type RenderOptions = { canvasRef: RefObject; @@ -34,7 +35,7 @@ type RenderOptions = { rangeMin: number; rangeMax: number; - search: string; + matchedLabels: Set | undefined; textAlign: TextAlign; // Total ticks that will be used for sizing @@ -46,6 +47,7 @@ type RenderOptions = { totalTicksRight: number | undefined; colorScheme: ColorScheme | ColorSchemeDiff; focusedItemData?: ClickedItemData; + collapsedMap: CollapsedMap; }; export function useFlameRender(options: RenderOptions) { @@ -58,32 +60,39 @@ export function useFlameRender(options: RenderOptions) { wrapperWidth, rangeMin, rangeMax, - search, + matchedLabels, textAlign, totalViewTicks, totalColorTicks, totalTicksRight, colorScheme, focusedItemData, + collapsedMap, } = options; - const foundLabels = useFoundLabels(search, data); const ctx = useSetupCanvas(canvasRef, wrapperWidth, depth); const theme = useTheme2(); // There is a bit of dependency injections here that does not add readability, mainly to prevent recomputing some // common stuff for all the nodes in the graph when only once is enough. perf/readability tradeoff. + const mutedColor = useMemo(() => { + const barMutedColor = color(theme.colors.background.secondary); + return theme.isLight ? barMutedColor.darken(10).toHexString() : barMutedColor.lighten(10).toHexString(); + }, [theme]); + const getBarColor = useColorFunction( totalColorTicks, totalTicksRight, colorScheme, theme, + mutedColor, rangeMin, rangeMax, - foundLabels, + matchedLabels, focusedItemData ? focusedItemData.item.level : 0 ); - const renderFunc = useRenderFunc(ctx, data, getBarColor, textAlign); + + const renderFunc = useRenderFunc(ctx, data, getBarColor, textAlign, collapsedMap); useEffect(() => { if (!ctx) { @@ -91,50 +100,164 @@ export function useFlameRender(options: RenderOptions) { } ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - walkTree(root, direction, data, totalViewTicks, rangeMin, rangeMax, wrapperWidth, renderFunc); - }, [ctx, data, root, wrapperWidth, rangeMin, rangeMax, totalViewTicks, direction, renderFunc]); + + const mutedPath2D = new Path2D(); + + // + // Walk the tree and compute the dimensions for each item in the flamegraph. + // + walkTree( + root, + direction, + data, + totalViewTicks, + rangeMin, + rangeMax, + wrapperWidth, + collapsedMap, + (item, x, y, width, height, label, muted) => { + if (muted) { + // We do a bit of optimization for muted regions, and we render them all in single fill later on as they don't + // have labels and are the same color. + mutedPath2D.rect(x, y, width, height); + } else { + renderFunc(item, x, y, width, height, label); + } + } + ); + + // Only fill the muted rects + ctx.fillStyle = mutedColor; + ctx.fill(mutedPath2D); + }, [ + ctx, + data, + root, + wrapperWidth, + rangeMin, + rangeMax, + totalViewTicks, + direction, + renderFunc, + collapsedMap, + mutedColor, + ]); } -type RenderFunc = ( +type RenderFunc = (item: LevelItem, x: number, y: number, width: number, height: number, label: string) => void; + +type RenderFuncWrap = ( item: LevelItem, x: number, y: number, width: number, height: number, label: string, - // Collapsed means the width is too small to show the label, and we group collapsed siblings together. - collapsed: boolean + muted: boolean ) => void; +/** + * Create a render function with some memoization to prevent excesive repainting of the canvas. + * @param ctx + * @param data + * @param getBarColor + * @param textAlign + * @param collapsedMap + */ function useRenderFunc( ctx: CanvasRenderingContext2D | undefined, data: FlameGraphDataContainer, - getBarColor: (item: LevelItem, label: string, collapsed: boolean) => string, - textAlign: TextAlign -): RenderFunc { + getBarColor: (item: LevelItem, label: string, muted: boolean) => string, + textAlign: TextAlign, + collapsedMap: CollapsedMap +) { return useMemo(() => { if (!ctx) { return () => {}; } - return (item, x, y, width, height, label, collapsed) => { + const renderFunc: RenderFunc = (item, x, y, width, height, label) => { ctx.beginPath(); - ctx.rect(x + (collapsed ? 0 : BAR_BORDER_WIDTH), y, width, height); - ctx.fillStyle = getBarColor(item, label, collapsed); - - if (collapsed) { - // Only fill the collapsed rects - ctx.fill(); - } else { - ctx.stroke(); - ctx.fill(); + ctx.rect(x + BAR_BORDER_WIDTH, y, width, height); + ctx.fillStyle = getBarColor(item, label, false); + ctx.stroke(); + ctx.fill(); + + const collapsedItemConfig = collapsedMap.get(item); + let finalLabel = label; + if (collapsedItemConfig && collapsedItemConfig.collapsed) { + const numberOfCollapsedItems = collapsedItemConfig.items.length; + finalLabel = `(${numberOfCollapsedItems}) ` + label; + } - if (width >= LABEL_THRESHOLD) { - renderLabel(ctx, data, label, item, width, x, y, textAlign); + if (width >= LABEL_THRESHOLD) { + if (collapsedItemConfig) { + renderLabel( + ctx, + data, + finalLabel, + item, + width, + textAlign === 'left' ? x + GROUP_STRIP_MARGIN_LEFT + GROUP_TEXT_OFFSET : x, + y, + textAlign + ); + + renderGroupingStrip(ctx, x, y, height, item, collapsedItemConfig); + } else { + renderLabel(ctx, data, finalLabel, item, width, x, y, textAlign); } } }; - }, [ctx, getBarColor, textAlign, data]); + + return renderFunc; + }, [ctx, getBarColor, textAlign, data, collapsedMap]); +} + +/** + * Render small strip on the left side of the bar to indicate that this item is part of a group that can be collapsed. + * @param ctx + * @param x + * @param y + * @param height + * @param item + * @param collapsedItemConfig + */ +function renderGroupingStrip( + ctx: CanvasRenderingContext2D, + x: number, + y: number, + height: number, + item: LevelItem, + collapsedItemConfig: CollapseConfig +) { + const groupStripX = x + GROUP_STRIP_MARGIN_LEFT; + + // This is to mask the label in case we align it right to left. + ctx.beginPath(); + ctx.rect(x, y, groupStripX - x + GROUP_STRIP_WIDTH + GROUP_STRIP_PADDING, height); + ctx.fill(); + + // For item in a group that can be collapsed, we draw a small strip to mark them. On the items that are at the + // start or and end of a group we draw just half the strip so 2 groups next to each other are separated + // visually. + ctx.beginPath(); + if (collapsedItemConfig.collapsed) { + ctx.rect(groupStripX, y + height / 4, GROUP_STRIP_WIDTH, height / 2); + } else { + if (collapsedItemConfig.items[0] === item) { + // Top item + ctx.rect(groupStripX, y + height / 2, GROUP_STRIP_WIDTH, height / 2); + } else if (collapsedItemConfig.items[collapsedItemConfig.items.length - 1] === item) { + // Bottom item + ctx.rect(groupStripX, y, GROUP_STRIP_WIDTH, height / 2); + } else { + ctx.rect(groupStripX, y, GROUP_STRIP_WIDTH, height); + } + } + + ctx.fillStyle = '#666'; + ctx.fill(); } /** @@ -151,19 +274,22 @@ export function walkTree( rangeMin: number, rangeMax: number, wrapperWidth: number, - renderFunc: RenderFunc + collapsedMap: CollapsedMap, + renderFunc: RenderFuncWrap ) { - const stack: LevelItem[] = []; - stack.push(root); + // The levelOffset here is to keep track if items that we don't render because they are collapsed into single row. + // That means we have to render next items with an offset of some rows up in the stack. + const stack: Array<{ item: LevelItem; levelOffset: number }> = []; + stack.push({ item: root, levelOffset: 0 }); const pixelsPerTick = (wrapperWidth * window.devicePixelRatio) / totalViewTicks / (rangeMax - rangeMin); + let collapsedItemRendered: LevelItem | undefined = undefined; while (stack.length > 0) { - const item = stack.shift()!; + const { item, levelOffset } = stack.shift()!; let curBarTicks = item.value; - // Multiple collapsed items are shown as a single gray bar - const collapsed = curBarTicks * pixelsPerTick <= COLLAPSE_THRESHOLD; - const width = curBarTicks * pixelsPerTick - (collapsed ? 0 : BAR_BORDER_WIDTH * 2); + const muted = curBarTicks * pixelsPerTick <= MUTE_THRESHOLD; + const width = curBarTicks * pixelsPerTick - (muted ? 0 : BAR_BORDER_WIDTH * 2); const height = PIXELS_PER_LEVEL; if (width < HIDE_THRESHOLD) { @@ -171,40 +297,41 @@ export function walkTree( continue; } - const barX = getBarX(item.start, totalViewTicks, rangeMin, pixelsPerTick); - const barY = item.level * PIXELS_PER_LEVEL; - - let label = data.getLabel(item.itemIndexes[0]); + let offsetModifier = 0; + let skipRender = false; + const collapsedItemConfig = collapsedMap.get(item); + const isCollapsedItem = collapsedItemConfig && collapsedItemConfig.collapsed; - renderFunc(item, barX, barY, width, height, label, collapsed); - - const nextList = direction === 'children' ? item.children : item.parents; - if (nextList) { - stack.unshift(...nextList); + if (isCollapsedItem) { + if (collapsedItemRendered === collapsedItemConfig.items[0]) { + offsetModifier = direction === 'children' ? -1 : +1; + skipRender = true; + } else { + // This is a case where we have another collapsed group right after different collapsed group, so we need to + // reset. + collapsedItemRendered = undefined; + } + } else { + collapsedItemRendered = undefined; } - } -} -/** - * Based on the search string it does a fuzzy search over all the unique labels so we can highlight them later. - */ -function useFoundLabels(search: string | undefined, data: FlameGraphDataContainer): Set | undefined { - return useMemo(() => { - if (search) { - const foundLabels = new Set(); - let idxs = ufuzzy.filter(data.getUniqueLabels(), search); + if (!skipRender) { + const barX = getBarX(item.start, totalViewTicks, rangeMin, pixelsPerTick); + const barY = (item.level + levelOffset) * PIXELS_PER_LEVEL; - if (idxs) { - for (let idx of idxs) { - foundLabels.add(data.getUniqueLabels()[idx]); - } + let label = data.getLabel(item.itemIndexes[0]); + if (isCollapsedItem) { + collapsedItemRendered = item; } - return foundLabels; + renderFunc(item, barX, barY, width, height, label, muted); + } + + const nextList = direction === 'children' ? item.children : item.parents; + if (nextList) { + stack.unshift(...nextList.map((c) => ({ item: c, levelOffset: levelOffset + offsetModifier }))); } - // In this case undefined means there was no search so no attempt to highlighting anything should be made. - return undefined; - }, [search, data]); + } } function useColorFunction( @@ -212,24 +339,18 @@ function useColorFunction( totalTicksRight: number | undefined, colorScheme: ColorScheme | ColorSchemeDiff, theme: GrafanaTheme2, + mutedColor: string, rangeMin: number, rangeMax: number, - foundNames: Set | undefined, + matchedLabels: Set | undefined, topLevel: number ) { - return useMemo(() => { - // We use the same color for all muted bars so let's do it just once and reuse the result in the closure of the - // returned function. - const barMutedColor = color(theme.colors.background.secondary); - const barMutedColorHex = theme.isLight - ? barMutedColor.darken(10).toHexString() - : barMutedColor.lighten(10).toHexString(); - - return function getColor(item: LevelItem, label: string, collapsed: boolean) { + return useCallback( + function getColor(item: LevelItem, label: string, muted: boolean) { // If collapsed and no search we can quickly return the muted color - if (collapsed && !foundNames) { + if (muted && !matchedLabels) { // Collapsed are always grayed - return barMutedColorHex; + return mutedColor; } const barColor = @@ -240,15 +361,16 @@ function useColorFunction( ? getBarColorByValue(item.value, totalTicks, rangeMin, rangeMax) : getBarColorByPackage(label, theme); - if (foundNames) { + if (matchedLabels) { // Means we are searching, we use color for matches and gray the rest - return foundNames.has(label) ? barColor.toHslString() : barMutedColorHex; + return matchedLabels.has(label) ? barColor.toHslString() : mutedColor; } // Mute if we are above the focused symbol return item.level > topLevel - 1 ? barColor.toHslString() : barColor.lighten(15).toHslString(); - }; - }, [totalTicks, totalTicksRight, colorScheme, theme, rangeMin, rangeMax, foundNames, topLevel]); + }, + [totalTicks, totalTicksRight, colorScheme, theme, rangeMin, rangeMax, matchedLabels, topLevel, mutedColor] + ); } function useSetupCanvas(canvasRef: RefObject, wrapperWidth: number, numberOfLevels: number) { @@ -312,7 +434,7 @@ function renderLabel( } } - ctx.fillText(fullLabel, labelX, y + PIXELS_PER_LEVEL / 2); + ctx.fillText(fullLabel, labelX, y + PIXELS_PER_LEVEL / 2 + 2); ctx.restore(); } diff --git a/packages/grafana-flamegraph/src/FlameGraph/testHelpers.ts b/packages/grafana-flamegraph/src/FlameGraph/testHelpers.ts index 482fb5a230031..69eab859df174 100644 --- a/packages/grafana-flamegraph/src/FlameGraph/testHelpers.ts +++ b/packages/grafana-flamegraph/src/FlameGraph/testHelpers.ts @@ -1,6 +1,6 @@ import { arrayToDataFrame, FieldType } from '@grafana/data'; -import { FlameGraphDataContainer, LevelItem } from './dataTransform'; +import { FlameGraphDataContainer, LevelItem, Options } from './dataTransform'; // Convert text to a FlameGraphDataContainer for testing. The format representing the flamegraph for example: // [0///////] @@ -9,7 +9,7 @@ import { FlameGraphDataContainer, LevelItem } from './dataTransform'; // [3] [6] // [7] // Each node starts with [ ends with ], single digit is used for label and the length of a node is it's value. -export function textToDataContainer(text: string) { +export function textToDataContainer(text: string, options?: Options) { const levels = text.split('\n'); if (levels.length === 0) { @@ -80,7 +80,7 @@ export function textToDataContainer(text: string) { const df = arrayToDataFrame(dfSorted); const labelField = df.fields.find((f) => f.name === 'label')!; labelField.type = FieldType.string; - return new FlameGraphDataContainer(df); + return new FlameGraphDataContainer(df, options || { collapsing: true }); } export function trimLevelsString(s: string) { diff --git a/packages/grafana-flamegraph/src/FlameGraphContainer.test.tsx b/packages/grafana-flamegraph/src/FlameGraphContainer.test.tsx index 7fc17fcb4b12c..4a3fc56761b29 100644 --- a/packages/grafana-flamegraph/src/FlameGraphContainer.test.tsx +++ b/packages/grafana-flamegraph/src/FlameGraphContainer.test.tsx @@ -1,4 +1,4 @@ -import { render, screen } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; @@ -40,9 +40,13 @@ describe('FlameGraphContainer', () => { render(); await userEvent.click((await screen.findAllByTitle('Highlight symbol'))[0]); expect(screen.getByDisplayValue('net/http.HandlerFunc.ServeHTTP')).toBeInTheDocument(); + // Unclick the selection so that we can click something else and continue test checks + await userEvent.click((await screen.findAllByTitle('Highlight symbol'))[0]); + await userEvent.click((await screen.findAllByTitle('Highlight symbol'))[1]); expect(screen.getByDisplayValue('total')).toBeInTheDocument(); - await userEvent.click((await screen.findAllByTitle('Highlight symbol'))[1]); + // after it is highlighted it will be the only (first) item in the table so [1] -> [0] + await userEvent.click((await screen.findAllByTitle('Highlight symbol'))[0]); expect(screen.queryByDisplayValue('total')).not.toBeInTheDocument(); }); @@ -87,4 +91,27 @@ describe('FlameGraphContainer', () => { expect(screen.queryByTestId(/Both/)).toBeNull(); }); + + it('should filter table items based on search input', async () => { + // Render the FlameGraphContainer with necessary props + render(); + + // Checking for presence of this function before filter + const matchingText = 'net/http.HandlerFunc.ServeHTTP'; + const nonMatchingText = 'runtime.systemstack'; + + expect(screen.queryAllByText(matchingText).length).toBe(1); + expect(screen.queryAllByText(nonMatchingText).length).toBe(1); + + // Apply the filter + const searchInput = await screen.getByPlaceholderText('Search...'); + await userEvent.type(searchInput, 'Handler serve'); + + // We have to wait for filter to take effect + await waitFor(() => { + expect(screen.queryAllByText(nonMatchingText).length).toBe(0); + }); + // Check we didn't lose the one that should match + expect(screen.queryAllByText(matchingText).length).toBe(1); + }); }); diff --git a/packages/grafana-flamegraph/src/FlameGraphContainer.tsx b/packages/grafana-flamegraph/src/FlameGraphContainer.tsx index ac4439b244a2a..df8435c0dadfa 100644 --- a/packages/grafana-flamegraph/src/FlameGraphContainer.tsx +++ b/packages/grafana-flamegraph/src/FlameGraphContainer.tsx @@ -1,4 +1,5 @@ import { css } from '@emotion/css'; +import uFuzzy from '@leeoniya/ufuzzy'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useMeasure } from 'react-use'; @@ -12,6 +13,8 @@ import FlameGraphTopTableContainer from './TopTable/FlameGraphTopTableContainer' import { MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH } from './constants'; import { ClickedItemData, ColorScheme, ColorSchemeDiff, SelectedView, TextAlign } from './types'; +const ufuzzy = new uFuzzy(); + export type Props = { /** * DataFrame with the profile data. The dataFrame needs to have the following fields: @@ -53,6 +56,16 @@ export type Props = { * If true the flamegraph will be rendered on top of the table. */ vertical?: boolean; + + /** + * If true only the flamegraph will be rendered. + */ + showFlameGraphOnly?: boolean; + + /** + * Disable behaviour where similar items in the same stack will be collapsed into single item. + */ + disableCollapsing?: boolean; }; const FlameGraphContainer = ({ @@ -65,6 +78,8 @@ const FlameGraphContainer = ({ stickyHeader, extraHeaderElements, vertical, + showFlameGraphOnly, + disableCollapsing, }: Props) => { const [focusedItemData, setFocusedItemData] = useState(); @@ -83,10 +98,11 @@ const FlameGraphContainer = ({ if (!data) { return; } - return new FlameGraphDataContainer(data, theme); - }, [data, theme]); + return new FlameGraphDataContainer(data, { collapsing: !disableCollapsing }, theme); + }, [data, theme, disableCollapsing]); const [colorScheme, setColorScheme] = useColorScheme(dataContainer); - const styles = getStyles(theme, vertical); + const styles = getStyles(theme); + const matchedLabels = useLabelSearch(search, dataContainer); // If user resizes window with both as the selected view useEffect(() => { @@ -132,75 +148,101 @@ const FlameGraphContainer = ({ return null; } + const flameGraph = ( + setFocusedItemData(data)} + focusedItemData={focusedItemData} + textAlign={textAlign} + sandwichItem={sandwichItem} + onSandwich={(label: string) => { + resetFocus(); + setSandwichItem(label); + }} + onFocusPillClick={resetFocus} + onSandwichPillClick={resetSandwich} + colorScheme={colorScheme} + showFlameGraphOnly={showFlameGraphOnly} + collapsing={!disableCollapsing} + /> + ); + + const table = ( + + ); + + let body; + if (showFlameGraphOnly || selectedView === SelectedView.FlameGraph) { + body = flameGraph; + } else if (selectedView === SelectedView.TopTable) { + body =
    {table}
    ; + } else if (selectedView === SelectedView.Both) { + if (vertical) { + body = ( +
    +
    {flameGraph}
    +
    {table}
    +
    + ); + } else { + body = ( +
    +
    {table}
    +
    {flameGraph}
    +
    + ); + } + } + return ( // We add the theme context to bridge the gap if this is rendered in non grafana environment where the context // isn't already provided.
    - { - setSelectedView(view); - onViewSelected?.(view); - }} - containerWidth={containerWidth} - onReset={() => { - resetFocus(); - resetSandwich(); - }} - textAlign={textAlign} - onTextAlignChange={(align) => { - setTextAlign(align); - onTextAlignSelected?.(align); - }} - showResetButton={Boolean(focusedItemData || sandwichItem)} - colorScheme={colorScheme} - onColorSchemeChange={setColorScheme} - stickyHeader={Boolean(stickyHeader)} - extraHeaderElements={extraHeaderElements} - vertical={vertical} - isDiffMode={Boolean(dataContainer.isDiffFlamegraph())} - /> - -
    - {selectedView !== SelectedView.FlameGraph && ( - - )} - - {selectedView !== SelectedView.TopTable && ( - setFocusedItemData(data)} - focusedItemData={focusedItemData} - textAlign={textAlign} - sandwichItem={sandwichItem} - onSandwich={(label: string) => { - resetFocus(); - setSandwichItem(label); - }} - onFocusPillClick={resetFocus} - onSandwichPillClick={resetSandwich} - colorScheme={colorScheme} - /> - )} -
    + {!showFlameGraphOnly && ( + { + setSelectedView(view); + onViewSelected?.(view); + }} + containerWidth={containerWidth} + onReset={() => { + resetFocus(); + resetSandwich(); + }} + textAlign={textAlign} + onTextAlignChange={(align) => { + setTextAlign(align); + onTextAlignSelected?.(align); + }} + showResetButton={Boolean(focusedItemData || sandwichItem)} + colorScheme={colorScheme} + onColorSchemeChange={setColorScheme} + stickyHeader={Boolean(stickyHeader)} + extraHeaderElements={extraHeaderElements} + vertical={vertical} + isDiffMode={Boolean(dataContainer.isDiffFlamegraph())} + /> + )} + +
    {body}
    ); @@ -218,10 +260,36 @@ function useColorScheme(dataContainer: FlameGraphDataContainer | undefined) { return [colorScheme, setColorScheme] as const; } -function getStyles(theme: GrafanaTheme2, vertical?: boolean) { +/** + * Based on the search string it does a fuzzy search over all the unique labels, so we can highlight them later. + */ +function useLabelSearch( + search: string | undefined, + data: FlameGraphDataContainer | undefined +): Set | undefined { + return useMemo(() => { + if (search && data) { + const foundLabels = new Set(); + let idxs = ufuzzy.filter(data.getUniqueLabels(), search); + + if (idxs) { + for (let idx of idxs) { + foundLabels.add(data.getUniqueLabels()[idx]); + } + } + + return foundLabels; + } + // In this case undefined means there was no search so no attempt to highlighting anything should be made. + return undefined; + }, [search, data]); +} + +function getStyles(theme: GrafanaTheme2) { return { container: css({ label: 'container', + overflow: 'auto', height: '100%', display: 'flex', flex: '1 1 0', @@ -231,11 +299,39 @@ function getStyles(theme: GrafanaTheme2, vertical?: boolean) { }), body: css({ label: 'body', - display: 'flex', flexGrow: 1, + }), + + tableContainer: css({ + // This is not ideal for dashboard panel where it creates a double scroll. In a panel it should be 100% but then + // in explore we need a specific height. + height: 800, + }), + + horizontalContainer: css({ + label: 'horizontalContainer', + display: 'flex', minHeight: 0, - flexDirection: vertical ? 'column-reverse' : 'row', + flexDirection: 'row', columnGap: theme.spacing(1), + width: '100%', + }), + + horizontalGraphContainer: css({ + flexBasis: '50%', + }), + + horizontalTableContainer: css({ + flexBasis: '50%', + maxHeight: 800, + }), + + verticalGraphContainer: css({ + marginBottom: theme.spacing(1), + }), + + verticalTableContainer: css({ + height: 800, }), }; } diff --git a/packages/grafana-flamegraph/src/FlameGraphHeader.tsx b/packages/grafana-flamegraph/src/FlameGraphHeader.tsx index 7c521af4714e0..1e372a936607c 100644 --- a/packages/grafana-flamegraph/src/FlameGraphHeader.tsx +++ b/packages/grafana-flamegraph/src/FlameGraphHeader.tsx @@ -73,7 +73,7 @@ const FlameGraphHeader = ({ onChange={(v) => { setLocalSearch(v.currentTarget.value); }} - placeholder={'Search..'} + placeholder={'Search...'} suffix={suffix} /> diff --git a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx index be543a09f957c..f693d057f9b14 100644 --- a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx +++ b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.test.tsx @@ -12,7 +12,7 @@ import FlameGraphTopTableContainer from './FlameGraphTopTableContainer'; describe('FlameGraphTopTableContainer', () => { const setup = () => { const flameGraphData = createDataFrame(data); - const container = new FlameGraphDataContainer(flameGraphData); + const container = new FlameGraphDataContainer(flameGraphData, { collapsing: true }); const onSearch = jest.fn(); const onSandwich = jest.fn(); diff --git a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx index cef80bc9806a5..936be01380621 100644 --- a/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx +++ b/packages/grafana-flamegraph/src/TopTable/FlameGraphTopTableContainer.tsx @@ -29,49 +29,49 @@ import { TableData } from '../types'; type Props = { data: FlameGraphDataContainer; onSymbolClick: (symbol: string) => void; - height?: number; + // This is used for highlighting the search button in case there is exact match. search?: string; + // We use these to filter out rows in the table if users is doing text search. + matchedLabels?: Set; sandwichItem?: string; onSearch: (str: string) => void; onSandwich: (str?: string) => void; onTableSort?: (sort: string) => void; - vertical?: boolean; }; const FlameGraphTopTableContainer = React.memo( - ({ data, onSymbolClick, height, search, onSearch, sandwichItem, onSandwich, onTableSort, vertical }: Props) => { + ({ data, onSymbolClick, search, matchedLabels, onSearch, sandwichItem, onSandwich, onTableSort }: Props) => { const table = useMemo(() => { // Group the data by label, we show only one row per label and sum the values // TODO: should be by filename + funcName + linenumber? - let table: { [key: string]: TableData } = {}; + let filteredTable: { [key: string]: TableData } = {}; for (let i = 0; i < data.data.length; i++) { const value = data.getValue(i); const valueRight = data.getValueRight(i); const self = data.getSelf(i); const label = data.getLabel(i); - table[label] = table[label] || {}; - table[label].self = table[label].self ? table[label].self + self : self; - table[label].total = table[label].total ? table[label].total + value : value; - table[label].totalRight = table[label].totalRight ? table[label].totalRight + valueRight : valueRight; - } - return table; - }, [data]); - const rowHeight = 35; - // When we use normal layout we size the table to have the same height as the flamegraph to look good side by side. - // In vertical layout we don't need that so this is a bit arbitrary. We want some max limit - // so we don't show potentially thousands of rows at once which can hinder performance (the table is virtualized - // so with some max height it handles it fine) - const tableHeight = vertical ? Math.min(Object.keys(table).length * rowHeight, 800) : 0; + // If user is doing text search we filter out labels in the same way we highlight them in flamegraph. + if (!matchedLabels || matchedLabels.has(label)) { + filteredTable[label] = filteredTable[label] || {}; + filteredTable[label].self = filteredTable[label].self ? filteredTable[label].self + self : self; + filteredTable[label].total = filteredTable[label].total ? filteredTable[label].total + value : value; + filteredTable[label].totalRight = filteredTable[label].totalRight + ? filteredTable[label].totalRight + valueRight + : valueRight; + } + } + return filteredTable; + }, [data, matchedLabels]); - const styles = useStyles2(getStyles, tableHeight); + const styles = useStyles2(getStyles); const theme = useTheme2(); const [sort, setSort] = useState([{ displayName: 'Self', desc: true }]); return (
    - + {({ width, height }) => { if (width < 3 || height < 3) { return null; @@ -319,21 +319,14 @@ function ActionCell(props: ActionCellProps) { ); } -const getStyles = (theme: GrafanaTheme2, height: number) => { +const getStyles = (theme: GrafanaTheme2) => { return { - topTableContainer: css` - label: topTableContainer; - flex-grow: 1; - flex-basis: 50%; - overflow: hidden; - padding: ${theme.spacing(1)}; - background-color: ${theme.colors.background.secondary}; - ${height - ? css` - min-height: ${height}px; - ` - : ''} - `, + topTableContainer: css({ + label: 'topTableContainer', + padding: theme.spacing(1), + backgroundColor: theme.colors.background.secondary, + height: '100%', + }), }; }; diff --git a/packages/grafana-flamegraph/src/constants.ts b/packages/grafana-flamegraph/src/constants.ts index db3da0a18c086..aa910799fceff 100644 --- a/packages/grafana-flamegraph/src/constants.ts +++ b/packages/grafana-flamegraph/src/constants.ts @@ -1,8 +1,12 @@ export const PIXELS_PER_LEVEL = 22 * window.devicePixelRatio; -export const COLLAPSE_THRESHOLD = 10 * window.devicePixelRatio; +export const MUTE_THRESHOLD = 10 * window.devicePixelRatio; export const HIDE_THRESHOLD = 0.5 * window.devicePixelRatio; export const LABEL_THRESHOLD = 20 * window.devicePixelRatio; export const BAR_BORDER_WIDTH = 0.5 * window.devicePixelRatio; export const BAR_TEXT_PADDING_LEFT = 4 * window.devicePixelRatio; +export const GROUP_STRIP_WIDTH = 3 * window.devicePixelRatio; +export const GROUP_STRIP_PADDING = 3 * window.devicePixelRatio; +export const GROUP_STRIP_MARGIN_LEFT = 4 * window.devicePixelRatio; +export const GROUP_TEXT_OFFSET = 2 * window.devicePixelRatio; export const MIN_WIDTH_TO_SHOW_BOTH_TOPTABLE_AND_FLAMEGRAPH = 800; export const TOP_TABLE_COLUMN_WIDTH = 120; diff --git a/packages/grafana-flamegraph/src/index.ts b/packages/grafana-flamegraph/src/index.ts index 1e91bd43c6537..ab6407c5e492b 100644 --- a/packages/grafana-flamegraph/src/index.ts +++ b/packages/grafana-flamegraph/src/index.ts @@ -1,2 +1,3 @@ export { default as FlameGraph, type Props } from './FlameGraphContainer'; export { checkFields, getMessageCheckFieldsResult } from './FlameGraph/dataTransform'; +export { data } from './FlameGraph/testData/dataNestedSet'; diff --git a/packages/grafana-runtime/package.json b/packages/grafana-runtime/package.json index a0ca950c78a88..2a1c2492a7845 100644 --- a/packages/grafana-runtime/package.json +++ b/packages/grafana-runtime/package.json @@ -73,7 +73,7 @@ "rollup-plugin-node-externals": "^5.0.0", "rollup-plugin-sourcemaps": "0.6.3", "rollup-plugin-terser": "7.0.2", - "typescript": "4.8.4" + "typescript": "5.2.2" }, "peerDependencies": { "react": "^17.0.0 || ^18.0.0", diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts index ab29635bbe2b6..deedcfeee5989 100644 --- a/packages/grafana-runtime/src/config.ts +++ b/packages/grafana-runtime/src/config.ts @@ -16,6 +16,7 @@ import { systemDateFormats, SystemDateFormatSettings, getThemeById, + AngularMeta, } from '@grafana/data'; export interface AzureSettings { @@ -30,7 +31,7 @@ export type AppPluginConfig = { path: string; version: string; preload: boolean; - angularDetected?: boolean; + angular: AngularMeta; }; export class GrafanaBootConfig implements GrafanaConfig { @@ -43,6 +44,7 @@ export class GrafanaBootConfig implements GrafanaConfig { minRefreshInterval = ''; appUrl = ''; appSubUrl = ''; + namespace = 'default'; windowTitlePrefix = ''; buildInfo: BuildInfo; newPanelTitle = ''; @@ -92,6 +94,7 @@ export class GrafanaBootConfig implements GrafanaConfig { theme2: GrafanaTheme2; featureToggles: FeatureToggles = {}; anonymousEnabled = false; + anonymousDeviceLimit = undefined; licenseInfo: LicenseInfo = {} as LicenseInfo; rendererAvailable = false; rendererVersion = ''; @@ -143,6 +146,9 @@ export class GrafanaBootConfig implements GrafanaConfig { reporting = { enabled: true, }; + analytics = { + enabled: true, + }; googleAnalyticsId: undefined; googleAnalytics4Id: undefined; googleAnalytics4SendManualPageViews = false; diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts index b1815fcc095ed..8d3d9ce7f47f1 100644 --- a/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.test.ts @@ -350,6 +350,63 @@ describe('DataSourceWithBackend', () => { }); }); + test('check that queries can skip the query cache', () => { + const { mock, ds } = createMockDatasource(); + ds.query({ + maxDataPoints: 10, + intervalMs: 5000, + targets: [{ refId: 'A' }], + dashboardUID: 'dashA', + panelId: 123, + range: getDefaultTimeRange(), + skipQueryCache: true, + requestId: 'request-123', + interval: '5s', + scopedVars: {}, + timezone: '', + app: '', + startTime: 0, + }); + + const args = mock.calls[0][0]; + + expect(mock.calls.length).toBe(1); + expect(args).toMatchInlineSnapshot(` + { + "data": { + "from": "1697133600000", + "queries": [ + { + "applyTemplateVariablesCalled": true, + "datasource": { + "type": "dummy", + "uid": "abc", + }, + "datasourceId": 1234, + "filters": undefined, + "intervalMs": 5000, + "maxDataPoints": 10, + "queryCachingTTL": undefined, + "refId": "A", + }, + ], + "to": "1697155200000", + }, + "headers": { + "X-Cache-Skip": "true", + "X-Dashboard-Uid": "dashA", + "X-Datasource-Uid": "abc", + "X-Panel-Id": "123", + "X-Plugin-Id": "dummy", + }, + "hideFromInspector": false, + "method": "POST", + "requestId": "request-123", + "url": "/api/ds/query?ds_type=dummy&requestId=request-123", + } + `); + }); + describe('isExpressionReference', () => { test('check all possible expression references', () => { expect(isExpressionReference('__expr__')).toBeTruthy(); // New UID diff --git a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts index da8a914251cb3..7085f0dc47a8c 100644 --- a/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts +++ b/packages/grafana-runtime/src/utils/DataSourceWithBackend.ts @@ -82,6 +82,7 @@ enum PluginRequestHeaders { PanelID = 'X-Panel-Id', // mainly useful for debugging slow queries QueryGroupID = 'X-Query-Group-Id', // mainly useful to find related queries with query splitting FromExpression = 'X-Grafana-From-Expr', // used by datasources to identify expression queries + SkipQueryCache = 'X-Cache-Skip', // used by datasources to skip the query cache } /** @@ -228,6 +229,9 @@ class DataSourceWithBackend< if (request.queryGroupId) { headers[PluginRequestHeaders.QueryGroupID] = `${request.queryGroupId}`; } + if (request.skipQueryCache) { + headers[PluginRequestHeaders.SkipQueryCache] = 'true'; + } return getBackendSrv() .fetch({ url, diff --git a/packages/grafana-schema/package.json b/packages/grafana-schema/package.json index 6ec2b9cf88dd6..0cac85c065b12 100644 --- a/packages/grafana-schema/package.json +++ b/packages/grafana-schema/package.json @@ -47,7 +47,7 @@ "rollup-plugin-dts": "^5.0.0", "rollup-plugin-esbuild": "5.0.0", "rollup-plugin-node-externals": "^5.0.0", - "typescript": "4.8.4" + "typescript": "5.2.2" }, "dependencies": { "tslib": "2.6.0" diff --git a/packages/grafana-schema/src/common/common.gen.ts b/packages/grafana-schema/src/common/common.gen.ts index 76676b232cc19..b05a4bdf35944 100644 --- a/packages/grafana-schema/src/common/common.gen.ts +++ b/packages/grafana-schema/src/common/common.gen.ts @@ -644,6 +644,14 @@ export enum BarGaugeNamePlacement { Top = 'top', } +/** + * Allows for the bar gauge size to be set explicitly + */ +export enum BarGaugeSizing { + Auto = 'auto', + Manual = 'manual', +} + /** * TODO docs */ diff --git a/packages/grafana-schema/src/common/mudball.cue b/packages/grafana-schema/src/common/mudball.cue index 9dbc0219ac1b2..ce4c0626d4b62 100644 --- a/packages/grafana-schema/src/common/mudball.cue +++ b/packages/grafana-schema/src/common/mudball.cue @@ -249,6 +249,9 @@ BarGaugeValueMode: "color" | "text" | "hidden" @cuetsy(kind="enum") // Allows for the bar gauge name to be placed explicitly BarGaugeNamePlacement: "auto" | "top" | "left" @cuetsy(kind="enum") +// Allows for the bar gauge size to be set explicitly +BarGaugeSizing: "auto" | "manual" @cuetsy(kind="enum") + // TODO docs VizTooltipOptions: { mode: TooltipDisplayMode diff --git a/packages/grafana-schema/src/index.gen.ts b/packages/grafana-schema/src/index.gen.ts index 6576c1ce63f92..9748a56bce2cf 100644 --- a/packages/grafana-schema/src/index.gen.ts +++ b/packages/grafana-schema/src/index.gen.ts @@ -37,9 +37,7 @@ export type { RegexMap, SpecialValueMap, ValueMappingResult, - LibraryPanelRef, - GraphPanel, - HeatmapPanel + LibraryPanelRef } from './raw/dashboard/x/dashboard_types.gen'; // Raw generated enums and default consts from dashboard kind. @@ -75,6 +73,7 @@ export type { VariableModel, DataSourceRef, DataTransformerConfig, + TimePickerConfig, Panel, FieldConfigSource, MatcherConfig, @@ -97,6 +96,7 @@ export { defaultAnnotationQuery, defaultVariableModel, VariableHide, + defaultTimePickerConfig, defaultPanel, defaultFieldConfigSource, defaultMatcherConfig, diff --git a/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts index c4513a6f2dc2a..70cdf925bef33 100644 --- a/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/bargauge/panelcfg/x/BarGaugePanelCfg_types.gen.ts @@ -15,18 +15,22 @@ export const pluginVersion = "10.3.0-pre"; export interface Options extends common.SingleStatBaseOptions { displayMode: common.BarGaugeDisplayMode; + maxVizHeight: number; minVizHeight: number; minVizWidth: number; namePlacement: common.BarGaugeNamePlacement; showUnfilled: boolean; + sizing: common.BarGaugeSizing; valueMode: common.BarGaugeValueMode; } export const defaultOptions: Partial = { displayMode: common.BarGaugeDisplayMode.Gradient, - minVizHeight: 10, - minVizWidth: 0, + maxVizHeight: 300, + minVizHeight: 75, + minVizWidth: 75, namePlacement: common.BarGaugeNamePlacement.Auto, showUnfilled: true, + sizing: common.BarGaugeSizing.Auto, valueMode: common.BarGaugeValueMode.Color, }; diff --git a/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts index b00ca10dee6b5..18c6625d9eee3 100644 --- a/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/gauge/panelcfg/x/GaugePanelCfg_types.gen.ts @@ -18,11 +18,13 @@ export interface Options extends common.SingleStatBaseOptions { minVizWidth: number; showThresholdLabels: boolean; showThresholdMarkers: boolean; + sizing: common.BarGaugeSizing; } export const defaultOptions: Partial = { - minVizHeight: 75, - minVizWidth: 75, + minVizHeight: 200, + minVizWidth: 200, showThresholdLabels: false, showThresholdMarkers: true, + sizing: common.BarGaugeSizing.Auto, }; diff --git a/packages/grafana-schema/src/raw/composable/grafanapyroscope/dataquery/x/GrafanaPyroscopeDataQuery_types.gen.ts b/packages/grafana-schema/src/raw/composable/grafanapyroscope/dataquery/x/GrafanaPyroscopeDataQuery_types.gen.ts index 08d7d682b9398..30e597171618c 100644 --- a/packages/grafana-schema/src/raw/composable/grafanapyroscope/dataquery/x/GrafanaPyroscopeDataQuery_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/grafanapyroscope/dataquery/x/GrafanaPyroscopeDataQuery_types.gen.ts @@ -34,9 +34,14 @@ export interface GrafanaPyroscopeDataQuery extends common.DataQuery { * Specifies the type of profile to query. */ profileTypeId: string; + /** + * Specifies the query span selectors. + */ + spanSelector?: Array; } export const defaultGrafanaPyroscopeDataQuery: Partial = { groupBy: [], labelSelector: '{}', + spanSelector: [], }; diff --git a/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts index f1909d68ff05a..4ed9a2f545045 100644 --- a/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/heatmap/panelcfg/x/HeatmapPanelCfg_types.gen.ts @@ -133,6 +133,10 @@ export interface HeatmapTooltip { * Controls if the tooltip is shown */ show: boolean; + /** + * Controls if the tooltip shows a color scale in header + */ + showColorScale?: boolean; /** * Controls if the tooltip shows a histogram of the y-axis values */ @@ -264,6 +268,7 @@ export const defaultOptions: Partial = { tooltip: { show: true, yHistogram: false, + showColorScale: false, }, }; diff --git a/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts b/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts index 842651d79f4e9..f372445d382a2 100644 --- a/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts +++ b/packages/grafana-schema/src/raw/composable/stat/panelcfg/x/StatPanelCfg_types.gen.ts @@ -18,6 +18,7 @@ export interface Options extends common.SingleStatBaseOptions { graphMode: common.BigValueGraphMode; justifyMode: common.BigValueJustifyMode; textMode: common.BigValueTextMode; + wideLayout: boolean; } export const defaultOptions: Partial = { @@ -25,4 +26,5 @@ export const defaultOptions: Partial = { graphMode: common.BigValueGraphMode.Area, justifyMode: common.BigValueJustifyMode.Auto, textMode: common.BigValueTextMode.Auto, + wideLayout: true, }; diff --git a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts index d16491351f700..8f4854b5bcb33 100644 --- a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts +++ b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts @@ -233,6 +233,8 @@ export enum VariableHide { * `4`: Numerical DESC * `5`: Alphabetical Case Insensitive ASC * `6`: Alphabetical Case Insensitive DESC + * `7`: Natural ASC + * `8`: Natural DESC */ export enum VariableSort { alphabeticalAsc = 1, @@ -240,6 +242,8 @@ export enum VariableSort { alphabeticalCaseInsensitiveDesc = 6, alphabeticalDesc = 2, disabled = 0, + naturalAsc = 7, + naturalDesc = 8, numericalAsc = 3, numericalDesc = 4, } @@ -301,7 +305,7 @@ export interface DashboardLink { /** * Link URL. Only required/valid if the type is link */ - url: string; + url?: string; } export const defaultDashboardLink: Partial = { @@ -621,6 +625,31 @@ export interface DataTransformerConfig { options: unknown; } +/** + * Time picker configuration + * It defines the default config for the time picker and the refresh picker for the specific dashboard. + */ +export interface TimePickerConfig { + /** + * Whether timepicker is visible or not. + */ + hidden: boolean; + /** + * Interval options available in the refresh picker dropdown. + */ + refresh_intervals: Array; + /** + * Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. + */ + time_options: Array; +} + +export const defaultTimePickerConfig: Partial = { + hidden: false, + refresh_intervals: ['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'], + time_options: ['5m', '15m', '1h', '6h', '12h', '24h', '2d', '7d', '30d'], +}; + /** * 0 for no shared crosshair or tooltip (default). * 1 for shared crosshair. @@ -937,7 +966,7 @@ export interface RowPanel { /** * List of panels in the row */ - panels: Array<(Panel | GraphPanel | HeatmapPanel)>; + panels: Array; /** * Name of template variable to repeat for. */ @@ -957,30 +986,6 @@ export const defaultRowPanel: Partial = { panels: [], }; -/** - * Support for legacy graph panel. - * @deprecated this a deprecated panel type - */ -export interface GraphPanel { - /** - * @deprecated this is part of deprecated graph panel - */ - legend?: { - show: boolean; - sort?: string; - sortDesc?: boolean; - }; - type: 'graph'; -} - -/** - * Support for legacy heatmap panel. - * @deprecated this a deprecated panel type - */ -export interface HeatmapPanel { - type: 'heatmap'; -} - export interface Dashboard { /** * Contains the list of annotations that are associated with the dashboard. @@ -1028,7 +1033,7 @@ export interface Dashboard { /** * List of dashboard panels */ - panels?: Array<(Panel | RowPanel | GraphPanel | HeatmapPanel)>; + panels?: Array<(Panel | RowPanel)>; /** * Refresh rate of dashboard. Represented via interval string, e.g. "5s", "1m", "1h", "1d". */ @@ -1116,24 +1121,7 @@ export interface Dashboard { /** * Configuration of the time picker shown at the top of a dashboard. */ - timepicker?: { - /** - * Whether timepicker is visible or not. - */ - hidden: boolean; - /** - * Interval options available in the refresh picker dropdown. - */ - refresh_intervals: Array; - /** - * Whether timepicker is collapsed or not. Has no effect on provisioned dashboard. - */ - collapse: boolean; - /** - * Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. - */ - time_options: Array; - }; + timepicker?: TimePickerConfig; /** * Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc". */ diff --git a/packages/grafana-schema/src/raw/preferences/x/preferences_types.gen.ts b/packages/grafana-schema/src/raw/preferences/x/preferences_types.gen.ts index d240e05754544..033e4233d4b12 100644 --- a/packages/grafana-schema/src/raw/preferences/x/preferences_types.gen.ts +++ b/packages/grafana-schema/src/raw/preferences/x/preferences_types.gen.ts @@ -21,6 +21,10 @@ export interface CookiePreferences { performance?: Record; } +/** + * Spec defines user, team or org Grafana preferences + * swagger:model Preferences + */ export interface Preferences { /** * Cookie preferences diff --git a/packages/grafana-schema/src/veneer/dashboard.types.ts b/packages/grafana-schema/src/veneer/dashboard.types.ts index 3f85370614eca..5e1db960f4de2 100644 --- a/packages/grafana-schema/src/veneer/dashboard.types.ts +++ b/packages/grafana-schema/src/veneer/dashboard.types.ts @@ -11,7 +11,7 @@ export interface Panel, TCustomFieldConfig = } export interface RowPanel extends Omit { - panels: Array; + panels: Panel[]; } export enum VariableHide { @@ -25,7 +25,7 @@ export interface VariableModel extends Omit { } export interface Dashboard extends Omit { - panels?: Array; + panels?: Array; annotations?: AnnotationContainer; templating?: { list?: VariableModel[]; @@ -61,10 +61,13 @@ export interface DataTransformerConfig extends raw.DataTransform options: TOptions; } +export interface TimePickerConfig extends raw.TimePickerConfig {} + export const defaultDashboard = raw.defaultDashboard as Dashboard; export const defaultVariableModel = { ...raw.defaultVariableModel, } as VariableModel; +export const defaultTimePickerConfig = raw.defaultTimePickerConfig as TimePickerConfig; export const defaultPanel: Partial = raw.defaultPanel; export const defaultRowPanel: Partial = raw.defaultRowPanel; export const defaultFieldConfig: Partial = raw.defaultFieldConfig; diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index e98c75f3984eb..81db580697942 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -53,7 +53,7 @@ "@grafana/e2e-selectors": "10.3.0-pre", "@grafana/faro-web-sdk": "1.2.1", "@grafana/schema": "10.3.0-pre", - "@leeoniya/ufuzzy": "1.0.8", + "@leeoniya/ufuzzy": "1.0.13", "@monaco-editor/react": "4.6.0", "@popperjs/core": "2.11.8", "@react-aria/button": "3.8.0", @@ -66,7 +66,6 @@ "ansicolor": "1.1.100", "calculate-size": "1.1.1", "classnames": "2.3.2", - "core-js": "3.33.0", "d3": "7.8.5", "date-fns": "2.30.0", "hoist-non-react-statics": "3.3.2", @@ -100,7 +99,6 @@ "react-popper-tooltip": "4.4.2", "react-router-dom": "5.3.3", "react-select": "5.7.4", - "react-select-event": "^5.1.0", "react-table": "7.8.0", "react-transition-group": "4.4.5", "react-use": "17.4.0", @@ -134,7 +132,7 @@ "@storybook/react-webpack5": "7.4.5", "@storybook/theming": "7.4.5", "@testing-library/dom": "9.3.3", - "@testing-library/jest-dom": "5.16.5", + "@testing-library/jest-dom": "6.1.4", "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.5.1", "@types/common-tags": "^1.8.0", @@ -145,7 +143,7 @@ "@types/jquery": "3.5.16", "@types/lodash": "4.14.195", "@types/mock-raf": "1.0.3", - "@types/node": "18.18.4", + "@types/node": "20.8.10", "@types/prismjs": "1.26.0", "@types/react": "18.2.15", "@types/react-beautiful-dnd": "13.1.4", @@ -165,6 +163,7 @@ "@types/tinycolor2": "1.4.3", "@types/uuid": "9.0.2", "common-tags": "1.8.2", + "core-js": "3.33.0", "css-loader": "6.8.1", "csstype": "3.1.2", "esbuild": "0.18.12", @@ -173,6 +172,7 @@ "process": "^0.11.10", "react": "18.2.0", "react-dom": "18.2.0", + "react-select-event": "^5.1.0", "react-test-renderer": "18.2.0", "rimraf": "5.0.1", "rollup": "2.79.1", @@ -185,7 +185,7 @@ "storybook-addon-turbo-build": "2.0.1", "storybook-dark-mode": "3.0.1", "style-loader": "3.3.3", - "typescript": "4.8.4", + "typescript": "5.2.2", "webpack": "5.89.0" }, "peerDependencies": { diff --git a/packages/grafana-ui/src/components/Alert/Alert.tsx b/packages/grafana-ui/src/components/Alert/Alert.tsx index 4595aad88c3b9..fb0cf2c080c12 100644 --- a/packages/grafana-ui/src/components/Alert/Alert.tsx +++ b/packages/grafana-ui/src/components/Alert/Alert.tsx @@ -54,15 +54,9 @@ export const Alert = React.forwardRef( const ariaLabel = restProps['aria-label'] || title; return ( -
    +
    { tooltip?: string; } -export const Badge = React.memo(({ icon, color, text, tooltip, className, ...otherProps }) => { +const BadgeComponent = React.memo(({ icon, color, text, tooltip, className, ...otherProps }) => { const styles = useStyles2(getStyles, color); const badge = (
    @@ -35,8 +37,21 @@ export const Badge = React.memo(({ icon, color, text, tooltip, class badge ); }); +BadgeComponent.displayName = 'Badge'; -Badge.displayName = 'Badge'; +const BadgeSkeleton: SkeletonComponent = ({ rootProps }) => { + const styles = useStyles2(getSkeletonStyles); + + return ; +}; + +export const Badge = attachSkeleton(BadgeComponent, BadgeSkeleton); + +const getSkeletonStyles = () => ({ + container: css({ + lineHeight: 1, + }), +}); const getStyles = (theme: GrafanaTheme2, color: BadgeColor) => { let sourceColor = theme.visualization.getColorByName(color); diff --git a/packages/grafana-ui/src/components/BigValue/BigValue.tsx b/packages/grafana-ui/src/components/BigValue/BigValue.tsx index 762cd2e893bbb..bfa8cd382b12b 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValue.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValue.tsx @@ -1,7 +1,7 @@ import { cx } from '@emotion/css'; import React, { PureComponent } from 'react'; -import { DisplayValue, DisplayValueAlignmentFactors, FieldSparkline, VizOrientation } from '@grafana/data'; +import { DisplayValue, DisplayValueAlignmentFactors, FieldSparkline } from '@grafana/data'; import { VizTextDisplayOptions } from '@grafana/schema'; import { Themeable2 } from '../../types'; @@ -66,8 +66,6 @@ export interface Props extends Themeable2 { textMode?: BigValueTextMode; /** If true disables the tooltip */ hasLinks?: boolean; - /** The orientation of the parent container */ - parentOrientation?: VizOrientation; /** * If part of a series of stat panes, this is the total number. diff --git a/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx index 15ff7a04b6901..d5662b9b2be0c 100644 --- a/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx +++ b/packages/grafana-ui/src/components/BigValue/BigValueLayout.tsx @@ -1,7 +1,7 @@ import React, { CSSProperties } from 'react'; import tinycolor from 'tinycolor2'; -import { formattedValueToString, DisplayValue, FieldConfig, FieldType, VizOrientation } from '@grafana/data'; +import { formattedValueToString, DisplayValue, FieldConfig, FieldType } from '@grafana/data'; import { GraphDrawStyle, GraphFieldConfig } from '@grafana/schema'; import { getTextColorForAlphaBackground } from '../../utils'; @@ -63,10 +63,6 @@ export abstract class BigValueLayout { lineHeight: LINE_HEIGHT, }; - if (this.props.parentOrientation === VizOrientation.Horizontal && this.justifyCenter) { - styles.paddingRight = '0.75ch'; - } - if ( this.props.colorMode === BigValueColorMode.Background || this.props.colorMode === BigValueColorMode.BackgroundSolid @@ -115,6 +111,7 @@ export abstract class BigValueLayout { styles.alignItems = 'center'; styles.justifyContent = 'center'; styles.flexGrow = 1; + styles.gap = '0.75ch'; } return styles; diff --git a/packages/grafana-ui/src/components/Button/Button.tsx b/packages/grafana-ui/src/components/Button/Button.tsx index 8e4f00b1c87fb..b2f8bf3bf32aa 100644 --- a/packages/grafana-ui/src/components/Button/Button.tsx +++ b/packages/grafana-ui/src/components/Button/Button.tsx @@ -83,7 +83,9 @@ export const Button = React.forwardRef( Button.displayName = 'Button'; -type ButtonLinkProps = CommonProps & ButtonHTMLAttributes & AnchorHTMLAttributes; +export type ButtonLinkProps = CommonProps & + ButtonHTMLAttributes & + AnchorHTMLAttributes; export const LinkButton = React.forwardRef( ( diff --git a/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx b/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx index 446c9a2cbed12..9c3fcfa7ca741 100644 --- a/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx +++ b/packages/grafana-ui/src/components/Button/FullWidthButtonContainer.tsx @@ -1,20 +1,20 @@ import { css, cx } from '@emotion/css'; import React from 'react'; -import { stylesFactory } from '../../themes'; +import { useStyles2 } from '../../themes'; export interface Props { className?: string; } export const FullWidthButtonContainer = ({ className, children }: React.PropsWithChildren) => { - const styles = getStyles(); + const styles = useStyles2(getStyles); return
    {children}
    ; }; -const getStyles = stylesFactory(() => { - return css({ +const getStyles = () => + css({ display: 'flex', button: { @@ -31,4 +31,3 @@ const getStyles = stylesFactory(() => { textAlign: 'center', }, }); -}); diff --git a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx index c849c8edbfcd2..3fe1450c51c7c 100644 --- a/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx +++ b/packages/grafana-ui/src/components/ButtonCascader/ButtonCascader.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; import { IconName } from '../../types/icon'; import { Button, ButtonProps } from '../Button'; import { CascaderOption } from '../Cascader/Cascader'; @@ -27,27 +27,9 @@ export interface ButtonCascaderProps { hideDownIcon?: boolean; } -const getStyles = stylesFactory((theme: GrafanaTheme2) => { - return { - popup: css({ - label: 'popup', - zIndex: theme.zIndex.dropdown, - }), - icons: { - right: css({ - margin: '1px 0 0 4px', - }), - left: css({ - margin: '-1px 4px 0 0', - }), - }, - }; -}); - export const ButtonCascader = (props: ButtonCascaderProps) => { const { onChange, className, loadData, icon, buttonProps, hideDownIcon, variant, disabled, ...rest } = props; - const theme = useTheme2(); - const styles = getStyles(theme); + const styles = useStyles2(getStyles); // Weird way to do this bit it goes around a styling issue in Button where even null/undefined child triggers // styling change which messes up the look if there is only single icon content. @@ -72,3 +54,20 @@ export const ButtonCascader = (props: ButtonCascaderProps) => { }; ButtonCascader.displayName = 'ButtonCascader'; + +const getStyles = (theme: GrafanaTheme2) => { + return { + popup: css({ + label: 'popup', + zIndex: theme.zIndex.dropdown, + }), + icons: { + right: css({ + margin: '1px 0 0 4px', + }), + left: css({ + margin: '-1px 4px 0 0', + }), + }, + }; +}; diff --git a/packages/grafana-ui/src/components/Card/Card.tsx b/packages/grafana-ui/src/components/Card/Card.tsx index 0f34721e03135..4ebb077f1fa7b 100644 --- a/packages/grafana-ui/src/components/Card/Card.tsx +++ b/packages/grafana-ui/src/components/Card/Card.tsx @@ -3,7 +3,7 @@ import React, { memo, cloneElement, FC, useMemo, useContext, ReactNode } from 'r import { GrafanaTheme2 } from '@grafana/data'; -import { useStyles2, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; import { getFocusStyles } from '../../themes/mixins'; import { CardContainer, CardContainerProps, getCardContainerStyles } from './CardContainer'; @@ -55,8 +55,7 @@ export const Card: CardInterface = ({ disabled, href, onClick, children, isSelec const disableHover = disabled || (!onClick && !href); const onCardClick = onClick && !disabled ? onClick : undefined; - const theme = useTheme2(); - const styles = getCardContainerStyles(theme, disabled, disableHover, isSelected); + const styles = useStyles2(getCardContainerStyles, disabled, disableHover, isSelected); return ( @@ -100,7 +103,8 @@ const Heading = ({ children, className, 'aria-label': ariaLabel }: ChildProps & ) : ( <>{children} )} - {isSelected !== undefined && } + {/* Input must be readonly because we are providing a value for the checked prop with no onChange handler */} + {isSelected !== undefined && } ); }; @@ -120,6 +124,9 @@ const getHeadingStyles = (theme: GrafanaTheme2) => ({ lineHeight: theme.typography.body.lineHeight, color: theme.colors.text.primary, fontWeight: theme.typography.fontWeightMedium, + '& input[readonly]': { + cursor: 'inherit', + }, }), linkHack: css({ all: 'unset', @@ -283,22 +290,22 @@ const BaseActions = ({ children, disabled, variant, className }: ActionsProps) = const getActionStyles = (theme: GrafanaTheme2) => ({ actions: css({ + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap', + gap: theme.spacing(1), gridArea: 'Actions', marginTop: theme.spacing(2), - '& > *': { - marginRight: theme.spacing(1), - }, }), secondaryActions: css({ - display: 'flex', - gridArea: 'Secondary', alignSelf: 'center', color: theme.colors.text.secondary, - marginTtop: theme.spacing(2), - - '& > *': { - marginRight: `${theme.spacing(1)} !important`, - }, + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap', + gap: theme.spacing(1), + gridArea: 'Secondary', + marginTop: theme.spacing(2), }), }); diff --git a/packages/grafana-ui/src/components/Card/CardContainer.tsx b/packages/grafana-ui/src/components/Card/CardContainer.tsx index 7205f6df6cbbe..e4a52c9f1f23d 100644 --- a/packages/grafana-ui/src/components/Card/CardContainer.tsx +++ b/packages/grafana-ui/src/components/Card/CardContainer.tsx @@ -3,7 +3,7 @@ import React, { HTMLAttributes } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { styleMixins, stylesFactory, useStyles2, useTheme2 } from '../../themes'; +import { styleMixins, useStyles2 } from '../../themes'; /** * @public @@ -57,8 +57,8 @@ export const CardContainer = ({ href, ...props }: CardContainerProps) => { - const theme = useTheme2(); - const { oldContainer } = getCardContainerStyles(theme, disableEvents, disableHover, isSelected); + const { oldContainer } = useStyles2(getCardContainerStyles, disableEvents, disableHover, isSelected); + return (
    {children} @@ -66,71 +66,74 @@ export const CardContainer = ({ ); }; -export const getCardContainerStyles = stylesFactory( - (theme: GrafanaTheme2, disabled = false, disableHover = false, isSelected) => { - const isSelectable = isSelected !== undefined; +export const getCardContainerStyles = ( + theme: GrafanaTheme2, + disabled = false, + disableHover = false, + isSelected?: boolean +) => { + const isSelectable = isSelected !== undefined; - return { - container: css({ - display: 'grid', - position: 'relative', - gridTemplateColumns: 'auto 1fr auto', - gridTemplateRows: '1fr auto auto auto', - gridAutoColumns: '1fr', - gridAutoFlow: 'row', - gridTemplateAreas: ` + return { + container: css({ + display: 'grid', + position: 'relative', + gridTemplateColumns: 'auto 1fr auto', + gridTemplateRows: '1fr auto auto auto', + gridAutoColumns: '1fr', + gridAutoFlow: 'row', + gridTemplateAreas: ` "Figure Heading Tags" "Figure Meta Tags" "Figure Description Tags" "Figure Actions Secondary"`, - width: '100%', - padding: theme.spacing(2), - background: theme.colors.background.secondary, - borderRadius: theme.shape.radius.default, - marginBottom: '8px', - pointerEvents: disabled ? 'none' : 'auto', - transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], { - duration: theme.transitions.duration.short, - }), - - ...(!disableHover && { - '&:hover': { - background: theme.colors.emphasize(theme.colors.background.secondary, 0.03), - cursor: 'pointer', - zIndex: 1, - }, - '&:focus': styleMixins.getFocusStyles(theme), - }), + width: '100%', + padding: theme.spacing(2), + background: theme.colors.background.secondary, + borderRadius: theme.shape.radius.default, + marginBottom: '8px', + pointerEvents: disabled ? 'none' : 'auto', + transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], { + duration: theme.transitions.duration.short, + }), - ...(isSelectable && { + ...(!disableHover && { + '&:hover': { + background: theme.colors.emphasize(theme.colors.background.secondary, 0.03), cursor: 'pointer', - }), + zIndex: 1, + }, + '&:focus': styleMixins.getFocusStyles(theme), + }), - ...(isSelected && { - outline: `solid 2px ${theme.colors.primary.border}`, - }), + ...(isSelectable && { + cursor: 'pointer', }), - oldContainer: css({ - display: 'flex', - width: '100%', - background: theme.colors.background.secondary, - borderRadius: theme.shape.radius.default, - position: 'relative', - pointerEvents: disabled ? 'none' : 'auto', - marginBottom: theme.spacing(1), - transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], { - duration: theme.transitions.duration.short, - }), - ...(!disableHover && { - '&:hover': { - background: theme.colors.emphasize(theme.colors.background.secondary, 0.03), - cursor: 'pointer', - zIndex: 1, - }, - '&:focus': styleMixins.getFocusStyles(theme), - }), + ...(isSelected && { + outline: `solid 2px ${theme.colors.primary.border}`, + }), + }), + oldContainer: css({ + display: 'flex', + width: '100%', + background: theme.colors.background.secondary, + borderRadius: theme.shape.radius.default, + position: 'relative', + pointerEvents: disabled ? 'none' : 'auto', + marginBottom: theme.spacing(1), + transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color', 'color'], { + duration: theme.transitions.duration.short, }), - }; - } -); + + ...(!disableHover && { + '&:hover': { + background: theme.colors.emphasize(theme.colors.background.secondary, 0.03), + cursor: 'pointer', + zIndex: 1, + }, + '&:focus': styleMixins.getFocusStyles(theme), + }), + }), + }; +}; diff --git a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx index 9a9fe8ff3aba3..a6a90a6ed35ac 100644 --- a/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx +++ b/packages/grafana-ui/src/components/ContextMenu/ContextMenu.tsx @@ -39,7 +39,7 @@ export const ContextMenu = React.memo( setPositionStyles({ position: 'fixed', left: collisions.right ? x - rect.width - OFFSET : x - OFFSET, - top: collisions.bottom ? y - rect.height - OFFSET : y + OFFSET, + top: Math.max(0, collisions.bottom ? y - rect.height - OFFSET : y + OFFSET), }); } }, [x, y]); diff --git a/packages/grafana-ui/src/components/CustomScrollbar/ScrollIndicators.tsx b/packages/grafana-ui/src/components/CustomScrollbar/ScrollIndicators.tsx index eed018c364821..b22711457ffca 100644 --- a/packages/grafana-ui/src/components/CustomScrollbar/ScrollIndicators.tsx +++ b/packages/grafana-ui/src/components/CustomScrollbar/ScrollIndicators.tsx @@ -1,11 +1,9 @@ import { css, cx } from '@emotion/css'; -import classNames from 'classnames'; import React, { useEffect, useRef, useState } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2 } from '../../themes'; -import { Icon } from '../Icon/Icon'; export const ScrollIndicators = ({ children }: React.PropsWithChildren<{}>) => { const [showScrollTopIndicator, setShowTopScrollIndicator] = useState(false); @@ -39,9 +37,7 @@ export const ScrollIndicators = ({ children }: React.PropsWithChildren<{}>) => { className={cx(styles.scrollIndicator, styles.scrollTopIndicator, { [styles.scrollIndicatorVisible]: showScrollTopIndicator, })} - > - -
    + />
    {children} @@ -51,9 +47,7 @@ export const ScrollIndicators = ({ children }: React.PropsWithChildren<{}>) => { className={cx(styles.scrollIndicator, styles.scrollBottomIndicator, { [styles.scrollIndicatorVisible]: showScrollBottomIndicator, })} - > - -
    + /> ); }; @@ -85,16 +79,5 @@ const getStyles = (theme: GrafanaTheme2) => { scrollIndicatorVisible: css({ opacity: 1, }), - scrollIcon: css({ - left: '50%', - position: 'absolute', - transform: 'translateX(-50%)', - }), - scrollTopIcon: css({ - top: 0, - }), - scrollBottomIcon: css({ - bottom: 0, - }), }; }; diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx index 56c17d7e59a36..23dbd13c95f19 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksContextMenu.tsx @@ -24,11 +24,11 @@ export const DataLinksContextMenu = ({ children, links, style }: DataLinksContex const itemsGroup: MenuItemsGroup[] = [{ items: linkModelToContextMenuItems(links), label: 'Data links' }]; const linksCounter = itemsGroup[0].items.length; const renderMenuGroupItems = () => { - return itemsGroup.map((group, index) => ( - - {(group.items || []).map((item) => ( + return itemsGroup.map((group, groupIdx) => ( + + {(group.items || []).map((item, itemIdx) => ( { - const theme = useTheme2(); const [editIndex, setEditIndex] = useState(null); const [isNew, setIsNew] = useState(false); - const styles = getDataLinksInlineEditorStyles(theme); + const styles = useStyles2(getDataLinksInlineEditorStyles); const linksSafe: DataLink[] = links ?? []; const isEditing = editIndex !== null; @@ -110,10 +109,8 @@ export const DataLinksInlineEditor = ({ links, onChange, getSuggestions, data }: ); }; -const getDataLinksInlineEditorStyles = stylesFactory((theme: GrafanaTheme2) => { - return { - wrapper: css({ - marginBottom: theme.spacing(2), - }), - }; +const getDataLinksInlineEditorStyles = (theme: GrafanaTheme2) => ({ + wrapper: css({ + marginBottom: theme.spacing(2), + }), }); diff --git a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx index 86044da878258..97a23834fe7e2 100644 --- a/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx +++ b/packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { DataFrame, DataLink, GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory, useTheme2 } from '../../../themes'; +import { useStyles2 } from '../../../themes'; import { isCompactUrl } from '../../../utils/dataLinks'; import { FieldValidationMessage } from '../../Forms/FieldValidationMessage'; import { IconButton } from '../../IconButton/IconButton'; @@ -19,8 +19,7 @@ export interface DataLinksListItemProps { } export const DataLinksListItem = ({ link, onEdit, onRemove }: DataLinksListItemProps) => { - const theme = useTheme2(); - const styles = getDataLinkListItemStyles(theme); + const styles = useStyles2(getDataLinkListItemStyles); const { title = '', url = '' } = link; const hasTitle = title.trim() !== ''; @@ -52,7 +51,7 @@ export const DataLinksListItem = ({ link, onEdit, onRemove }: DataLinksListItemP ); }; -const getDataLinkListItemStyles = stylesFactory((theme: GrafanaTheme2) => { +const getDataLinkListItemStyles = (theme: GrafanaTheme2) => { return { wrapper: css({ marginBottom: theme.spacing(2), @@ -95,4 +94,4 @@ const getDataLinkListItemStyles = stylesFactory((theme: GrafanaTheme2) => { maxWidth: '90%', }), }; -}); +}; diff --git a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx index 8802e32193905..0751890d5a0c6 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx @@ -4,7 +4,7 @@ import React, { PureComponent } from 'react'; import { DataSourceSettings } from '@grafana/data'; -import { stylesFactory } from '../../themes'; +import { useStyles2 } from '../../themes'; import { Button } from '../Button'; import { FormField } from '../FormField/FormField'; import { Icon } from '../Icon/Icon'; @@ -36,26 +36,25 @@ interface CustomHeaderRowProps { onBlur: () => void; } -const getCustomHeaderRowStyles = stylesFactory(() => { - return { - layout: css({ - display: 'flex', - alignItems: 'center', - marginBottom: '4px', - '> *': { - marginLeft: '4px', - marginBottom: 0, - height: '100%', - '&:first-child, &:last-child': { - marginLeft: 0, - }, +const getCustomHeaderRowStyles = () => ({ + layout: css({ + display: 'flex', + alignItems: 'center', + marginBottom: '4px', + '> *': { + marginLeft: '4px', + marginBottom: 0, + height: '100%', + '&:first-child, &:last-child': { + marginLeft: 0, }, - }), - }; + }, + }), }); const CustomHeaderRow = ({ header, onBlur, onChange, onRemove, onReset }: CustomHeaderRowProps) => { - const styles = getCustomHeaderRowStyles(); + const styles = useStyles2(getCustomHeaderRowStyles); + return (
    { it('should update date onblur', async () => { const onChangeInput = jest.fn(); render(); - const dateTimeInput = screen.getByTestId('date-time-input'); + const dateTimeInput = screen.getByTestId(Components.DateTimePicker.input); await userEvent.clear(dateTimeInput); await userEvent.type(dateTimeInput, '2021-07-31 12:30:30'); expect(dateTimeInput).toHaveDisplayValue('2021-07-31 12:30:30'); @@ -44,7 +45,7 @@ describe('Date time picker', () => { it('should not update onblur if invalid date', async () => { const onChangeInput = jest.fn(); render(); - const dateTimeInput = screen.getByTestId('date-time-input'); + const dateTimeInput = screen.getByTestId(Components.DateTimePicker.input); await userEvent.clear(dateTimeInput); await userEvent.type(dateTimeInput, '2021:05:05 12-00-00'); expect(dateTimeInput).toHaveDisplayValue('2021:05:05 12-00-00'); diff --git a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx index c6d185672285e..e0e7f45a113fa 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx @@ -8,6 +8,7 @@ import { usePopper } from 'react-popper'; import { useMedia } from 'react-use'; import { dateTimeFormat, DateTime, dateTime, GrafanaTheme2, isDateTime } from '@grafana/data'; +import { Components } from '@grafana/e2e-selectors'; import { useStyles2, useTheme2 } from '../../../themes'; import { Button } from '../../Button/Button'; @@ -71,7 +72,7 @@ export const DateTimePicker = ({ const { dialogProps } = useDialog({}, ref); const theme = useTheme2(); - const { modalBackdrop } = getModalStyles(theme); + const { modalBackdrop } = useStyles2(getModalStyles); const isFullscreen = useMedia(`(min-width: ${theme.breakpoints.values.lg}px)`); const styles = useStyles2(getStyles); @@ -232,7 +233,7 @@ const DateTimeInput = React.forwardRef( addonAfter={icon} value={internalDate.value} onBlur={onBlur} - data-testid="date-time-input" + data-testid={Components.DateTimePicker.input} placeholder="Select date/time" ref={ref} /> diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx index d0eb37aa84e17..8a63f528743ad 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangeInput.tsx @@ -4,8 +4,7 @@ import React, { FormEvent, MouseEvent, useState } from 'react'; import { dateTime, getDefaultTimeRange, GrafanaTheme2, TimeRange, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { stylesFactory } from '../../themes'; -import { useTheme2 } from '../../themes/ThemeContext'; +import { useStyles2 } from '../../themes/ThemeContext'; import { ClickOutsideWrapper } from '../ClickOutsideWrapper/ClickOutsideWrapper'; import { Icon } from '../Icon/Icon'; import { getInputStyles } from '../Input/Input'; @@ -47,8 +46,7 @@ export const TimeRangeInput = ({ showIcon = false, }: TimeRangeInputProps) => { const [isOpen, setIsOpen] = useState(false); - const theme = useTheme2(); - const styles = getStyles(theme, disabled); + const styles = useStyles2(getStyles, disabled); const onOpen = (event: FormEvent) => { event.stopPropagation(); @@ -115,7 +113,7 @@ export const TimeRangeInput = ({ ); }; -const getStyles = stylesFactory((theme: GrafanaTheme2, disabled = false) => { +const getStyles = (theme: GrafanaTheme2, disabled = false) => { const inputStyles = getInputStyles({ theme, invalid: false }); return { container: css({ @@ -163,4 +161,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2, disabled = false) => { marginRight: theme.spacing(0.5), }), }; -}); +}; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx index fcbdb8349143a..13b46255d37a8 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.test.tsx @@ -1,10 +1,14 @@ -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import React from 'react'; import { dateTime, TimeRange } from '@grafana/data'; +import { selectors as e2eSelectors } from '@grafana/e2e-selectors'; import { TimeRangePicker } from './TimeRangePicker'; +const selectors = e2eSelectors.components.TimePicker; + const from = dateTime('2019-12-17T07:48:27.433Z'); const to = dateTime('2019-12-18T07:48:27.433Z'); @@ -29,4 +33,25 @@ describe('TimePicker', () => { expect(container.queryByLabelText(/Time range selected/i)).toBeInTheDocument(); }); + it('switches overlay content visibility when toolbar button is clicked twice', async () => { + render( + {}} + onChange={(value) => {}} + value={value} + onMoveBackward={() => {}} + onMoveForward={() => {}} + onZoom={() => {}} + /> + ); + + const openButton = screen.getByTestId(selectors.openButton); + const overlayContent = screen.queryByTestId(selectors.overlayContent); + + expect(overlayContent).not.toBeInTheDocument(); + await userEvent.click(openButton); + expect(screen.getByTestId(selectors.overlayContent)).toBeInTheDocument(); + await userEvent.click(openButton); + expect(overlayContent).not.toBeInTheDocument(); + }); }); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx index 1ce6ba3627eba..d59f7b6ec858b 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker.tsx @@ -2,10 +2,9 @@ import { css, cx } from '@emotion/css'; import { useDialog } from '@react-aria/dialog'; import { FocusScope } from '@react-aria/focus'; import { useOverlay } from '@react-aria/overlays'; -import React, { memo, FormEvent, createRef, useState } from 'react'; +import React, { memo, createRef, useState, useEffect } from 'react'; import { - isDateTime, rangeUtil, GrafanaTheme2, dateTimeFormat, @@ -16,7 +15,7 @@ import { } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { useStyles2, useTheme2 } from '../../themes/ThemeContext'; +import { useStyles2 } from '../../themes/ThemeContext'; import { t, Trans } from '../../utils/i18n'; import { ButtonGroup } from '../Button'; import { getModalStyles } from '../Modal/getModalStyles'; @@ -44,6 +43,7 @@ export interface TimeRangePickerProps { hideQuickRanges?: boolean; widthOverride?: number; isOnCanvas?: boolean; + onToolbarTimePickerClick?: () => void; } export interface State { @@ -68,6 +68,7 @@ export function TimeRangePicker(props: TimeRangePickerProps) { hideQuickRanges, widthOverride, isOnCanvas, + onToolbarTimePickerClick, } = props; const onChange = (timeRange: TimeRange) => { @@ -75,26 +76,44 @@ export function TimeRangePicker(props: TimeRangePickerProps) { setOpen(false); }; - const onOpen = (event: FormEvent) => { - event.stopPropagation(); - event.preventDefault(); - setOpen(!isOpen); + useEffect(() => { + if (isOpen && onToolbarTimePickerClick) { + onToolbarTimePickerClick(); + } + }, [isOpen, onToolbarTimePickerClick]); + + const onToolbarButtonSwitch = () => { + setOpen((prevState) => !prevState); }; const onClose = () => { setOpen(false); }; - const ref = createRef(); - const { overlayProps, underlayProps } = useOverlay({ onClose, isDismissable: true, isOpen }, ref); - const { dialogProps } = useDialog({}, ref); + const overlayRef = createRef(); + const buttonRef = createRef(); + const { overlayProps, underlayProps } = useOverlay( + { + onClose, + isDismissable: true, + isOpen, + shouldCloseOnInteractOutside: (element) => { + return !buttonRef.current?.contains(element); + }, + }, + overlayRef + ); + const { dialogProps } = useDialog({}, overlayRef); - const theme = useTheme2(); const styles = useStyles2(getStyles); - const { modalBackdrop } = getModalStyles(theme); - const hasAbsolute = isDateTime(value.raw.from) || isDateTime(value.raw.to); + const { modalBackdrop } = useStyles2(getModalStyles); + const hasAbsolute = !rangeUtil.isRelativeTime(value.raw.from) || !rangeUtil.isRelativeTime(value.raw.to); + const variant = isSynced ? 'active' : isOnCanvas ? 'canvas' : 'default'; + const isFromAfterTo = value?.to?.isBefore(value.from); + const timePickerIcon = isFromAfterTo ? 'exclamation-triangle' : 'clock-nine'; + const currentTimeRange = formattedRange(value, timeZone); return ( @@ -109,15 +128,20 @@ export function TimeRangePicker(props: TimeRangePickerProps) { /> )} - } placement="bottom" interactive> + } + placement="bottom" + interactive + > @@ -125,10 +149,10 @@ export function TimeRangePicker(props: TimeRangePickerProps) { {isOpen && ( -
    +
    -
    +
    - + -
    + + + ); } Footer.displayName = 'Footer'; - -const getFooterStyles = (theme: GrafanaTheme2) => { - return { - container: css({ - backgroundColor: theme.colors.background.primary, - display: 'flex', - justifyContent: 'center', - padding: '10px', - alignItems: 'stretch', - }), - apply: css({ - marginRight: '4px', - width: '100%', - justifyContent: 'center', - }), - }; -}; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx index f87fcca805b64..c09d39d198a6e 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/CalendarHeader.tsx @@ -1,44 +1,30 @@ -import { css } from '@emotion/css'; import React from 'react'; -import { GrafanaTheme2 } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { useStyles2 } from '../../../themes'; -import { Trans } from '../../../utils/i18n'; -import { Button } from '../../Button'; +import { Trans, t } from '../../../utils/i18n'; +import { IconButton } from '../../IconButton/IconButton'; +import { Stack } from '../../Layout/Stack/Stack'; import { TimePickerCalendarProps } from './TimePickerCalendar'; import { TimePickerTitle } from './TimePickerTitle'; export function Header({ onClose }: TimePickerCalendarProps) { - const styles = useStyles2(getHeaderStyles); - return ( -
    + Select a time range -
    + ); } Header.displayName = 'Header'; - -const getHeaderStyles = (theme: GrafanaTheme2) => { - return { - container: css({ - backgroundColor: theme.colors.background.primary, - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - padding: '7px', - }), - }; -}; diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx index 2e32795301ee1..9b39f55f4afd7 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerCalendar.tsx @@ -7,7 +7,7 @@ import React, { FormEvent, memo } from 'react'; import { DateTime, GrafanaTheme2, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { useTheme2 } from '../../../themes'; +import { useStyles2, useTheme2 } from '../../../themes'; import { getModalStyles } from '../../Modal/getModalStyles'; import { Body } from './CalendarBody'; @@ -19,27 +19,28 @@ export const getStyles = (theme: GrafanaTheme2, isReversed = false) => { container: css({ top: 0, position: 'absolute', - [`${isReversed ? 'left' : 'right'}`]: '544px', + [`${isReversed ? 'left' : 'right'}`]: '546px', // lmao + }), + + modalContainer: css({ + label: 'modalContainer', + margin: '0 auto', + }), + + calendar: css({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(1), + padding: theme.spacing(1), + label: 'calendar', boxShadow: theme.shadows.z3, backgroundColor: theme.colors.background.primary, - zIndex: -1, border: `1px solid ${theme.colors.border.weak}`, - borderTopLeftRadius: theme.shape.radius.default, - borderBottomLeftRadius: theme.shape.radius.default, - - '&:after': { - display: 'block', - backgroundColor: theme.colors.background.primary, - width: '19px', - height: '100%', - content: `${!isReversed ? '" "' : '""'}`, - position: 'absolute', - top: 0, - right: '-19px', - borderLeft: `1px solid ${theme.colors.border.weak}`, - }, + borderRadius: theme.shape.radius.default, }), + modal: css({ + label: 'modal', boxShadow: theme.shadows.z3, left: '50%', position: 'fixed', @@ -47,10 +48,6 @@ export const getStyles = (theme: GrafanaTheme2, isReversed = false) => { transform: 'translate(-50%, -50%)', zIndex: theme.zIndex.modal, }), - content: css({ - margin: '0 auto', - width: '268px', - }), }; }; @@ -61,6 +58,11 @@ export interface TimePickerCalendarProps { onClose: () => void; onApply: (e: FormEvent) => void; onChange: (from: DateTime, to: DateTime) => void; + + /** + * When true, the calendar is rendered as a floating "tooltip" next to the input. + * When false, the calendar is rendered "fullscreen" in a modal. Yes. Don't ask. + */ isFullscreen: boolean; timeZone?: TimeZone; isReversed?: boolean; @@ -68,9 +70,9 @@ export interface TimePickerCalendarProps { function TimePickerCalendar(props: TimePickerCalendarProps) { const theme = useTheme2(); - const { modalBackdrop } = getModalStyles(theme); + const { modalBackdrop } = useStyles2(getModalStyles); const styles = getStyles(theme, props.isReversed); - const { isOpen, isFullscreen, onClose } = props; + const { isOpen, isFullscreen: isFullscreenProp, onClose } = props; const ref = React.createRef(); const { dialogProps } = useDialog( { @@ -87,17 +89,31 @@ function TimePickerCalendar(props: TimePickerCalendarProps) { ref ); + // This prop is confusingly worded, so rename it to something more intuitive. + const showInModal = !isFullscreenProp; + if (!isOpen) { return null; } - if (isFullscreen) { + const calendar = ( +
    +
    + + {showInModal &&
    } +
    + ); + + if (!showInModal) { return ( -
    -
    - -
    +
    {calendar}
    ); } @@ -105,14 +121,11 @@ function TimePickerCalendar(props: TimePickerCalendarProps) { return (
    + -
    -
    -
    - -
    -
    -
    +
    +
    {calendar}
    +
    ); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx index 40d9dc2b693bc..ba9c9a4f011e2 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.test.tsx @@ -96,22 +96,22 @@ describe('TimePickerContent', () => { it('renders with absolute picker when absolute value and quick ranges are visible', () => { renderComponent({ value: absoluteValue, isFullscreen: false }); - expect(screen.queryByLabelText(/time range from field/i)).toBeInTheDocument(); + expect(screen.queryByLabelText('From')).toBeInTheDocument(); }); it('renders with absolute picker when absolute value and quick ranges are hidden', () => { renderComponent({ value: absoluteValue, isFullscreen: false, hideQuickRanges: true }); - expect(screen.queryByLabelText(/time range from field/i)).toBeInTheDocument(); + expect(screen.queryByLabelText('From')).toBeInTheDocument(); }); it('renders without absolute picker when narrow screen and quick ranges are visible', () => { renderComponent({ value: relativeValue, isFullscreen: false }); - expect(screen.queryByLabelText(/time range from field/i)).not.toBeInTheDocument(); + expect(screen.queryByLabelText('From')).not.toBeInTheDocument(); }); it('renders with absolute picker when narrow screen and quick ranges are hidden', () => { renderComponent({ value: relativeValue, isFullscreen: false, hideQuickRanges: true }); - expect(screen.queryByLabelText(/time range from field/i)).toBeInTheDocument(); + expect(screen.queryByLabelText('From')).toBeInTheDocument(); }); it('renders without timezone picker', () => { diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx index 48d28f1e2fe9e..a0bc70b19ccf3 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerContent.tsx @@ -4,7 +4,7 @@ import React, { memo, useMemo, useState } from 'react'; import { GrafanaTheme2, isDateTime, rangeUtil, RawTimeRange, TimeOption, TimeRange, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { stylesFactory, useTheme2 } from '../../../themes'; +import { useStyles2, useTheme2 } from '../../../themes'; import { getFocusStyles } from '../../../themes/mixins'; import { t, Trans } from '../../../utils/i18n'; import { CustomScrollbar } from '../../CustomScrollbar/CustomScrollbar'; @@ -63,8 +63,7 @@ export const TimePickerContentWithScreenSize = (props: PropsWithScreenSize) => { const isHistoryEmpty = !history?.length; const isContainerTall = (isFullscreen && showHistory) || (!isFullscreen && ((showHistory && !isHistoryEmpty) || !hideQuickRanges)); - const theme = useTheme2(); - const styles = getStyles(theme, isReversed, hideQuickRanges, isContainerTall, isFullscreen); + const styles = useStyles2(getStyles, isReversed, hideQuickRanges, isContainerTall, isFullscreen); const historyOptions = mapToHistoryOptions(history, timeZone); const timeOption = useTimeOption(value.raw, quickOptions); const [searchTerm, setSearchQuery] = useState(''); @@ -124,8 +123,7 @@ export const TimePickerContent = (props: Props) => { const NarrowScreenForm = (props: FormProps) => { const { value, hideQuickRanges, onChange, timeZone, historyOptions = [], showHistory } = props; - const theme = useTheme2(); - const styles = getNarrowScreenStyles(theme); + const styles = useStyles2(getNarrowScreenStyles); const isAbsolute = isDateTime(value.raw.from) || isDateTime(value.raw.to); const [collapsedFlag, setCollapsedFlag] = useState(!isAbsolute); const collapsed = hideQuickRanges ? false : collapsedFlag; @@ -176,8 +174,7 @@ const NarrowScreenForm = (props: FormProps) => { const FullScreenForm = (props: FormProps) => { const { onChange, value, timeZone, fiscalYearStartMonth, isReversed, historyOptions } = props; - const theme = useTheme2(); - const styles = getFullScreenStyles(theme, props.hideQuickRanges); + const styles = useStyles2(getFullScreenStyles, props.hideQuickRanges); const onChangeTimeOption = (timeOption: TimeOption) => { return onChange(mapOptionToTimeRange(timeOption, timeZone)); }; @@ -214,8 +211,7 @@ const FullScreenForm = (props: FormProps) => { }; const EmptyRecentList = memo(() => { - const theme = useTheme2(); - const styles = getEmptyListStyles(theme); + const styles = useStyles2(getEmptyListStyles); const emptyRecentListText = t( 'time-picker.content.empty-recent-list-info', "It looks like you haven't used this time picker before. As soon as you enter some time intervals, recently used intervals will appear here." @@ -263,104 +259,102 @@ const useTimeOption = (raw: RawTimeRange, quickOptions: TimeOption[]): TimeOptio }, [raw, quickOptions]); }; -const getStyles = stylesFactory((theme: GrafanaTheme2, isReversed, hideQuickRanges, isContainerTall, isFullscreen) => { - return { - container: css({ - background: theme.colors.background.primary, - boxShadow: theme.shadows.z3, - width: `${isFullscreen ? '546px' : '262px'}`, - borderRadius: theme.shape.radius.default, - border: `1px solid ${theme.colors.border.weak}`, - [`${isReversed ? 'left' : 'right'}`]: 0, - }), - body: css({ - display: 'flex', - flexDirection: 'row-reverse', - height: `${isContainerTall ? '381px' : '217px'}`, - maxHeight: '100vh', - }), - leftSide: css({ - display: 'flex', - flexDirection: 'column', - borderRight: `${isReversed ? 'none' : `1px solid ${theme.colors.border.weak}`}`, - width: `${!hideQuickRanges ? '60%' : '100%'}`, - overflow: 'hidden', - order: isReversed ? 1 : 0, - }), - rightSide: css({ - width: `${isFullscreen ? '40%' : '100%'}; !important`, - borderRight: isReversed ? `1px solid ${theme.colors.border.weak}` : 'none', - display: 'flex', - flexDirection: 'column', - }), - timeRangeFilter: css({ - padding: theme.spacing(1), - }), - spacing: css({ - marginTop: '16px', - }), - }; +const getStyles = ( + theme: GrafanaTheme2, + isReversed?: boolean, + hideQuickRanges?: boolean, + isContainerTall?: boolean, + isFullscreen?: boolean +) => ({ + container: css({ + background: theme.colors.background.primary, + boxShadow: theme.shadows.z3, + width: `${isFullscreen ? '546px' : '262px'}`, + borderRadius: theme.shape.radius.default, + border: `1px solid ${theme.colors.border.weak}`, + [`${isReversed ? 'left' : 'right'}`]: 0, + }), + body: css({ + display: 'flex', + flexDirection: 'row-reverse', + height: `${isContainerTall ? '381px' : '217px'}`, + maxHeight: '100vh', + }), + leftSide: css({ + display: 'flex', + flexDirection: 'column', + borderRight: `${isReversed ? 'none' : `1px solid ${theme.colors.border.weak}`}`, + width: `${!hideQuickRanges ? '60%' : '100%'}`, + overflow: 'hidden', + order: isReversed ? 1 : 0, + }), + rightSide: css({ + width: `${isFullscreen ? '40%' : '100%'}; !important`, + borderRight: isReversed ? `1px solid ${theme.colors.border.weak}` : 'none', + display: 'flex', + flexDirection: 'column', + }), + timeRangeFilter: css({ + padding: theme.spacing(1), + }), + spacing: css({ + marginTop: '16px', + }), }); -const getNarrowScreenStyles = stylesFactory((theme: GrafanaTheme2) => { - return { - header: css({ - display: 'flex', - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - borderBottom: `1px solid ${theme.colors.border.weak}`, - padding: '7px 9px 7px 9px', - }), - expandButton: css({ - backgroundColor: 'transparent', - border: 'none', - display: 'flex', - width: '100%', +const getNarrowScreenStyles = (theme: GrafanaTheme2) => ({ + header: css({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + borderBottom: `1px solid ${theme.colors.border.weak}`, + padding: '7px 9px 7px 9px', + }), + expandButton: css({ + backgroundColor: 'transparent', + border: 'none', + display: 'flex', + width: '100%', - '&:focus-visible': getFocusStyles(theme), - }), - body: css({ - borderBottom: `1px solid ${theme.colors.border.weak}`, - }), - form: css({ - padding: '7px 9px 7px 9px', - }), - }; + '&:focus-visible': getFocusStyles(theme), + }), + body: css({ + borderBottom: `1px solid ${theme.colors.border.weak}`, + }), + form: css({ + padding: '7px 9px 7px 9px', + }), }); -const getFullScreenStyles = stylesFactory((theme: GrafanaTheme2, hideQuickRanges?: boolean) => { - return { - container: css({ - paddingTop: '9px', - paddingLeft: '11px', - paddingRight: !hideQuickRanges ? '20%' : '11px', - }), - title: css({ - marginBottom: '11px', - }), - recent: css({ - flexGrow: 1, - display: 'flex', - flexDirection: 'column', - justifyContent: 'flex-end', - paddingTop: theme.spacing(1), - }), - }; +const getFullScreenStyles = (theme: GrafanaTheme2, hideQuickRanges?: boolean) => ({ + container: css({ + paddingTop: '9px', + paddingLeft: '11px', + paddingRight: !hideQuickRanges ? '20%' : '11px', + }), + title: css({ + marginBottom: '11px', + }), + recent: css({ + flexGrow: 1, + display: 'flex', + flexDirection: 'column', + justifyContent: 'flex-end', + paddingTop: theme.spacing(1), + }), }); -const getEmptyListStyles = stylesFactory((theme: GrafanaTheme2) => { - return { - container: css({ - padding: '12px', - margin: '12px', +const getEmptyListStyles = (theme: GrafanaTheme2) => ({ + container: css({ + padding: '12px', + margin: '12px', - 'a, span': { - fontSize: '13px', - }, - }), - link: css({ - color: theme.colors.text.link, - }), - }; + 'a, span': { + fontSize: '13px', + }, + }), + link: css({ + color: theme.colors.text.link, + }), }); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx index 3286314f7efff..67e14033bdf2b 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimePickerFooter.tsx @@ -5,7 +5,7 @@ import React, { useCallback, useState } from 'react'; import { getTimeZoneInfo, GrafanaTheme2, TimeZone } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; -import { stylesFactory, useTheme2 } from '../../../themes'; +import { useStyles2 } from '../../../themes'; import { t, Trans } from '../../../utils/i18n'; import { Button } from '../../Button'; import { Field } from '../../Forms/Field'; @@ -46,8 +46,7 @@ export const TimePickerFooter = (props: Props) => { [isEditing, setEditing] ); - const theme = useTheme2(); - const style = getStyle(theme); + const style = useStyles2(getStyle); if (!isString(timeZone)) { return null; @@ -110,7 +109,7 @@ export const TimePickerFooter = (props: Props) => { ) : (
    { ); }; -const getStyle = stylesFactory((theme: GrafanaTheme2) => { - return { - container: css({ - borderTop: `1px solid ${theme.colors.border.weak}`, - padding: '11px', - display: 'flex', - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - }), - editContainer: css({ - borderTop: `1px solid ${theme.colors.border.weak}`, - padding: '11px', - justifyContent: 'space-between', - alignItems: 'center', - }), - spacer: css({ - marginLeft: '7px', - }), - timeSettingContainer: css({ - paddingTop: theme.spacing(1), - }), - fiscalYearField: css({ - marginBottom: 0, - }), - timeZoneContainer: css({ - display: 'flex', - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - flexGrow: 1, - }), - timeZone: css({ - display: 'flex', - flexDirection: 'row', - alignItems: 'baseline', - flexGrow: 1, - }), - }; +const getStyle = (theme: GrafanaTheme2) => ({ + container: css({ + borderTop: `1px solid ${theme.colors.border.weak}`, + padding: '11px', + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + }), + editContainer: css({ + borderTop: `1px solid ${theme.colors.border.weak}`, + padding: '11px', + justifyContent: 'space-between', + alignItems: 'center', + }), + spacer: css({ + marginLeft: '7px', + }), + timeSettingContainer: css({ + paddingTop: theme.spacing(1), + }), + fiscalYearField: css({ + marginBottom: 0, + }), + timeZoneContainer: css({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + flexGrow: 1, + }), + timeZone: css({ + display: 'flex', + flexDirection: 'row', + alignItems: 'baseline', + flexGrow: 1, + }), }); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.test.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.test.tsx index ac074c9ae281f..a03b7c5ea7d9f 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.test.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.test.tsx @@ -36,18 +36,17 @@ function setup(initial: TimeRange = defaultTimeRange, timeZone = 'utc'): TimeRan describe('TimeRangeForm', () => { it('should render form correcty', () => { const { getByLabelText, getByText, getAllByRole } = setup(); - const { TimePicker } = selectors.components; expect(getByText('Apply time range')).toBeInTheDocument(); - expect(getAllByRole('button', { name: TimePicker.calendar.openButton })).toHaveLength(2); - expect(getByLabelText(TimePicker.fromField)).toBeInTheDocument(); - expect(getByLabelText(TimePicker.toField)).toBeInTheDocument(); + expect(getAllByRole('button', { name: 'Open calendar' })).toHaveLength(2); + expect(getByLabelText('From')).toBeInTheDocument(); + expect(getByLabelText('To')).toBeInTheDocument(); }); it('should display calendar when clicking the calendar icon', () => { const { getByLabelText, getAllByRole } = setup(); const { TimePicker } = selectors.components; - const openCalendarButton = getAllByRole('button', { name: TimePicker.calendar.openButton }); + const openCalendarButton = getAllByRole('button', { name: 'Open calendar' }); fireEvent.click(openCalendarButton[0]); expect(getByLabelText(TimePicker.calendar.label)).toBeInTheDocument(); @@ -55,24 +54,23 @@ describe('TimeRangeForm', () => { it('should have passed time range entered in form', () => { const { getByLabelText } = setup(); - const { TimePicker } = selectors.components; const fromValue = defaultTimeRange.raw.from as string; const toValue = defaultTimeRange.raw.to as string; - expect(getByLabelText(TimePicker.fromField)).toHaveValue(fromValue); - expect(getByLabelText(TimePicker.toField)).toHaveValue(toValue); + expect(getByLabelText('From')).toHaveValue(fromValue); + expect(getByLabelText('To')).toHaveValue(toValue); }); it('should close calendar when clicking the close icon', () => { const { queryByLabelText, getAllByRole, getByRole } = setup(); const { TimePicker } = selectors.components; - const openCalendarButton = getAllByRole('button', { name: TimePicker.calendar.openButton }); + const openCalendarButton = getAllByRole('button', { name: 'Open calendar' }); fireEvent.click(openCalendarButton[0]); - expect(getByRole('button', { name: TimePicker.calendar.closeButton })).toBeInTheDocument(); + expect(getByRole('button', { name: 'Close calendar' })).toBeInTheDocument(); - fireEvent.click(getByRole('button', { name: TimePicker.calendar.closeButton })); + fireEvent.click(getByRole('button', { name: 'Close calendar' })); expect(queryByLabelText(TimePicker.calendar.label)).toBeNull(); }); @@ -85,8 +83,7 @@ describe('TimeRangeForm', () => { it('should have passed time range selected in calendar', () => { const { getAllByRole, getCalendarDayByLabelText } = setup(); - const { TimePicker } = selectors.components; - const openCalendarButton = getAllByRole('button', { name: TimePicker.calendar.openButton }); + const openCalendarButton = getAllByRole('button', { name: 'Open calendar' }); fireEvent.click(openCalendarButton[0]); const from = getCalendarDayByLabelText('June 17, 2021'); @@ -98,8 +95,7 @@ describe('TimeRangeForm', () => { it('should select correct time range in calendar when having a custom time zone', () => { const { getAllByRole, getCalendarDayByLabelText } = setup(defaultTimeRange, 'Asia/Tokyo'); - const { TimePicker } = selectors.components; - const openCalendarButton = getAllByRole('button', { name: TimePicker.calendar.openButton }); + const openCalendarButton = getAllByRole('button', { name: 'Open calendar' }); fireEvent.click(openCalendarButton[1]); const from = getCalendarDayByLabelText('June 17, 2021'); diff --git a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx index a91d10282ae78..4cbf3748b4d10 100644 --- a/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx +++ b/packages/grafana-ui/src/components/DateTimePickers/TimeRangePicker/TimeRangeContent.tsx @@ -1,5 +1,5 @@ import { css } from '@emotion/css'; -import React, { FormEvent, useCallback, useEffect, useState } from 'react'; +import React, { FormEvent, useCallback, useEffect, useId, useState } from 'react'; import { DateTime, @@ -55,6 +55,9 @@ export const TimeRangeContent = (props: Props) => { const [to, setTo] = useState(toValue); const [isOpen, setOpen] = useState(false); + const fromFieldId = useId(); + const toFieldId = useId(); + // Synchronize internal state with external value useEffect(() => { const [fromValue, toValue] = valueToState(value.raw.from, value.raw.to, timeZone); @@ -113,7 +116,8 @@ export const TimeRangeContent = (props: Props) => { const icon = ( - - - - - - - - - - - - - - - - - - - - - - I am a card heading - - - - I am a card heading - Ohhhhh - and now a description and some actions - - - - - - - - I am a card heading - Ohhhhh - and now a description! - - - - - - - I am a card heading - - - - I am a card heading - Ohhhhh - and now a description and some actions - - - - - - - - I am a card heading - Ohhhhh - and now a description! - - - - - - -
    - - - - - - - - - - - - - - - - - -
    - -

    Child alignment

    - -
    - - - -
    - - -
    - - - -
    - - - - - I am a card heading - - - - I am a card heading - Ohhhhh - and now a description and some actions - - - - - - - - I am a card heading - Ohhhhh - and now a description! - - - - - - - - I am a card heading - - - - I am a card heading - Ohhhhh - and now a description! - - - - - - - - - - - - - - - - - - - - - Surprise - a description! What will happen to the height of all the other alerts? - - - - - -
    - ); -}; - -function Example({ title, children }: { title: string; children: React.ReactNode }) { - return ( -
    - {title} -
    {children}
    -
    - ); -} - -function MyComponent({ children }: { children: React.ReactNode }) { - return
    {children}
    ; -} - -export default meta; diff --git a/packages/grafana-ui/src/components/Layout/Stack/Stack.mdx b/packages/grafana-ui/src/components/Layout/Stack/Stack.mdx index b21e7652f8ff3..046f414b697ca 100644 --- a/packages/grafana-ui/src/components/Layout/Stack/Stack.mdx +++ b/packages/grafana-ui/src/components/Layout/Stack/Stack.mdx @@ -1,44 +1,27 @@ -import { Meta, ArgTypes, Canvas } from '@storybook/blocks'; -import { Stack, HorizontalStack } from './index'; -import * as Stories from './Stack.internal.story'; +import { Meta, ArgTypes } from '@storybook/blocks'; +import { Stack } from './Stack'; # Stack -The `Stack` component is designed to assist with layout and positioning of elements within a container, offering a simple and flexible way to stack elements vertically or horizontally. This documentation outlines the proper usage of the Stack component and provides guidance on when to use it over the Grid or Flex components. - -There is also a `HorizontalStack` component, which is a thin wrapper around Stack, equivalent to ``. +The Stack component is a simple wrapper around the flexbox layout model that allows to easily create responsive and flexible layouts. It provides a simple and intuitive way to align and distribute items within a container either horizontally or vertically. ### Usage #### When to use -Use the Stack component when you need to arrange elements in a linear format, either vertically or horizontally. It's particularly useful when you want to maintain consistent spacing between items. - -Use the Stack component when: - -- You need a simple way to stack elements with predictable spacing. -- You want to ensure consistent alignment. +- For creating responsive and flexible layouts that can adapt to different screen sizes and orientations. +- When needing a simple and intuitive way to align and distribute items within a container either horizontally or vertically. +- To easily reorder and rearrange elements without changing the HTML structure. +- When aiming to create equal height columns. +- To create a grid-like structure with automatic wrapping and sizing of items based on the available space. #### When not to use -Use the `Grid` component instead for these use cases: - -- **Intricate Layouts:** Grids are ideal for complex dashboard and magazine-style designs with rows and columns. -- **Structured Grid:** Use Grids when items need to span multiple rows/columns, creating structured layouts. - -Use the `Flex` component instead for these use cases: +- For complex multi-dimensional layouts with intricate requirements that are better suited for CSS frameworks or grid systems. +- When precise control over spacing and positioning of elements is necessary. -- **Alignment:** More options for item alignment. -- **Flex items:** Custom flex basis or configure how items stretch and wrap. - -## Props - -### Stack +### Props - -### HorizontalStack - - diff --git a/packages/grafana-ui/src/components/Layout/Flex/Flex.internal.story.tsx b/packages/grafana-ui/src/components/Layout/Stack/Stack.story.tsx similarity index 72% rename from packages/grafana-ui/src/components/Layout/Flex/Flex.internal.story.tsx rename to packages/grafana-ui/src/components/Layout/Stack/Stack.story.tsx index 4bada87b32b47..259c67e913258 100644 --- a/packages/grafana-ui/src/components/Layout/Flex/Flex.internal.story.tsx +++ b/packages/grafana-ui/src/components/Layout/Stack/Stack.story.tsx @@ -5,9 +5,10 @@ import { ThemeSpacingTokens } from '@grafana/data'; import { useTheme2 } from '../../../themes'; import { SpacingTokenControl } from '../../../utils/storybook/themeStorybookControls'; +import { JustifyContent, Wrap, Direction } from '../types'; -import { Flex, JustifyContent, Wrap, Direction } from './Flex'; -import mdx from './Flex.mdx'; +import { Stack } from './Stack'; +import mdx from './Stack.mdx'; const Item = ({ color, text, height }: { color: string; text?: string | number; height?: string }) => { return ( @@ -26,9 +27,9 @@ const Item = ({ color, text, height }: { color: string; text?: string | number; ); }; -const meta: Meta = { - title: 'General/Layout/Flex', - component: Flex, +const meta: Meta = { + title: 'General/Layout/Stack', + component: Stack, parameters: { docs: { page: mdx, @@ -36,15 +37,15 @@ const meta: Meta = { }, }; -export const Basic: StoryFn = ({ direction, wrap, alignItems, justifyContent, gap }) => { +export const Basic: StoryFn = ({ direction, wrap, alignItems, justifyContent, gap }) => { const theme = useTheme2(); return (
    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - +
    ); }; @@ -74,48 +75,48 @@ Basic.argTypes = { }, }; -export const AlignItemsExamples: StoryFn = () => { +export const AlignItemsExamples: StoryFn = () => { const theme = useTheme2(); return (

    Align items flex-start

    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - +

    Align items flex-end

    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - +

    Align items baseline

    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - +

    Align items center

    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - +

    Align items stretch

    - + - +
    ); }; -export const JustifyContentExamples: StoryFn = () => { +export const JustifyContentExamples: StoryFn = () => { const theme = useTheme2(); const justifyContentOptions: JustifyContent[] = [ 'space-between', @@ -131,18 +132,18 @@ export const JustifyContentExamples: StoryFn = () => { {justifyContentOptions.map((justifyContent) => ( <>

    Justify Content {justifyContent}

    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - +
    ))}
    ); }; -export const GapExamples: StoryFn = () => { +export const GapExamples: StoryFn = () => { const theme = useTheme2(); const gapOptions: ThemeSpacingTokens[] = [2, 8, 10]; return ( @@ -150,18 +151,18 @@ export const GapExamples: StoryFn = () => { {gapOptions.map((gap) => ( <>

    Gap with spacingToken set to {gap}

    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - + ))}
    ); }; -export const WrapExamples: StoryFn = () => { +export const WrapExamples: StoryFn = () => { const theme = useTheme2(); const wrapOptions: Wrap[] = ['nowrap', 'wrap', 'wrap-reverse']; return ( @@ -169,18 +170,18 @@ export const WrapExamples: StoryFn = () => { {wrapOptions.map((wrap) => ( <>

    Wrap examples with {wrap} and gap set to spacingToken 2 (16px)

    - + {Array.from({ length: 10 }).map((_, i) => ( ))} - + ))}
    ); }; -export const DirectionExamples: StoryFn = () => { +export const DirectionExamples: StoryFn = () => { const theme = useTheme2(); const directionOptions: Direction[] = ['row', 'row-reverse', 'column', 'column-reverse']; return ( @@ -188,11 +189,11 @@ export const DirectionExamples: StoryFn = () => { {directionOptions.map((direction) => ( <>

    Direction {direction}

    - + {Array.from({ length: 5 }).map((_, i) => ( ))} - + ))}
    diff --git a/packages/grafana-ui/src/components/Layout/Stack/Stack.tsx b/packages/grafana-ui/src/components/Layout/Stack/Stack.tsx index 2e24f2332f9d3..835282b8e171c 100644 --- a/packages/grafana-ui/src/components/Layout/Stack/Stack.tsx +++ b/packages/grafana-ui/src/components/Layout/Stack/Stack.tsx @@ -1,26 +1,78 @@ +import { css } from '@emotion/css'; import React from 'react'; -import { ThemeSpacingTokens } from '@grafana/data'; +import { GrafanaTheme2, ThemeSpacingTokens } from '@grafana/data'; -import { Flex } from '../Flex/Flex'; -import { ResponsiveProp } from '../utils/responsiveness'; -interface StackProps extends Omit, 'className' | 'style'> { - direction?: ResponsiveProp<'column' | 'row'>; +import { useStyles2 } from '../../../themes'; +import { AlignItems, Direction, FlexProps, JustifyContent, Wrap } from '../types'; +import { ResponsiveProp, getResponsiveStyle } from '../utils/responsiveness'; + +interface StackProps extends FlexProps, Omit, 'className' | 'style'> { gap?: ResponsiveProp; + alignItems?: ResponsiveProp; + justifyContent?: ResponsiveProp; + direction?: ResponsiveProp; + wrap?: ResponsiveProp; + children?: React.ReactNode; } -export const Stack = React.forwardRef>( - ({ gap = 1, direction = 'column', children, ...rest }, ref) => { - return ( - - {React.Children.toArray(children) - .filter(Boolean) - .map((child, index) => ( -
    {child}
    - ))} -
    - ); - } -); +export const Stack = React.forwardRef((props, ref) => { + const { gap = 1, alignItems, justifyContent, direction, wrap, children, grow, shrink, basis, flex, ...rest } = props; + const styles = useStyles2(getStyles, gap, alignItems, justifyContent, direction, wrap, grow, shrink, basis, flex); + + return ( +
    + {children} +
    + ); +}); Stack.displayName = 'Stack'; + +const getStyles = ( + theme: GrafanaTheme2, + gap: StackProps['gap'], + alignItems: StackProps['alignItems'], + justifyContent: StackProps['justifyContent'], + direction: StackProps['direction'], + wrap: StackProps['wrap'], + grow: StackProps['grow'], + shrink: StackProps['shrink'], + basis: StackProps['basis'], + flex: StackProps['flex'] +) => { + return { + flex: css([ + { + display: 'flex', + }, + getResponsiveStyle(theme, direction, (val) => ({ + flexDirection: val, + })), + getResponsiveStyle(theme, wrap, (val) => ({ + flexWrap: val, + })), + getResponsiveStyle(theme, alignItems, (val) => ({ + alignItems: val, + })), + getResponsiveStyle(theme, justifyContent, (val) => ({ + justifyContent: val, + })), + getResponsiveStyle(theme, gap, (val) => ({ + gap: theme.spacing(val), + })), + getResponsiveStyle(theme, grow, (val) => ({ + flexGrow: val, + })), + getResponsiveStyle(theme, shrink, (val) => ({ + flexShrink: val, + })), + getResponsiveStyle(theme, basis, (val) => ({ + flexBasis: val, + })), + getResponsiveStyle(theme, flex, (val) => ({ + flex: val, + })), + ]), + }; +}; diff --git a/packages/grafana-ui/src/components/Layout/Stack/index.ts b/packages/grafana-ui/src/components/Layout/Stack/index.ts deleted file mode 100644 index 89768e71dc004..0000000000000 --- a/packages/grafana-ui/src/components/Layout/Stack/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Stack } from './Stack'; -export { HorizontalStack } from './HorizontalStack'; diff --git a/packages/grafana-ui/src/components/Layout/types.ts b/packages/grafana-ui/src/components/Layout/types.ts new file mode 100644 index 0000000000000..b31f68c97abb8 --- /dev/null +++ b/packages/grafana-ui/src/components/Layout/types.ts @@ -0,0 +1,51 @@ +import { ResponsiveProp } from './utils/responsiveness'; + +export type AlignItems = + | 'stretch' + | 'flex-start' + | 'flex-end' + | 'center' + | 'baseline' + | 'start' + | 'end' + | 'self-start' + | 'self-end'; + +export type JustifyContent = + | 'flex-start' + | 'flex-end' + | 'center' + | 'space-between' + | 'space-around' + | 'space-evenly' + | 'start' + | 'end' + | 'left' + | 'right'; + +export type Direction = 'row' | 'row-reverse' | 'column' | 'column-reverse'; +export type Wrap = 'nowrap' | 'wrap' | 'wrap-reverse'; + +type FlexGrow = number; +type FlexShrink = number; +type FlexBasis = 'auto' | 'initial' | '0' | `${number}%` | `${number}px`; + +// Support the following formats for the "flex" shorthand property: +// - 1 +// - '1' +// - '1 1' +// - '1 1 0' +// - '1 1 0px' +// - '1 1 auto' +type Flex = FlexGrow | `${FlexGrow}` | `${FlexGrow} ${FlexShrink}` | `${FlexGrow} ${FlexShrink} ${FlexBasis}`; + +export type FlexProps = { + /** Sets the property `flex-grow` */ + grow?: ResponsiveProp; + /** Sets the property `flex-shrink` */ + shrink?: ResponsiveProp; + /** Sets the property `flex-basis` */ + basis?: ResponsiveProp; + /** Sets the property `flex` */ + flex?: ResponsiveProp; +}; diff --git a/packages/grafana-ui/src/components/Menu/Menu.story.tsx b/packages/grafana-ui/src/components/Menu/Menu.story.tsx index e3e0c597f5c6b..4a547fb84aebb 100644 --- a/packages/grafana-ui/src/components/Menu/Menu.story.tsx +++ b/packages/grafana-ui/src/components/Menu/Menu.story.tsx @@ -49,6 +49,42 @@ export function Examples() { + + + + , + , + , + , + , + ]} + />, + ]} + shortcut="p s" + /> + , + , + , + ]} + /> + + + diff --git a/packages/grafana-ui/src/components/Menu/MenuItem.tsx b/packages/grafana-ui/src/components/Menu/MenuItem.tsx index 74ef322bd43d4..49f3d751f0af9 100644 --- a/packages/grafana-ui/src/components/Menu/MenuItem.tsx +++ b/packages/grafana-ui/src/components/Menu/MenuItem.tsx @@ -7,6 +7,7 @@ import { useStyles2 } from '../../themes'; import { getFocusStyles } from '../../themes/mixins'; import { IconName } from '../../types/icon'; import { Icon } from '../Icon/Icon'; +import { Stack } from '../Layout/Stack/Stack'; import { SubMenu } from './SubMenu'; @@ -17,6 +18,8 @@ export type MenuItemElement = HTMLAnchorElement & HTMLButtonElement & HTMLDivEle export interface MenuItemProps { /** Label of the menu item */ label: string; + /** Description of item */ + description?: string; /** Aria label for accessibility support */ ariaLabel?: string; /** Aria checked for accessibility support */ @@ -57,6 +60,7 @@ export const MenuItem = React.memo( url, icon, label, + description, ariaLabel, ariaChecked, target, @@ -104,6 +108,7 @@ export const MenuItem = React.memo( }, className ); + const disabledProps = { [ItemElement === 'button' ? 'disabled' : 'aria-disabled']: disabled, ...(ItemElement === 'a' && disabled && { href: undefined, onClick: undefined }), @@ -159,10 +164,9 @@ export const MenuItem = React.memo( tabIndex={tabIndex} {...disabledProps} > - <> + {icon && } - {label} - + {label}
    {hasShortcut && (
    @@ -181,7 +185,16 @@ export const MenuItem = React.memo( /> )}
    - + + {description && ( +
    + {description} +
    + )} ); }) @@ -197,7 +210,8 @@ const getStyles = (theme: GrafanaTheme2) => { whiteSpace: 'nowrap', color: theme.colors.text.primary, display: 'flex', - alignItems: 'center', + flexDirection: 'column', + alignItems: 'stretch', padding: theme.spacing(0.5, 2), minHeight: theme.spacing(4), margin: 0, @@ -234,7 +248,7 @@ const getStyles = (theme: GrafanaTheme2) => { }), disabled: css({ color: theme.colors.action.disabledText, - + label: 'menu-item-disabled', '&:hover, &:focus, &:focus-visible': { cursor: 'not-allowed', background: 'none', @@ -243,8 +257,6 @@ const getStyles = (theme: GrafanaTheme2) => { }), icon: css({ opacity: 0.7, - marginRight: '10px', - marginLeft: '-4px', color: theme.colors.text.secondary, }), rightWrapper: css({ @@ -252,9 +264,6 @@ const getStyles = (theme: GrafanaTheme2) => { alignItems: 'center', marginLeft: 'auto', }), - shortcutIcon: css({ - marginRight: theme.spacing(1), - }), withShortcut: css({ minWidth: theme.spacing(10.5), }), @@ -266,5 +275,18 @@ const getStyles = (theme: GrafanaTheme2) => { color: theme.colors.text.secondary, opacity: 0.7, }), + description: css({ + ...theme.typography.bodySmall, + color: theme.colors.text.secondary, + textAlign: 'start', + }), + descriptionWithIcon: css({ + marginLeft: theme.spacing(3), + }), + ellipsis: css({ + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }), }; }; diff --git a/packages/grafana-ui/src/components/Menu/SubMenu.tsx b/packages/grafana-ui/src/components/Menu/SubMenu.tsx index 03b9229b1bff9..4159f62a0718c 100644 --- a/packages/grafana-ui/src/components/Menu/SubMenu.tsx +++ b/packages/grafana-ui/src/components/Menu/SubMenu.tsx @@ -49,8 +49,8 @@ export const SubMenu = React.memo( return ( <> -
    - +
    +
    {isOpen && (
    ) { onClickBackdrop, trapFocus = true, } = props; - const theme = useTheme2(); - const styles = getModalStyles(theme); + const styles = useStyles2(getModalStyles); const ref = useRef(null); @@ -101,8 +100,7 @@ export function Modal(props: PropsWithChildren) { } function ModalButtonRow({ leftItems, children }: { leftItems?: React.ReactNode; children: React.ReactNode }) { - const theme = useTheme2(); - const styles = getModalStyles(theme); + const styles = useStyles2(getModalStyles); if (leftItems) { return ( diff --git a/packages/grafana-ui/src/components/Modal/getModalStyles.ts b/packages/grafana-ui/src/components/Modal/getModalStyles.ts index c9b115736da61..ede316fbd3211 100644 --- a/packages/grafana-ui/src/components/Modal/getModalStyles.ts +++ b/packages/grafana-ui/src/components/Modal/getModalStyles.ts @@ -2,9 +2,7 @@ import { css } from '@emotion/css'; import { GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory } from '../../themes'; - -export const getModalStyles = stylesFactory((theme: GrafanaTheme2) => { +export const getModalStyles = (theme: GrafanaTheme2) => { const borderRadius = theme.shape.radius.default; return { @@ -80,4 +78,4 @@ export const getModalStyles = stylesFactory((theme: GrafanaTheme2) => { paddingTop: theme.spacing(3), }), }; -}); +}; diff --git a/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx b/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx index d995299ddc328..a7ac0d7fb0d9a 100644 --- a/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx +++ b/packages/grafana-ui/src/components/Monaco/CodeEditor.tsx @@ -27,6 +27,8 @@ class UnthemedCodeEditor extends PureComponent { if (this.completionCancel) { this.completionCancel.dispose(); } + + this.props.onEditorWillUnmount?.(); } componentDidUpdate(oldProps: Props) { @@ -77,6 +79,13 @@ class UnthemedCodeEditor extends PureComponent { } }; + onFocus = () => { + const { onFocus } = this.props; + if (onFocus) { + onFocus(this.getEditorValue()); + } + }; + onSave = () => { const { onSave } = this.props; if (onSave) { @@ -164,7 +173,12 @@ class UnthemedCodeEditor extends PureComponent { } return ( -
    +
    void; + /** Callback before the edior has unmounted */ + onEditorWillUnmount?: () => void; + /** Handler to be performed when editor is blurred */ onBlur?: CodeEditorChangeHandler; + /** Handler to be performed when editor is focused */ + onFocus?: CodeEditorChangeHandler; + /** Handler to be performed whenever the text inside the editor changes */ onChange?: CodeEditorChangeHandler; diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx index b0ef4858be14c..16ed96da300c0 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.story.tsx @@ -51,7 +51,7 @@ function renderPanel(name: string, overrides?: Partial) { return ( - {(innerWidth, innerHeight) => { + {(innerWidth: number, innerHeight: number) => { return
    {name}
    ; }}
    @@ -75,7 +75,7 @@ function renderCollapsiblePanel(name: string, overrides?: Partial - {(innerWidth, innerHeight) => { + {(innerWidth: number, innerHeight: number) => { return
    {name}
    ; }} diff --git a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx index 474ace6c3efb0..4b2bd1c1c1722 100644 --- a/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx +++ b/packages/grafana-ui/src/components/PanelChrome/PanelChrome.tsx @@ -465,7 +465,7 @@ const getStyles = (theme: GrafanaTheme2) => { position: 'absolute', left: 0, top: 0, - zIndex: theme.zIndex.tooltip, + zIndex: 1, }), rightActions: css({ display: 'flex', diff --git a/packages/grafana-ui/src/components/Segment/Segment.story.tsx b/packages/grafana-ui/src/components/Segment/Segment.story.tsx index c17f6729d3d57..771fc011ba7af 100644 --- a/packages/grafana-ui/src/components/Segment/Segment.story.tsx +++ b/packages/grafana-ui/src/components/Segment/Segment.story.tsx @@ -33,7 +33,7 @@ const SegmentFrame = ({ children: React.ReactNode; }) => ( <> - + {children} action('New value added')(value)} options={options} /> diff --git a/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx b/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx index 918a5af232f79..edf49d2564729 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentAsync.story.tsx @@ -29,12 +29,13 @@ const SegmentFrame = ({ loadOptions: (options: Array>) => Promise>>; }>) => ( <> - + {children} action('New value added')(value)} loadOptions={() => loadOptions(options)} + inputMinWidth={100} /> diff --git a/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx index 0f596e5f33444..85e9122ef4f94 100644 --- a/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx +++ b/packages/grafana-ui/src/components/Segment/SegmentInput.story.tsx @@ -8,7 +8,7 @@ import { SegmentInputProps } from './SegmentInput'; const SegmentFrame = ({ children }: React.PropsWithChildren) => ( <> - {children} + {children} ); diff --git a/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx b/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx index e54058ff53f8a..5e56ce531d65b 100644 --- a/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx +++ b/packages/grafana-ui/src/components/Select/DropdownIndicator.tsx @@ -1,13 +1,11 @@ import React from 'react'; +import { DropdownIndicatorProps } from 'react-select'; import { Icon } from '../Icon/Icon'; -interface DropdownIndicatorProps { - isOpen: boolean; -} - -export const DropdownIndicator = ({ isOpen }: DropdownIndicatorProps) => { +export function DropdownIndicator({ selectProps }: DropdownIndicatorProps) { + const isOpen = selectProps.menuIsOpen; const icon = isOpen ? 'search' : 'angle-down'; const size = isOpen ? 'sm' : 'md'; return ; -}; +} diff --git a/packages/grafana-ui/src/components/Select/InputControl.tsx b/packages/grafana-ui/src/components/Select/InputControl.tsx index 14b979ed8d84f..c4a3e4b90f281 100644 --- a/packages/grafana-ui/src/components/Select/InputControl.tsx +++ b/packages/grafana-ui/src/components/Select/InputControl.tsx @@ -3,8 +3,7 @@ import React from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory } from '../../themes'; -import { useTheme2 } from '../../themes/ThemeContext'; +import { useStyles2 } from '../../themes/ThemeContext'; import { inputPadding } from '../Forms/commonStyles'; import { getInputStyles } from '../Input/Input'; @@ -17,7 +16,20 @@ interface InputControlProps { innerProps: JSX.IntrinsicElements['div']; } -const getInputControlStyles = stylesFactory((theme: GrafanaTheme2, invalid: boolean, withPrefix: boolean) => { +export const InputControl = React.forwardRef>( + function InputControl({ focused, invalid, disabled, children, innerProps, prefix, ...otherProps }, ref) { + const styles = useStyles2(getInputControlStyles, invalid, !!prefix); + + return ( +
    + {prefix &&
    {prefix}
    } + {children} +
    + ); + } +); + +const getInputControlStyles = (theme: GrafanaTheme2, invalid: boolean, withPrefix: boolean) => { const styles = getInputStyles({ theme, invalid }); return { @@ -47,17 +59,4 @@ const getInputControlStyles = stylesFactory((theme: GrafanaTheme2, invalid: bool }) ), }; -}); - -export const InputControl = React.forwardRef>( - function InputControl({ focused, invalid, disabled, children, innerProps, prefix, ...otherProps }, ref) { - const theme = useTheme2(); - const styles = getInputControlStyles(theme, invalid, !!prefix); - return ( -
    - {prefix &&
    {prefix}
    } - {children} -
    - ); - } -); +}; diff --git a/packages/grafana-ui/src/components/Select/Select.story.tsx b/packages/grafana-ui/src/components/Select/Select.story.tsx index 2c8751b54ee22..7bb9537e7d64f 100644 --- a/packages/grafana-ui/src/components/Select/Select.story.tsx +++ b/packages/grafana-ui/src/components/Select/Select.story.tsx @@ -45,7 +45,6 @@ const meta: Meta = { 'renderControl', 'options', 'isOptionDisabled', - 'maxVisibleValues', 'aria-label', 'noOptionsMessage', 'menuPosition', @@ -225,7 +224,7 @@ export const MultiSelectBasic: Story = (args) => { const [value, setValue] = useState>>([]); return ( - <> +
    { prefix={getPrefix(args.icon)} {...args} /> - +
    ); }; + MultiSelectBasic.args = { isClearable: false, closeMenuOnSelect: false, maxVisibleValues: 5, + noMultiValueWrap: false, }; export const MultiSelectAsync: Story = (args) => { diff --git a/packages/grafana-ui/src/components/Select/SelectBase.tsx b/packages/grafana-ui/src/components/Select/SelectBase.tsx index c47d9cf3c5ce9..661c97995e891 100644 --- a/packages/grafana-ui/src/components/Select/SelectBase.tsx +++ b/packages/grafana-ui/src/components/Select/SelectBase.tsx @@ -1,6 +1,6 @@ import { t } from 'i18next'; import React, { ComponentProps, useCallback, useEffect, useRef, useState } from 'react'; -import { default as ReactSelect } from 'react-select'; +import { default as ReactSelect, IndicatorsContainerProps, Props as ReactSelectProps } from 'react-select'; import { default as ReactAsyncSelect } from 'react-select/async'; import { default as AsyncCreatable } from 'react-select/async-creatable'; import Creatable from 'react-select/creatable'; @@ -25,31 +25,6 @@ import { useCustomSelectStyles } from './resetSelectStyles'; import { ActionMeta, InputActionMeta, SelectBaseProps } from './types'; import { cleanValue, findSelectedValue, omitDescriptions } from './utils'; -interface ExtraValuesIndicatorProps { - maxVisibleValues?: number | undefined; - selectedValuesCount: number; - menuIsOpen: boolean; - showAllSelectedWhenOpen: boolean; -} - -const renderExtraValuesIndicator = (props: ExtraValuesIndicatorProps) => { - const { maxVisibleValues, selectedValuesCount, menuIsOpen, showAllSelectedWhenOpen } = props; - - if ( - maxVisibleValues !== undefined && - selectedValuesCount > maxVisibleValues && - !(showAllSelectedWhenOpen && menuIsOpen) - ) { - return ( - - (+{selectedValuesCount - maxVisibleValues}) - - ); - } - - return null; -}; - const CustomControl = (props: any) => { const { children, @@ -88,6 +63,12 @@ const CustomControl = (props: any) => { ); }; +interface SelectPropsWithExtras extends ReactSelectProps { + maxVisibleValues?: number | undefined; + showAllSelectedWhenOpen: boolean; + noMultiValueWrap?: boolean; +} + export function SelectBase({ allowCustomValue = false, allowCreateWhileLoading = false, @@ -145,6 +126,7 @@ export function SelectBase({ tabSelectsValue = true, value, virtualized = false, + noMultiValueWrap, width, isValidNewOption, formatOptionLabel, @@ -274,6 +256,7 @@ export function SelectBase({ showAllSelectedWhenOpen, tabSelectsValue, value: isMulti ? selectedValue : selectedValue?.[0], + noMultiValueWrap, }; if (allowCustomValue) { @@ -305,31 +288,8 @@ export function SelectBase({ MenuList: SelectMenuComponent, Group: SelectOptionGroup, ValueContainer, - IndicatorsContainer(props: any) { - const { selectProps } = props; - const { value, showAllSelectedWhenOpen, maxVisibleValues, menuIsOpen } = selectProps; - - if (maxVisibleValues !== undefined) { - const selectedValuesCount = value.length; - const indicatorChildren = [...props.children]; - indicatorChildren.splice( - -1, - 0, - renderExtraValuesIndicator({ - maxVisibleValues, - selectedValuesCount, - showAllSelectedWhenOpen, - menuIsOpen, - }) - ); - return {indicatorChildren}; - } - - return ; - }, - IndicatorSeparator() { - return <>; - }, + IndicatorsContainer: CustomIndicatorsContainer, + IndicatorSeparator: IndicatorSeparator, Control: CustomControl, Option: SelectMenuOptions, ClearIndicator(props: any) { @@ -361,9 +321,7 @@ export function SelectBase({
    ); }, - DropdownIndicator(props) { - return ; - }, + DropdownIndicator: DropdownIndicator, SingleValue(props: any) { return ; }, @@ -394,3 +352,37 @@ function defaultFormatCreateLabel(input: string) {
    ); } + +type CustomIndicatorsContainerProps = IndicatorsContainerProps & { + selectProps: SelectPropsWithExtras; + children: React.ReactNode; +}; + +function CustomIndicatorsContainer(props: CustomIndicatorsContainerProps) { + const { showAllSelectedWhenOpen, maxVisibleValues, menuIsOpen } = props.selectProps; + + const value = props.getValue(); + + if (maxVisibleValues !== undefined && Array.isArray(props.children)) { + const selectedValuesCount = value.length; + + if (selectedValuesCount > maxVisibleValues && !(showAllSelectedWhenOpen && menuIsOpen)) { + const indicatorChildren = [...props.children]; + indicatorChildren.splice( + -1, + 0, + + (+{selectedValuesCount - maxVisibleValues}) + + ); + + return {indicatorChildren}; + } + } + + return ; +} + +function IndicatorSeparator() { + return <>; +} diff --git a/packages/grafana-ui/src/components/Select/SelectContainer.tsx b/packages/grafana-ui/src/components/Select/SelectContainer.tsx index 95a3d0c3d8b1f..8e6f4ff895d11 100644 --- a/packages/grafana-ui/src/components/Select/SelectContainer.tsx +++ b/packages/grafana-ui/src/components/Select/SelectContainer.tsx @@ -4,8 +4,7 @@ import { components, ContainerProps as BaseContainerProps, GroupBase } from 'rea import { GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory } from '../../themes'; -import { useTheme2 } from '../../themes/ThemeContext'; +import { useStyles2 } from '../../themes/ThemeContext'; import { getFocusStyles } from '../../themes/mixins'; import { sharedInputStyle } from '../Forms/commonStyles'; import { getInputStyles } from '../Input/Input'; @@ -26,8 +25,7 @@ export const SelectContainer = @@ -36,33 +34,31 @@ export const SelectContainer = { - const styles = getInputStyles({ theme, invalid }); +const getSelectContainerStyles = (theme: GrafanaTheme2, focused: boolean, disabled: boolean, invalid: boolean) => { + const styles = getInputStyles({ theme, invalid }); - return { - wrapper: cx( - styles.wrapper, - sharedInputStyle(theme, invalid), - focused && css(getFocusStyles(theme)), - disabled && styles.inputDisabled, - css({ - position: 'relative', - boxSizing: 'border-box', - /* The display property is set by the styles prop in SelectBase because it's dependant on the width prop */ - flexDirection: 'row', - flexWrap: 'wrap', - alignItems: 'stretch', - justifyContent: 'space-between', - minHeight: '32px', - height: 'auto', - maxWidth: '100%', + return { + wrapper: cx( + styles.wrapper, + sharedInputStyle(theme, invalid), + focused && css(getFocusStyles(theme)), + disabled && styles.inputDisabled, + css({ + position: 'relative', + boxSizing: 'border-box', + /* The display property is set by the styles prop in SelectBase because it's dependant on the width prop */ + flexDirection: 'row', + flexWrap: 'wrap', + alignItems: 'stretch', + justifyContent: 'space-between', + minHeight: '32px', + height: 'auto', + maxWidth: '100%', - /* Input padding is applied to the InputControl so the menu is aligned correctly */ - padding: 0, - cursor: disabled ? 'not-allowed' : 'pointer', - }) - ), - }; - } -); + /* Input padding is applied to the InputControl so the menu is aligned correctly */ + padding: 0, + cursor: disabled ? 'not-allowed' : 'pointer', + }) + ), + }; +}; diff --git a/packages/grafana-ui/src/components/Select/ValueContainer.tsx b/packages/grafana-ui/src/components/Select/ValueContainer.tsx index b7c6f957fcb4e..9025a4a1d0d05 100644 --- a/packages/grafana-ui/src/components/Select/ValueContainer.tsx +++ b/packages/grafana-ui/src/components/Select/ValueContainer.tsx @@ -30,8 +30,15 @@ class UnthemedValueContainer extends Component { renderContainer(children?: ReactNode) { const { isMulti, theme } = this.props; + const noWrap = this.props.selectProps?.noMultiValueWrap && !this.props.selectProps?.menuIsOpen; const styles = getSelectStyles(theme); - const className = cx(styles.valueContainer, isMulti && styles.valueContainerMulti); + + const className = cx( + styles.valueContainer, + isMulti && styles.valueContainerMulti, + noWrap && styles.valueContainerMultiNoWrap + ); + return
    {children}
    ; } } diff --git a/packages/grafana-ui/src/components/Select/getSelectStyles.ts b/packages/grafana-ui/src/components/Select/getSelectStyles.ts index d0a017089f9bf..84ce715aab2bc 100644 --- a/packages/grafana-ui/src/components/Select/getSelectStyles.ts +++ b/packages/grafana-ui/src/components/Select/getSelectStyles.ts @@ -27,6 +27,9 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => { '&:hover': { background: theme.colors.action.hover, + '@media (forced-colors: active), (prefers-contrast: more)': { + border: `1px solid ${theme.colors.primary.border}`, + }, }, }), optionIcon: css({ @@ -55,6 +58,9 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => { optionFocused: css({ label: 'grafana-select-option-focused', background: theme.colors.action.focus, + '@media (forced-colors: active), (prefers-contrast: more)': { + border: `1px solid ${theme.colors.primary.border}`, + }, }), optionSelected: css({ background: theme.colors.action.selected, @@ -90,6 +96,9 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => { flexWrap: 'wrap', display: 'flex', }), + valueContainerMultiNoWrap: css({ + flexWrap: 'nowrap', + }), loadingMessage: css({ label: 'grafana-select-loading-message', padding: theme.spacing(1), @@ -107,6 +116,8 @@ export const getSelectStyles = stylesFactory((theme: GrafanaTheme2) => { padding: theme.spacing(0.25, 0, 0.25, 1), color: theme.colors.text.primary, fontSize: theme.typography.size.sm, + overflow: 'hidden', + whiteSpace: 'nowrap', '&:hover': { background: theme.colors.emphasize(theme.colors.background.secondary), diff --git a/packages/grafana-ui/src/components/Select/mockOptions.tsx b/packages/grafana-ui/src/components/Select/mockOptions.tsx index 12d56b0bdc0a5..7af01826de632 100644 --- a/packages/grafana-ui/src/components/Select/mockOptions.tsx +++ b/packages/grafana-ui/src/components/Select/mockOptions.tsx @@ -24,6 +24,7 @@ export const generateOptions = (desc = false) => { 'Ok Vicente', 'Garry Spitz', 'Han Harnish', + 'A very long value that is very long and takes up a lot of space and should be truncated preferrably if it does not fit', ]; return values.map>((name) => ({ diff --git a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts index fb844575d668c..3f1e31abff714 100644 --- a/packages/grafana-ui/src/components/Select/resetSelectStyles.ts +++ b/packages/grafana-ui/src/components/Select/resetSelectStyles.ts @@ -30,7 +30,10 @@ export default function resetSelectStyles(theme: GrafanaTheme2) { maxHeight, }), multiValue: () => ({}), - multiValueLabel: () => ({}), + multiValueLabel: () => ({ + overflow: 'hidden', + textOverflow: 'ellipsis', + }), multiValueRemove: () => ({}), noOptionsMessage: () => ({}), option: () => ({}), diff --git a/packages/grafana-ui/src/components/Select/types.ts b/packages/grafana-ui/src/components/Select/types.ts index e3fe5c6b76632..0cbe644ed7040 100644 --- a/packages/grafana-ui/src/components/Select/types.ts +++ b/packages/grafana-ui/src/components/Select/types.ts @@ -99,6 +99,8 @@ export interface SelectCommonProps { ) => boolean; /** Message to display isLoading=true*/ loadingMessage?: string; + /** Disables wrapping of multi value values when closed */ + noMultiValueWrap?: boolean; } export interface SelectAsyncProps { diff --git a/packages/grafana-ui/src/components/Slider/RangeSlider.tsx b/packages/grafana-ui/src/components/Slider/RangeSlider.tsx index dcd0df00e169f..83e97e58f9c5f 100644 --- a/packages/grafana-ui/src/components/Slider/RangeSlider.tsx +++ b/packages/grafana-ui/src/components/Slider/RangeSlider.tsx @@ -3,7 +3,7 @@ import { Global } from '@emotion/react'; import Slider, { SliderProps } from 'rc-slider'; import React, { useCallback } from 'react'; -import { useTheme2 } from '../../themes/ThemeContext'; +import { useStyles2 } from '../../themes/ThemeContext'; import HandleTooltip from './HandleTooltip'; import { getStyles } from './styles'; @@ -43,8 +43,7 @@ export const RangeSlider = ({ ); const isHorizontal = orientation === 'horizontal'; - const theme = useTheme2(); - const styles = getStyles(theme, isHorizontal); + const styles = useStyles2(getStyles, isHorizontal); const tipHandleRender: SliderProps['handleRender'] = (node, handleProps) => { return ( diff --git a/packages/grafana-ui/src/components/Slider/Slider.tsx b/packages/grafana-ui/src/components/Slider/Slider.tsx index ca442bd440a61..7f7dc200ceba3 100644 --- a/packages/grafana-ui/src/components/Slider/Slider.tsx +++ b/packages/grafana-ui/src/components/Slider/Slider.tsx @@ -3,7 +3,7 @@ import { Global } from '@emotion/react'; import SliderComponent from 'rc-slider'; import React, { useState, useCallback, ChangeEvent, FocusEvent } from 'react'; -import { useTheme2 } from '../../themes/ThemeContext'; +import { useStyles2 } from '../../themes/ThemeContext'; import { Input } from '../Input/Input'; import { getStyles } from './styles'; @@ -26,8 +26,7 @@ export const Slider = ({ included, }: SliderProps) => { const isHorizontal = orientation === 'horizontal'; - const theme = useTheme2(); - const styles = getStyles(theme, isHorizontal, Boolean(marks)); + const styles = useStyles2(getStyles, isHorizontal, Boolean(marks)); const SliderWithTooltip = SliderComponent; const [sliderValue, setSliderValue] = useState(value ?? min); diff --git a/packages/grafana-ui/src/components/Slider/styles.ts b/packages/grafana-ui/src/components/Slider/styles.ts index e5d7873698613..0b422da66baac 100644 --- a/packages/grafana-ui/src/components/Slider/styles.ts +++ b/packages/grafana-ui/src/components/Slider/styles.ts @@ -3,9 +3,7 @@ import { css as cssCore } from '@emotion/react'; import { GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory } from '../../themes'; - -export const getStyles = stylesFactory((theme: GrafanaTheme2, isHorizontal: boolean, hasMarks = false) => { +export const getStyles = (theme: GrafanaTheme2, isHorizontal: boolean, hasMarks = false) => { const { spacing } = theme; const railColor = theme.colors.border.strong; const trackColor = theme.colors.primary.main; @@ -127,4 +125,4 @@ export const getStyles = stylesFactory((theme: GrafanaTheme2, isHorizontal: bool order: 1, }), }; -}); +}; diff --git a/packages/grafana-ui/src/components/Sparkline/utils.ts b/packages/grafana-ui/src/components/Sparkline/utils.ts index c643d375a370d..aa77fd64dc48e 100644 --- a/packages/grafana-ui/src/components/Sparkline/utils.ts +++ b/packages/grafana-ui/src/components/Sparkline/utils.ts @@ -5,11 +5,10 @@ import { FieldType, isLikelyAscendingVector, sortDataFrame, + applyNullInsertThreshold, } from '@grafana/data'; import { GraphFieldConfig } from '@grafana/schema'; -import { applyNullInsertThreshold } from '../GraphNG/nullInsertThreshold'; - /** @internal * Given a sparkline config returns a DataFrame ready to be turned into Plot data set **/ diff --git a/packages/grafana-ui/src/components/Switch/Switch.tsx b/packages/grafana-ui/src/components/Switch/Switch.tsx index aa9cbd6026281..95c401201c24c 100644 --- a/packages/grafana-ui/src/components/Switch/Switch.tsx +++ b/packages/grafana-ui/src/components/Switch/Switch.tsx @@ -4,7 +4,7 @@ import React, { HTMLProps, useRef } from 'react'; import { GrafanaTheme2, deprecationWarning } from '@grafana/data'; -import { stylesFactory, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; import { getFocusStyles, getMouseFocusStyles } from '../../themes/mixins'; export interface Props extends Omit, 'value'> { @@ -21,8 +21,7 @@ export const Switch = React.forwardRef( deprecationWarning('Switch', 'checked prop', 'value'); } - const theme = useTheme2(); - const styles = getSwitchStyles(theme); + const styles = useStyles2(getSwitchStyles); const switchIdRef = useRef(id ? id : uniqueId('switch-')); return ( @@ -52,8 +51,7 @@ export interface InlineSwitchProps extends Props { export const InlineSwitch = React.forwardRef( ({ transparent, className, showLabel, label, value, id, invalid, ...props }, ref) => { - const theme = useTheme2(); - const styles = getSwitchStyles(theme, transparent); + const styles = useStyles2(getSwitchStyles, transparent); return (
    { - return { - switch: css({ - width: '32px', - height: '16px', - position: 'relative', - - input: { - opacity: 0, - left: '-100vw', - zIndex: -1000, - position: 'absolute', - - '&:disabled + label': { - background: theme.colors.action.disabledBackground, - cursor: 'not-allowed', - }, - - '&:checked + label': { - background: theme.colors.primary.main, - borderColor: theme.colors.primary.main, - - '&:hover': { - background: theme.colors.primary.shade, - }, - - '&::after': { - transform: 'translate3d(18px, -50%, 0)', - background: theme.colors.primary.contrastText, - }, - }, - - '&:focus + label, &:focus-visible + label': getFocusStyles(theme), - - '&:focus:not(:focus-visible) + label': getMouseFocusStyles(theme), +const getSwitchStyles = (theme: GrafanaTheme2, transparent?: boolean) => ({ + switch: css({ + width: '32px', + height: '16px', + position: 'relative', + + input: { + opacity: 0, + left: '-100vw', + zIndex: -1000, + position: 'absolute', + + '&:disabled + label': { + background: theme.colors.action.disabledBackground, + cursor: 'not-allowed', }, - label: { - width: '100%', - height: '100%', - cursor: 'pointer', - borderRadius: theme.shape.radius.pill, - background: theme.components.input.background, - border: `1px solid ${theme.components.input.borderColor}`, - transition: 'all 0.3s ease', + '&:checked + label': { + background: theme.colors.primary.main, + borderColor: theme.colors.primary.main, '&:hover': { - borderColor: theme.components.input.borderHover, + background: theme.colors.primary.shade, }, '&::after': { - position: 'absolute', - display: 'block', - content: '""', - width: '12px', - height: '12px', - borderRadius: theme.shape.radius.circle, - background: theme.colors.text.secondary, - boxShadow: theme.shadows.z1, - top: '50%', - transform: 'translate3d(2px, -50%, 0)', - transition: 'transform 0.2s cubic-bezier(0.19, 1, 0.22, 1)', - - '@media (forced-colors: active)': { - border: '1px solid transparent', - }, + transform: 'translate3d(18px, -50%, 0)', + background: theme.colors.primary.contrastText, }, }, - }), - inlineContainer: css({ - padding: theme.spacing(0, 1), - height: theme.spacing(theme.components.height.md), - display: 'inline-flex', - alignItems: 'center', - background: transparent ? 'transparent' : theme.components.input.background, - border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderColor}`, - borderRadius: theme.shape.radius.default, + + '&:focus + label, &:focus-visible + label': getFocusStyles(theme), + + '&:focus:not(:focus-visible) + label': getMouseFocusStyles(theme), + }, + + label: { + width: '100%', + height: '100%', + cursor: 'pointer', + borderRadius: theme.shape.radius.pill, + background: theme.components.input.background, + border: `1px solid ${theme.components.input.borderColor}`, + transition: 'all 0.3s ease', '&:hover': { - border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderHover}`, + borderColor: theme.components.input.borderHover, + }, - '.inline-switch-label': { - color: theme.colors.text.primary, + '&::after': { + position: 'absolute', + display: 'block', + content: '""', + width: '12px', + height: '12px', + borderRadius: theme.shape.radius.circle, + background: theme.colors.text.secondary, + boxShadow: theme.shadows.z1, + top: '50%', + transform: 'translate3d(2px, -50%, 0)', + transition: 'transform 0.2s cubic-bezier(0.19, 1, 0.22, 1)', + + '@media (forced-colors: active)': { + border: '1px solid transparent', }, }, - }), - disabled: css({ - backgroundColor: 'rgba(204, 204, 220, 0.04)', - color: 'rgba(204, 204, 220, 0.6)', - border: '1px solid rgba(204, 204, 220, 0.04)', - }), - inlineLabel: css({ - cursor: 'pointer', - paddingRight: theme.spacing(1), - color: theme.colors.text.secondary, - whiteSpace: 'nowrap', - }), - inlineLabelEnabled: css({ - color: theme.colors.text.primary, - }), - invalid: css({ - 'input + label, input:checked + label, input:hover + label': { - border: `1px solid ${theme.colors.error.border}`, + }, + }), + inlineContainer: css({ + padding: theme.spacing(0, 1), + height: theme.spacing(theme.components.height.md), + display: 'inline-flex', + alignItems: 'center', + background: transparent ? 'transparent' : theme.components.input.background, + border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderColor}`, + borderRadius: theme.shape.radius.default, + + '&:hover': { + border: `1px solid ${transparent ? 'transparent' : theme.components.input.borderHover}`, + + '.inline-switch-label': { + color: theme.colors.text.primary, }, - }), - }; + }, + }), + disabled: css({ + backgroundColor: 'rgba(204, 204, 220, 0.04)', + color: 'rgba(204, 204, 220, 0.6)', + border: '1px solid rgba(204, 204, 220, 0.04)', + }), + inlineLabel: css({ + cursor: 'pointer', + paddingRight: theme.spacing(1), + color: theme.colors.text.secondary, + whiteSpace: 'nowrap', + }), + inlineLabelEnabled: css({ + color: theme.colors.text.primary, + }), + invalid: css({ + 'input + label, input:checked + label, input:hover + label': { + border: `1px solid ${theme.colors.error.border}`, + }, + }), }); diff --git a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx index 86973201467cb..1794b1a96da8a 100644 --- a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx +++ b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx @@ -5,7 +5,7 @@ import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; import { IconButton } from '../../components/IconButton/IconButton'; import { TabsBar, Tab, TabContent } from '../../components/Tabs'; -import { stylesFactory, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; import { IconName } from '../../types/icon'; import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; @@ -23,45 +23,14 @@ export interface TabbedContainerProps { onClose: () => void; } -const getStyles = stylesFactory((theme: GrafanaTheme2) => { - return { - container: css({ - height: '100%', - }), - tabContent: css({ - padding: theme.spacing(2), - backgroundColor: theme.colors.background.primary, - height: `calc(100% - ${theme.components.menuTabs.height}px)`, - }), - close: css({ - position: 'absolute', - right: '16px', - top: '5px', - cursor: 'pointer', - fontSize: theme.typography.size.lg, - }), - tabs: css({ - paddingTop: theme.spacing(1), - borderColor: theme.colors.border.weak, - ul: { - marginLeft: theme.spacing(2), - }, - }), - }; -}); - -export function TabbedContainer(props: TabbedContainerProps) { - const [activeTab, setActiveTab] = useState( - props.tabs.some((tab) => tab.value === props.defaultTab) ? props.defaultTab : props.tabs?.[0].value - ); +export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose }: TabbedContainerProps) { + const [activeTab, setActiveTab] = useState(tabs.some((tab) => tab.value === defaultTab) ? defaultTab : tabs[0].value); const onSelectTab = (item: SelectableValue) => { setActiveTab(item.value!); }; - const { tabs, onClose, closeIconTooltip } = props; - const theme = useTheme2(); - const styles = getStyles(theme); + const styles = useStyles2(getStyles); return (
    @@ -83,3 +52,28 @@ export function TabbedContainer(props: TabbedContainerProps) {
    ); } + +const getStyles = (theme: GrafanaTheme2) => ({ + container: css({ + height: '100%', + }), + tabContent: css({ + padding: theme.spacing(2), + backgroundColor: theme.colors.background.primary, + height: `calc(100% - ${theme.components.menuTabs.height}px)`, + }), + close: css({ + position: 'absolute', + right: '16px', + top: '5px', + cursor: 'pointer', + fontSize: theme.typography.size.lg, + }), + tabs: css({ + paddingTop: theme.spacing(1), + borderColor: theme.colors.border.weak, + ul: { + marginLeft: theme.spacing(2), + }, + }), +}); diff --git a/packages/grafana-ui/src/components/Table/FilterList.tsx b/packages/grafana-ui/src/components/Table/FilterList.tsx index 1900aae00add5..2ff6d26bb41d3 100644 --- a/packages/grafana-ui/src/components/Table/FilterList.tsx +++ b/packages/grafana-ui/src/components/Table/FilterList.tsx @@ -5,7 +5,7 @@ import { FixedSizeList as List } from 'react-window'; import { GrafanaTheme2, SelectableValue } from '@grafana/data'; import { Checkbox, FilterInput, Label, VerticalGroup } from '..'; -import { stylesFactory, useTheme2 } from '../../themes'; +import { useStyles2, useTheme2 } from '../../themes'; interface Props { values: SelectableValue[]; @@ -18,8 +18,6 @@ const ITEM_HEIGHT = 28; const MIN_HEIGHT = ITEM_HEIGHT * 5; export const FilterList = ({ options, values, caseSensitive, onChange }: Props) => { - const theme = useTheme2(); - const styles = getStyles(theme); const [searchFilter, setSearchFilter] = useState(''); const regex = useMemo(() => new RegExp(searchFilter, caseSensitive ? undefined : 'i'), [searchFilter, caseSensitive]); const items = useMemo( @@ -32,16 +30,12 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props) }), [options, regex] ); + + const styles = useStyles2(getStyles); + const theme = useTheme2(); const gutter = theme.spacing.gridSize; const height = useMemo(() => Math.min(items.length * ITEM_HEIGHT, MIN_HEIGHT) + gutter, [gutter, items.length]); - const onInputChange = useCallback( - (v: string) => { - setSearchFilter(v); - }, - [setSearchFilter] - ); - const onCheckedChanged = useCallback( (option: SelectableValue) => (event: React.FormEvent) => { const newValues = event.currentTarget.checked @@ -55,7 +49,7 @@ export const FilterList = ({ options, values, caseSensitive, onChange }: Props) return ( - + {!items.length && } {items.length && ( ({ +const getStyles = (theme: GrafanaTheme2) => ({ filterList: css({ label: 'filterList', }), @@ -98,4 +92,4 @@ const getStyles = stylesFactory((theme: GrafanaTheme2) => ({ backgroundColor: theme.colors.action.hover, }, }), -})); +}); diff --git a/packages/grafana-ui/src/components/Table/RowsList.tsx b/packages/grafana-ui/src/components/Table/RowsList.tsx new file mode 100644 index 0000000000000..ebb2773421e16 --- /dev/null +++ b/packages/grafana-ui/src/components/Table/RowsList.tsx @@ -0,0 +1,301 @@ +import { css, cx } from '@emotion/css'; +import React, { CSSProperties, UIEventHandler, useCallback, useEffect, useMemo, useState } from 'react'; +import { Cell, Row, TableState } from 'react-table'; +import { VariableSizeList } from 'react-window'; +import { Subscription, debounceTime } from 'rxjs'; + +import { + DataFrame, + DataHoverClearEvent, + DataHoverEvent, + Field, + FieldType, + TimeRange, + hasTimeField, +} from '@grafana/data'; +import { TableCellHeight } from '@grafana/schema'; + +import { useTheme2 } from '../../themes'; +import CustomScrollbar from '../CustomScrollbar/CustomScrollbar'; +import { usePanelContext } from '../PanelChrome'; + +import { ExpandedRow, getExpandedRowHeight } from './ExpandedRow'; +import { TableCell } from './TableCell'; +import { TableStyles } from './styles'; +import { TableFilterActionCallback } from './types'; +import { calculateAroundPointThreshold, isPointTimeValAroundTableTimeVal } from './utils'; + +interface RowsListProps { + data: DataFrame; + rows: Row[]; + enableSharedCrosshair: boolean; + headerHeight: number; + rowHeight: number; + itemCount: number; + pageIndex: number; + listHeight: number; + width: number; + cellHeight?: TableCellHeight; + listRef: React.RefObject; + tableState: TableState; + tableStyles: TableStyles; + nestedDataField?: Field; + prepareRow: (row: Row) => void; + onCellFilterAdded?: TableFilterActionCallback; + timeRange?: TimeRange; + footerPaginationEnabled: boolean; +} + +export const RowsList = (props: RowsListProps) => { + const { + data, + rows, + headerHeight, + footerPaginationEnabled, + rowHeight, + itemCount, + pageIndex, + tableState, + prepareRow, + onCellFilterAdded, + width, + cellHeight = TableCellHeight.Sm, + timeRange, + tableStyles, + nestedDataField, + listHeight, + listRef, + enableSharedCrosshair = false, + } = props; + + const [rowHighlightIndex, setRowHighlightIndex] = useState(undefined); + + const theme = useTheme2(); + const panelContext = usePanelContext(); + + const threshold = useMemo(() => { + const timeField = data.fields.find((f) => f.type === FieldType.time); + + if (!timeField) { + return 0; + } + + return calculateAroundPointThreshold(timeField); + }, [data]); + + const onRowHover = useCallback( + (idx: number, frame: DataFrame) => { + if (!panelContext || !enableSharedCrosshair || !hasTimeField(frame)) { + return; + } + + const timeField: Field = frame!.fields.find((f) => f.type === FieldType.time)!; + + panelContext.eventBus.publish( + new DataHoverEvent({ + point: { + time: timeField.values[idx], + }, + }) + ); + }, + [enableSharedCrosshair, panelContext] + ); + + const onRowLeave = useCallback(() => { + if (!panelContext || !enableSharedCrosshair) { + return; + } + + panelContext.eventBus.publish(new DataHoverClearEvent()); + }, [enableSharedCrosshair, panelContext]); + + const onDataHoverEvent = useCallback( + (evt: DataHoverEvent) => { + if (evt.payload.point?.time && evt.payload.rowIndex !== undefined) { + const timeField = data.fields.find((f) => f.type === FieldType.time); + const time = timeField!.values[evt.payload.rowIndex]; + const pointTime = evt.payload.point.time; + + // If the time value of the hovered point is around the time value of the + // row with same index, highlight the row + if (isPointTimeValAroundTableTimeVal(pointTime, time, threshold)) { + setRowHighlightIndex(evt.payload.rowIndex); + return; + } + + // If the time value of the hovered point is not around the time value of the + // row with same index, try to find a row with same time value + const matchedRowIndex = timeField!.values.findIndex((t) => + isPointTimeValAroundTableTimeVal(pointTime, t, threshold) + ); + + if (matchedRowIndex !== -1) { + setRowHighlightIndex(matchedRowIndex); + return; + } + + setRowHighlightIndex(undefined); + } + }, + [data.fields, threshold] + ); + + useEffect(() => { + if (!panelContext || !enableSharedCrosshair || !hasTimeField(data) || footerPaginationEnabled) { + return; + } + + const subs = new Subscription(); + + subs.add( + panelContext.eventBus + .getStream(DataHoverEvent) + .pipe(debounceTime(250)) + .subscribe({ + next: (evt) => { + if (panelContext.eventBus === evt.origin) { + return; + } + + onDataHoverEvent(evt); + }, + }) + ); + + subs.add( + panelContext.eventBus + .getStream(DataHoverClearEvent) + .pipe(debounceTime(250)) + .subscribe({ + next: (evt) => { + if (panelContext.eventBus === evt.origin) { + return; + } + + setRowHighlightIndex(undefined); + }, + }) + ); + + return () => { + subs.unsubscribe(); + }; + }, [data, enableSharedCrosshair, footerPaginationEnabled, onDataHoverEvent, panelContext]); + + let scrollTop: number | undefined = undefined; + if (rowHighlightIndex !== undefined) { + const firstMatchedRowIndex = rows.findIndex((row) => row.index === rowHighlightIndex); + + if (firstMatchedRowIndex !== -1) { + scrollTop = headerHeight + (firstMatchedRowIndex - 1) * rowHeight; + } + } + + const rowIndexForPagination = useCallback( + (index: number) => { + return tableState.pageIndex * tableState.pageSize + index; + }, + [tableState.pageIndex, tableState.pageSize] + ); + + const RenderRow = useCallback( + ({ index, style, rowHighlightIndex }: { index: number; style: CSSProperties; rowHighlightIndex?: number }) => { + const indexForPagination = rowIndexForPagination(index); + const row = rows[indexForPagination]; + + prepareRow(row); + + const expandedRowStyle = tableState.expanded[row.index] ? css({ '&:hover': { background: 'inherit' } }) : {}; + + if (rowHighlightIndex !== undefined && row.index === rowHighlightIndex) { + style = { ...style, backgroundColor: theme.components.table.rowHoverBackground }; + } + + return ( +
    onRowHover(index, data)} + onMouseLeave={onRowLeave} + > + {/*add the nested data to the DOM first to prevent a 1px border CSS issue on the last cell of the row*/} + {nestedDataField && tableState.expanded[row.index] && ( + + )} + {row.cells.map((cell: Cell, index: number) => ( + + ))} +
    + ); + }, + [ + cellHeight, + data, + nestedDataField, + onCellFilterAdded, + onRowHover, + onRowLeave, + prepareRow, + rowIndexForPagination, + rows, + tableState.expanded, + tableStyles, + theme.components.table.rowHoverBackground, + timeRange, + width, + ] + ); + + const getItemSize = (index: number): number => { + const indexForPagination = rowIndexForPagination(index); + const row = rows[indexForPagination]; + if (tableState.expanded[row.index] && nestedDataField) { + return getExpandedRowHeight(nestedDataField, index, tableStyles); + } + + return tableStyles.rowHeight; + }; + + const handleScroll: UIEventHandler = (event) => { + const { scrollTop } = event.currentTarget; + + if (listRef.current !== null) { + listRef.current.scrollTo(scrollTop); + } + }; + + return ( + <> + + + {({ index, style }) => RenderRow({ index, style, rowHighlightIndex })} + + + + ); +}; diff --git a/packages/grafana-ui/src/components/Table/Table.tsx b/packages/grafana-ui/src/components/Table/Table.tsx index 398732e792204..ffa4cab48bc66 100644 --- a/packages/grafana-ui/src/components/Table/Table.tsx +++ b/packages/grafana-ui/src/components/Table/Table.tsx @@ -1,7 +1,5 @@ -import { css, cx } from '@emotion/css'; -import React, { CSSProperties, memo, useCallback, useEffect, useMemo, useRef, useState, UIEventHandler } from 'react'; +import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { - Cell, useAbsoluteLayout, useExpanded, useFilters, @@ -20,10 +18,9 @@ import { useTheme2 } from '../../themes'; import { CustomScrollbar } from '../CustomScrollbar/CustomScrollbar'; import { Pagination } from '../Pagination/Pagination'; -import { getExpandedRowHeight, ExpandedRow } from './ExpandedRow'; import { FooterRow } from './FooterRow'; import { HeaderRow } from './HeaderRow'; -import { TableCell } from './TableCell'; +import { RowsList } from './RowsList'; import { useFixScrollbarContainer, useResetVariableListSizeCache } from './hooks'; import { getInitialState, useTableStateReducer } from './reducer'; import { useTableStyles } from './styles'; @@ -50,6 +47,7 @@ export const Table = memo((props: Props) => { enablePagination, cellHeight = TableCellHeight.Sm, timeRange, + enableSharedCrosshair = false, } = props; const listRef = useRef(null); @@ -231,64 +229,6 @@ export const Table = memo((props: Props) => { useResetVariableListSizeCache(extendedState, listRef, data); useFixScrollbarContainer(variableSizeListScrollbarRef, tableDivRef); - const rowIndexForPagination = useCallback( - (index: number) => { - return state.pageIndex * state.pageSize + index; - }, - [state.pageIndex, state.pageSize] - ); - - const RenderRow = useCallback( - ({ index, style }: { index: number; style: CSSProperties }) => { - const indexForPagination = rowIndexForPagination(index); - const row = rows[indexForPagination]; - - prepareRow(row); - - const expandedRowStyle = state.expanded[row.index] ? css({ '&:hover': { background: 'inherit' } }) : {}; - - return ( -
    - {/*add the nested data to the DOM first to prevent a 1px border CSS issue on the last cell of the row*/} - {nestedDataField && state.expanded[row.index] && ( - - )} - {row.cells.map((cell: Cell, index: number) => ( - - ))} -
    - ); - }, - [ - rowIndexForPagination, - rows, - prepareRow, - state.expanded, - tableStyles, - nestedDataField, - width, - cellHeight, - onCellFilterAdded, - timeRange, - data, - ] - ); - const onNavigate = useCallback( (toPage: number) => { gotoPage(toPage - 1); @@ -322,24 +262,6 @@ export const Table = memo((props: Props) => { ); } - const getItemSize = (index: number): number => { - const indexForPagination = rowIndexForPagination(index); - const row = rows[indexForPagination]; - if (state.expanded[row.index] && nestedDataField) { - return getExpandedRowHeight(nestedDataField, index, tableStyles); - } - - return tableStyles.rowHeight; - }; - - const handleScroll: UIEventHandler = (event) => { - const { scrollTop } = event.currentTarget; - - if (listRef.current !== null) { - listRef.current.scrollTo(scrollTop); - } - }; - return (
    { )} {itemCount > 0 ? (
    - - - {RenderRow} - - +
    ) : ( -
    +
    No data
    )} diff --git a/packages/grafana-ui/src/components/Table/types.ts b/packages/grafana-ui/src/components/Table/types.ts index 1cb4f5d85b489..517aefb1b90da 100644 --- a/packages/grafana-ui/src/components/Table/types.ts +++ b/packages/grafana-ui/src/components/Table/types.ts @@ -94,6 +94,7 @@ export interface Props { cellHeight?: schema.TableCellHeight; /** @alpha Used by SparklineCell when provided */ timeRange?: TimeRange; + enableSharedCrosshair?: boolean; } /** diff --git a/packages/grafana-ui/src/components/Table/utils.ts b/packages/grafana-ui/src/components/Table/utils.ts index 91c18ebc02997..efece819ba613 100644 --- a/packages/grafana-ui/src/components/Table/utils.ts +++ b/packages/grafana-ui/src/components/Table/utils.ts @@ -533,3 +533,33 @@ export function getAlignmentFactor( return alignmentFactor; } } + +// since the conversion from timeseries panel crosshair to time is pixel based, we need +// to set a threshold where the table row highlights when the crosshair is hovered over a certain point +// because multiple pixels (converted to times) may represent the same point/row in table +export function isPointTimeValAroundTableTimeVal(pointTime: number, rowTime: number, threshold: number) { + return Math.abs(Math.floor(pointTime) - rowTime) < threshold; +} + +// calculate the threshold for which we consider a point in a chart +// to match a row in a table based on a time value +export function calculateAroundPointThreshold(timeField: Field): number { + let max = -Number.MAX_VALUE; + let min = Number.MAX_VALUE; + + if (timeField.values.length < 2) { + return 0; + } + + for (let i = 0; i < timeField.values.length; i++) { + const value = timeField.values[i]; + if (value > max) { + max = value; + } + if (value < min) { + min = value; + } + } + + return (max - min) / timeField.values.length; +} diff --git a/packages/grafana-ui/src/components/Tabs/Counter.tsx b/packages/grafana-ui/src/components/Tabs/Counter.tsx index 351863c7cf463..8a8c507bff25c 100644 --- a/packages/grafana-ui/src/components/Tabs/Counter.tsx +++ b/packages/grafana-ui/src/components/Tabs/Counter.tsx @@ -3,22 +3,7 @@ import React from 'react'; import { GrafanaTheme2, locale } from '@grafana/data'; -import { stylesFactory, useStyles2 } from '../../themes'; - -const getStyles = stylesFactory((theme: GrafanaTheme2) => { - return { - counter: css({ - label: 'counter', - marginLeft: theme.spacing(1), - borderRadius: theme.spacing(3), - backgroundColor: theme.colors.action.hover, - padding: theme.spacing(0.25, 1), - color: theme.colors.text.secondary, - fontWeight: theme.typography.fontWeightMedium, - fontSize: theme.typography.size.sm, - }), - }; -}); +import { useStyles2 } from '../../themes'; export interface CounterProps { value: number; @@ -29,3 +14,16 @@ export const Counter = ({ value }: CounterProps) => { return {locale(value, 0).text}; }; + +const getStyles = (theme: GrafanaTheme2) => ({ + counter: css({ + label: 'counter', + marginLeft: theme.spacing(1), + borderRadius: theme.spacing(3), + backgroundColor: theme.colors.action.hover, + padding: theme.spacing(0.25, 1), + color: theme.colors.text.secondary, + fontWeight: theme.typography.fontWeightMedium, + fontSize: theme.typography.size.sm, + }), +}); diff --git a/packages/grafana-ui/src/components/Tabs/Tab.tsx b/packages/grafana-ui/src/components/Tabs/Tab.tsx index 01ae75bb5c4c1..86ac3adfb360c 100644 --- a/packages/grafana-ui/src/components/Tabs/Tab.tsx +++ b/packages/grafana-ui/src/components/Tabs/Tab.tsx @@ -7,26 +7,29 @@ import { selectors } from '@grafana/e2e-selectors'; import { useStyles2 } from '../../themes'; import { getFocusStyles } from '../../themes/mixins'; import { IconName } from '../../types'; +import { clearButtonStyles } from '../Button'; import { Icon } from '../Icon/Icon'; import { Counter } from './Counter'; -export interface TabProps extends HTMLProps { +export interface TabProps extends HTMLProps { label: string; active?: boolean; /** When provided, it is possible to use the tab as a hyperlink. Use in cases where the tabs update location. */ href?: string; icon?: IconName; - onChangeTab?: (event?: React.MouseEvent) => void; + onChangeTab?: (event: React.MouseEvent) => void; /** A number rendered next to the text. Usually used to display the number of items in a tab's view. */ counter?: number | null; /** Extra content, displayed after the tab label and counter */ suffix?: NavModelItem['tabSuffix']; } -export const Tab = React.forwardRef( +export const Tab = React.forwardRef( ({ label, active, icon, onChangeTab, counter, suffix: Suffix, className, href, ...otherProps }, ref) => { const tabsStyles = useStyles2(getStyles); + const clearStyles = useStyles2(clearButtonStyles); + const content = () => ( <> {icon && } @@ -36,23 +39,44 @@ export const Tab = React.forwardRef( ); - const linkClass = cx(tabsStyles.link, active ? tabsStyles.activeStyle : tabsStyles.notActive); + const linkClass = cx(clearStyles, tabsStyles.link, active ? tabsStyles.activeStyle : tabsStyles.notActive); + + const commonProps = { + className: linkClass, + ...otherProps, + onClick: onChangeTab, + 'aria-label': otherProps['aria-label'] || selectors.components.Tab.title(label), + role: 'tab', + 'aria-selected': active, + }; + + if (href) { + return ( + + ); + } return ( ); } @@ -108,10 +132,6 @@ const getStyles = (theme: GrafanaTheme2) => { color: theme.colors.text.primary, overflow: 'hidden', - a: { - color: theme.colors.text.primary, - }, - '&::before': { backgroundImage: theme.colors.gradients.brandHorizontal, }, diff --git a/packages/grafana-ui/src/components/Tabs/TabContent.tsx b/packages/grafana-ui/src/components/Tabs/TabContent.tsx index 929c7f854ddf9..76c7b88f18270 100644 --- a/packages/grafana-ui/src/components/Tabs/TabContent.tsx +++ b/packages/grafana-ui/src/components/Tabs/TabContent.tsx @@ -3,23 +3,14 @@ import React, { HTMLAttributes, ReactNode } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; interface Props extends HTMLAttributes { children: ReactNode; } -const getTabContentStyle = stylesFactory((theme: GrafanaTheme2) => { - return { - tabContent: css({ - background: theme.colors.background.primary, - }), - }; -}); - export const TabContent = ({ children, className, ...restProps }: Props) => { - const theme = useTheme2(); - const styles = getTabContentStyle(theme); + const styles = useStyles2(getTabContentStyle); return (
    @@ -27,3 +18,9 @@ export const TabContent = ({ children, className, ...restProps }: Props) => {
    ); }; + +const getTabContentStyle = (theme: GrafanaTheme2) => ({ + tabContent: css({ + background: theme.colors.background.primary, + }), +}); diff --git a/packages/grafana-ui/src/components/Tags/Tag.tsx b/packages/grafana-ui/src/components/Tags/Tag.tsx index 84742cfd98713..81a857ee4ffd0 100644 --- a/packages/grafana-ui/src/components/Tags/Tag.tsx +++ b/packages/grafana-ui/src/components/Tags/Tag.tsx @@ -7,6 +7,7 @@ import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2, useTheme2 } from '../../themes'; import { IconName } from '../../types/icon'; import { getTagColor, getTagColorsFromName } from '../../utils'; +import { SkeletonComponent, attachSkeleton } from '../../utils/skeleton'; import { Icon } from '../Icon/Icon'; /** @@ -50,18 +51,12 @@ const TagComponent = forwardRef(({ name, onClick, icon, clas }); TagComponent.displayName = 'Tag'; -const TagSkeleton = () => { +const TagSkeleton: SkeletonComponent = ({ rootProps }) => { const styles = useStyles2(getSkeletonStyles); - return ; + return ; }; -interface TagWithSkeleton extends React.ForwardRefExoticComponent> { - Skeleton: typeof TagSkeleton; -} - -export const Tag: TagWithSkeleton = Object.assign(TagComponent, { - Skeleton: TagSkeleton, -}); +export const Tag = attachSkeleton(TagComponent, TagSkeleton); const getSkeletonStyles = () => ({ container: css({ diff --git a/packages/grafana-ui/src/components/Tags/TagList.tsx b/packages/grafana-ui/src/components/Tags/TagList.tsx index 6749f2fc78185..fefd90c4b4c4f 100644 --- a/packages/grafana-ui/src/components/Tags/TagList.tsx +++ b/packages/grafana-ui/src/components/Tags/TagList.tsx @@ -5,6 +5,7 @@ import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2, useTheme2 } from '../../themes'; import { IconName } from '../../types/icon'; +import { SkeletonComponent, attachSkeleton } from '../../utils/skeleton'; import { OnTagClick, Tag } from './Tag'; @@ -56,23 +57,17 @@ const TagListComponent = memo( ); TagListComponent.displayName = 'TagList'; -const TagListSkeleton = () => { +const TagListSkeleton: SkeletonComponent = ({ rootProps }) => { const styles = useStyles2(getSkeletonStyles); return ( -
    +
    ); }; -interface TagListWithSkeleton extends React.ForwardRefExoticComponent> { - Skeleton: typeof TagListSkeleton; -} - -export const TagList: TagListWithSkeleton = Object.assign(TagListComponent, { - Skeleton: TagListSkeleton, -}); +export const TagList = attachSkeleton(TagListComponent, TagListSkeleton); const getSkeletonStyles = (theme: GrafanaTheme2) => ({ container: css({ diff --git a/packages/grafana-ui/src/components/Text/Text.tsx b/packages/grafana-ui/src/components/Text/Text.tsx index eb036f186e761..29f3a46c1134a 100644 --- a/packages/grafana-ui/src/components/Text/Text.tsx +++ b/packages/grafana-ui/src/components/Text/Text.tsx @@ -1,12 +1,11 @@ import { css } from '@emotion/css'; -import React, { createElement, CSSProperties, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; -import ReactDomServer from 'react-dom/server'; +import React, { createElement, CSSProperties } from 'react'; import { GrafanaTheme2, ThemeTypographyVariantTypes } from '@grafana/data'; import { useStyles2 } from '../../themes'; -import { Tooltip } from '../Tooltip/Tooltip'; +import { TruncatedText } from './TruncatedText'; import { customWeight, customColor, customVariant } from './utils'; export interface TextProps extends Omit, 'className' | 'style'> { @@ -30,70 +29,35 @@ export interface TextProps extends Omit, 'clas export const Text = React.forwardRef( ({ element = 'span', variant, weight, color, truncate, italic, textAlignment, children, ...restProps }, ref) => { const styles = useStyles2(getTextStyles, element, variant, color, weight, truncate, italic, textAlignment); - const [isOverflowing, setIsOverflowing] = useState(false); - const internalRef = useRef(null); - // wire up the forwarded ref to the internal ref - useImperativeHandle(ref, () => internalRef.current); + const childElement = (ref: React.ForwardedRef | undefined) => { + return createElement( + element, + { + ...restProps, + style: undefined, // Remove the style prop to avoid overriding the styles + className: styles, + // When overflowing, the internalRef is passed to the tooltip, which forwards it to the child element + ref, + }, + children + ); + }; - const childElement = createElement( - element, - { - ...restProps, - style: undefined, // remove style prop to avoid overriding the styles - className: styles, - // when overflowing, the internalRef is passed to the tooltip which forwards it on to the child element - ref: isOverflowing ? undefined : internalRef, - }, - children - ); + // A 'span' is an inline element, so it can't be truncated + // and it should be wrapped in a parent element that will show the tooltip + if (!truncate || element === 'span') { + return childElement(undefined); + } - const resizeObserver = useMemo( - () => - new ResizeObserver((entries) => { - for (const entry of entries) { - if (entry.target.clientWidth && entry.target.scrollWidth) { - if (entry.target.scrollWidth > entry.target.clientWidth) { - setIsOverflowing(true); - } - if (entry.target.scrollWidth <= entry.target.clientWidth) { - setIsOverflowing(false); - } - } - } - }), - [] + return ( + ); - - useEffect(() => { - const { current } = internalRef; - if (current && truncate) { - resizeObserver.observe(current); - } - return () => { - resizeObserver.disconnect(); - }; - }, [isOverflowing, resizeObserver, truncate]); - - const getTooltipText = (children: NonNullable) => { - if (typeof children === 'string') { - return children; - } - const html = ReactDomServer.renderToStaticMarkup(<>{children}); - const getRidOfTags = html.replace(/(<([^>]+)>)/gi, ''); - return getRidOfTags; - }; - // A 'span' is an inline element therefore it can't be truncated - // and it should be wrapped in a parent element that is the one that will show the tooltip - if (truncate && isOverflowing && element !== 'span') { - return ( - - {childElement} - - ); - } else { - return childElement; - } } ); diff --git a/packages/grafana-ui/src/components/Text/TruncatedText.tsx b/packages/grafana-ui/src/components/Text/TruncatedText.tsx new file mode 100644 index 0000000000000..e74cbd36bb72e --- /dev/null +++ b/packages/grafana-ui/src/components/Text/TruncatedText.tsx @@ -0,0 +1,64 @@ +import React, { useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; +import ReactDOMServer from 'react-dom/server'; + +import { Tooltip } from '../Tooltip/Tooltip'; + +interface TruncatedTextProps { + childElement: (ref: React.ForwardedRef | undefined) => React.ReactElement; + children: NonNullable; +} + +export const TruncatedText = React.forwardRef(({ childElement, children }, ref) => { + const [isOverflowing, setIsOverflowing] = useState(false); + const internalRef = useRef(null); + + // Wire up the forwarded ref to the internal ref + useImperativeHandle(ref, () => internalRef.current); + + const resizeObserver = useMemo( + () => + new ResizeObserver((entries) => { + for (const entry of entries) { + if (entry.target.clientWidth && entry.target.scrollWidth) { + if (entry.target.scrollWidth > entry.target.clientWidth) { + setIsOverflowing(true); + } + if (entry.target.scrollWidth <= entry.target.clientWidth) { + setIsOverflowing(false); + } + } + } + }), + [] + ); + + useEffect(() => { + const { current } = internalRef; + if (current) { + resizeObserver.observe(current); + } + return () => { + resizeObserver.disconnect(); + }; + }, [setIsOverflowing, resizeObserver]); + + const getTooltipText = (children: NonNullable) => { + if (typeof children === 'string') { + return children; + } + const html = ReactDOMServer.renderToStaticMarkup(<>{children}); + return html.replace(/(<([^>]+)>)/gi, ''); + }; + + if (isOverflowing) { + return ( + + {childElement(undefined)} + + ); + } else { + return childElement(internalRef); + } +}); + +TruncatedText.displayName = 'TruncatedText'; diff --git a/packages/grafana-ui/src/components/TextArea/TextArea.tsx b/packages/grafana-ui/src/components/TextArea/TextArea.tsx index bae097216e1e5..5f438b9982ce5 100644 --- a/packages/grafana-ui/src/components/TextArea/TextArea.tsx +++ b/packages/grafana-ui/src/components/TextArea/TextArea.tsx @@ -3,7 +3,7 @@ import React, { HTMLProps } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; -import { stylesFactory, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; import { getFocusStyle, sharedInputStyle } from '../Forms/commonStyles'; export interface Props extends Omit, 'size'> { @@ -12,26 +12,23 @@ export interface Props extends Omit, 'size'> { } export const TextArea = React.forwardRef(({ invalid, className, ...props }, ref) => { - const theme = useTheme2(); - const styles = getTextAreaStyle(theme, invalid); + const styles = useStyles2(getTextAreaStyle, invalid); return